summaryrefslogtreecommitdiffstats
path: root/net/url_request
diff options
context:
space:
mode:
Diffstat (limited to 'net/url_request')
-rw-r--r--net/url_request/url_request_http_job.cc60
-rw-r--r--net/url_request/url_request_http_job.h1
-rw-r--r--net/url_request/url_request_job.cc4
-rw-r--r--net/url_request/url_request_job.h4
4 files changed, 66 insertions, 3 deletions
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index fe1332d..4539f13 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -173,11 +173,65 @@ bool URLRequestHttpJob::GetContentEncodings(
void* iter = NULL;
while (response_info_->headers->EnumerateHeader(&iter, "Content-Encoding",
&encoding_type)) {
- encoding_types->push_back(encoding_type);
+ encoding_types->push_back(StringToLowerASCII(encoding_type));
}
+
+ // TODO(jar): Transition to returning enums, rather than strings, and perform
+ // all content encoding fixups here, rather than doing some in the
+ // FilterFactor(). Note that enums generated can be more specific than mere
+ // restatement of strings. For example, rather than just having a GZIP
+ // encoding we can have a GZIP_OPTIONAL encoding to help with odd SDCH related
+ // fixups.
+
+ // TODO(jar): Refactor code so that content-encoding error recovery is
+ // testable via unit tests.
+
+ if (!IsSdchResponse())
+ return !encoding_types->empty();
+
+ // If content encoding included SDCH, then everything is fine.
+ if (!encoding_types->empty() && ("sdch" == encoding_types->front()))
+ return !encoding_types->empty();
+
+ // SDCH "search results" protective hack: To make sure we don't break the only
+ // currently deployed SDCH enabled server, be VERY cautious about proxies that
+ // strip all content-encoding to not include sdch. IF we don't see content
+ // encodings that seem to match what we'd expect from a server that asked us
+ // to use a dictionary (and we advertised said dictionary in the GET), then
+ // we set the encoding to (try to) use SDCH to decode. Note that SDCH will
+ // degrade into a pass-through filter if it doesn't have a viable dictionary
+ // hash in its header. Also note that a solo "sdch" will implicitly create
+ // a "sdch,gzip" decoding filter, where the gzip portion will degrade to a
+ // pass through if a gzip header is not encountered. Hence we can replace
+ // "gzip" with "sdch" and "everything will work."
+ // The one failure mode comes when we advertise a dictionary, and the server
+ // tries to *send* a gzipped file (not gzip encode content), and then we could
+ // do a gzip decode :-(. Since current server support does not ever see such
+ // a transfer, we are safe (for now).
+
+ std::string mime_type;
+ GetMimeType(&mime_type);
+ if (std::string::npos != mime_type.find_first_of("text/html")) {
+ // Suspicious case: Advertised dictionary, but server didn't use sdch, even
+ // though it is text_html content.
+ if (encoding_types->empty())
+ SdchManager::SdchErrorRecovery(SdchManager::ADDED_CONTENT_ENCODING);
+ else if (encoding_types->size() == 1)
+ SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODING);
+ else
+ SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODINGS);
+ encoding_types->clear();
+ encoding_types->push_back("sdch"); // Handle SDCH/GZIP-opt encoding.
+ }
+
return !encoding_types->empty();
}
+bool URLRequestHttpJob::IsSdchResponse() const {
+ return response_info_ &&
+ (request_info_.load_flags & net::LOAD_SDCH_DICTIONARY_ADVERTISED);
+}
+
bool URLRequestHttpJob::IsRedirectResponse(GURL* location,
int* http_status_code) {
if (!response_info_)
@@ -516,9 +570,11 @@ void URLRequestHttpJob::AddExtraHeaders() {
std::string avail_dictionaries;
SdchManager::Global()->GetAvailDictionaryList(request_->url(),
&avail_dictionaries);
- if (!avail_dictionaries.empty())
+ if (!avail_dictionaries.empty()) {
request_info_.extra_headers += "Avail-Dictionary: "
+ avail_dictionaries + "\r\n";
+ request_info_.load_flags |= net::LOAD_SDCH_DICTIONARY_ADVERTISED;
+ }
scoped_ptr<FileVersionInfo> file_version_info(
FileVersionInfo::CreateFileVersionInfoForCurrentModule());
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index 908db2c..b984722 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -42,6 +42,7 @@ class URLRequestHttpJob : public URLRequestJob {
virtual bool GetResponseCookies(std::vector<std::string>* cookies);
virtual int GetResponseCode();
virtual bool GetContentEncodings(std::vector<std::string>* encoding_type);
+ virtual bool IsSdchResponse() const;
virtual bool IsRedirectResponse(GURL* location, int* http_status_code);
virtual bool IsSafeRedirect(const GURL& location);
virtual bool NeedsAuth();
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 0501286..f4924bb 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -52,8 +52,10 @@ void URLRequestJob::SetupFilter() {
std::string mime_type;
GetMimeType(&mime_type);
filter_.reset(Filter::Factory(encoding_types, mime_type, kFilterBufSize));
- if (filter_.get())
+ if (filter_.get()) {
filter_->SetURL(request_->url());
+ filter_->SetMimeType(mime_type);
+ }
}
}
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index 1e4a089..2df62fd 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -123,6 +123,10 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob> {
return false;
}
+ // Find out if this is a response to a request that advertised an SDCH
+ // dictionary. Only makes sense for some types of requests.
+ virtual bool IsSdchResponse() const { return false; }
+
// Called to setup stream filter for this request. An example of filter is
// content encoding/decoding.
void SetupFilter();