summaryrefslogtreecommitdiffstats
path: root/net/url_request/url_request_http_job.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/url_request/url_request_http_job.cc')
-rw-r--r--net/url_request/url_request_http_job.cc60
1 files changed, 58 insertions, 2 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());