diff options
Diffstat (limited to 'net/url_request/url_request_http_job.cc')
-rw-r--r-- | net/url_request/url_request_http_job.cc | 60 |
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()); |