Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: net/url_request/url_request_http_job.cc

Issue 8018: Clean up filter and content encoding handling ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/url_request/url_request_http_job.h ('k') | net/url_request/url_request_job.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/url_request/url_request_http_job.h" 5 #include "net/url_request/url_request_http_job.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/file_version_info.h" 9 #include "base/file_version_info.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "net/base/cookie_monster.h" 12 #include "net/base/cookie_monster.h"
13 #include "net/base/filter.h"
13 #include "net/base/load_flags.h" 14 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
15 #include "net/base/net_util.h" 16 #include "net/base/net_util.h"
16 #include "net/base/sdch_manager.h" 17 #include "net/base/sdch_manager.h"
17 #include "net/http/http_response_info.h" 18 #include "net/http/http_response_info.h"
18 #include "net/http/http_transaction.h" 19 #include "net/http/http_transaction.h"
19 #include "net/http/http_transaction_factory.h" 20 #include "net/http/http_transaction_factory.h"
20 #include "net/url_request/url_request.h" 21 #include "net/url_request/url_request.h"
21 #include "net/url_request/url_request_error_job.h" 22 #include "net/url_request/url_request_error_job.h"
22 23
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 int URLRequestHttpJob::GetResponseCode() { 156 int URLRequestHttpJob::GetResponseCode() {
156 DCHECK(transaction_.get()); 157 DCHECK(transaction_.get());
157 158
158 if (!response_info_) 159 if (!response_info_)
159 return -1; 160 return -1;
160 161
161 return response_info_->headers->response_code(); 162 return response_info_->headers->response_code();
162 } 163 }
163 164
164 bool URLRequestHttpJob::GetContentEncodings( 165 bool URLRequestHttpJob::GetContentEncodings(
165 std::vector<std::string>* encoding_types) { 166 std::vector<Filter::FilterType>* encoding_types) {
166 DCHECK(transaction_.get()); 167 DCHECK(transaction_.get());
167
168 if (!response_info_) 168 if (!response_info_)
169 return false; 169 return false;
170 DCHECK(encoding_types->empty());
170 171
171 std::string encoding_type; 172 std::string encoding_type;
172 void* iter = NULL; 173 void* iter = NULL;
173 while (response_info_->headers->EnumerateHeader(&iter, "Content-Encoding", 174 while (response_info_->headers->EnumerateHeader(&iter, "Content-Encoding",
174 &encoding_type)) { 175 &encoding_type)) {
175 encoding_types->push_back(StringToLowerASCII(encoding_type)); 176 encoding_types->push_back(Filter::ConvertEncodingToType(encoding_type));
176 } 177 }
177 178
178 // TODO(jar): Transition to returning enums, rather than strings, and perform 179 if (!encoding_types->empty()) {
179 // all content encoding fixups here, rather than doing some in the 180 std::string mime_type;
180 // FilterFactor(). Note that enums generated can be more specific than mere 181 GetMimeType(&mime_type);
181 // restatement of strings. For example, rather than just having a GZIP 182 Filter::FixupEncodingTypes(IsSdchResponse(), mime_type, encoding_types);
182 // encoding we can have a GZIP_OPTIONAL encoding to help with odd SDCH related
183 // fixups.
184
185 // TODO(jar): Refactor code so that content-encoding error recovery is
186 // testable via unit tests.
187
188 if (!IsSdchResponse())
189 return !encoding_types->empty();
190
191 // If content encoding included SDCH, then everything is fine.
192 if (!encoding_types->empty() && ("sdch" == encoding_types->front()))
193 return !encoding_types->empty();
194
195 // SDCH "search results" protective hack: To make sure we don't break the only
196 // currently deployed SDCH enabled server, be VERY cautious about proxies that
197 // strip all content-encoding to not include sdch. IF we don't see content
198 // encodings that seem to match what we'd expect from a server that asked us
199 // to use a dictionary (and we advertised said dictionary in the GET), then
200 // we set the encoding to (try to) use SDCH to decode. Note that SDCH will
201 // degrade into a pass-through filter if it doesn't have a viable dictionary
202 // hash in its header. Also note that a solo "sdch" will implicitly create
203 // a "sdch,gzip" decoding filter, where the gzip portion will degrade to a
204 // pass through if a gzip header is not encountered. Hence we can replace
205 // "gzip" with "sdch" and "everything will work."
206 // The one failure mode comes when we advertise a dictionary, and the server
207 // tries to *send* a gzipped file (not gzip encode content), and then we could
208 // do a gzip decode :-(. Since current server support does not ever see such
209 // a transfer, we are safe (for now).
210
211 std::string mime_type;
212 GetMimeType(&mime_type);
213 if (std::string::npos != mime_type.find_first_of("text/html")) {
214 // Suspicious case: Advertised dictionary, but server didn't use sdch, even
215 // though it is text_html content.
216 if (encoding_types->empty())
217 SdchManager::SdchErrorRecovery(SdchManager::ADDED_CONTENT_ENCODING);
218 else if (encoding_types->size() == 1)
219 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODING);
220 else
221 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODINGS);
222 encoding_types->clear();
223 encoding_types->push_back("sdch"); // Handle SDCH/GZIP-opt encoding.
224 } 183 }
225
226 return !encoding_types->empty(); 184 return !encoding_types->empty();
227 } 185 }
228 186
229 bool URLRequestHttpJob::IsSdchResponse() const { 187 bool URLRequestHttpJob::IsSdchResponse() const {
230 return response_info_ && 188 return response_info_ &&
231 (request_info_.load_flags & net::LOAD_SDCH_DICTIONARY_ADVERTISED); 189 (request_info_.load_flags & net::LOAD_SDCH_DICTIONARY_ADVERTISED);
232 } 190 }
233 191
234 bool URLRequestHttpJob::IsRedirectResponse(GURL* location, 192 bool URLRequestHttpJob::IsRedirectResponse(GURL* location,
235 int* http_status_code) { 193 int* http_status_code) {
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 rv = net::ERR_FAILED; 485 rv = net::ERR_FAILED;
528 } 486 }
529 487
530 // The transaction started synchronously, but we need to notify the 488 // The transaction started synchronously, but we need to notify the
531 // URLRequest delegate via the message loop. 489 // URLRequest delegate via the message loop.
532 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 490 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
533 this, &URLRequestHttpJob::OnStartCompleted, rv)); 491 this, &URLRequestHttpJob::OnStartCompleted, rv));
534 } 492 }
535 493
536 void URLRequestHttpJob::AddExtraHeaders() { 494 void URLRequestHttpJob::AddExtraHeaders() {
495 // Supply Accept-Encoding headers first so that it is more likely that they
496 // will be in the first transmitted packet. This can sometimes make it easier
497 // to filter and analyze the streams to assure that a proxy has not damaged
498 // these headers. Some proxies deliberately corrupt Accept-Encoding headers.
499 if (!SdchManager::Global() ||
500 !SdchManager::Global()->IsInSupportedDomain(request_->url())) {
501 // Tell the server what compression formats we support (other than SDCH).
502 request_info_.extra_headers += "Accept-Encoding: gzip,deflate,bzip2\r\n";
503 } else {
504 // Supply SDCH related headers, as well as accepting that encoding.
505 // Tell the server what compression formats we support.
506 request_info_.extra_headers += "Accept-Encoding: "
507 "gzip,deflate,bzip2,sdch\r\n";
508
509 // TODO(jar): See if it is worth optimizing away these bytes when the URL is
510 // probably an img or such. (and SDCH encoding is not likely).
511 std::string avail_dictionaries;
512 SdchManager::Global()->GetAvailDictionaryList(request_->url(),
513 &avail_dictionaries);
514 if (!avail_dictionaries.empty()) {
515 request_info_.extra_headers += "Avail-Dictionary: "
516 + avail_dictionaries + "\r\n";
517 request_info_.load_flags |= net::LOAD_SDCH_DICTIONARY_ADVERTISED;
518 }
519
520 scoped_ptr<FileVersionInfo> file_version_info(
521 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
522 request_info_.extra_headers += "X-SDCH: Chrome ";
523 request_info_.extra_headers +=
524 WideToASCII(file_version_info->product_version());
525 request_info_.extra_headers += "\r\n";
526 }
527
537 URLRequestContext* context = request_->context(); 528 URLRequestContext* context = request_->context();
538 if (context) { 529 if (context) {
539 // Add in the cookie header. TODO might we need more than one header? 530 // Add in the cookie header. TODO might we need more than one header?
540 if (context->cookie_store() && 531 if (context->cookie_store() &&
541 context->cookie_policy()->CanGetCookies(request_->url(), 532 context->cookie_policy()->CanGetCookies(request_->url(),
542 request_->policy_url())) { 533 request_->policy_url())) {
543 std::string cookies = request_->context()->cookie_store()-> 534 std::string cookies = request_->context()->cookie_store()->
544 GetCookiesWithOptions(request_->url(), 535 GetCookiesWithOptions(request_->url(),
545 net::CookieMonster::INCLUDE_HTTPONLY); 536 net::CookieMonster::INCLUDE_HTTPONLY);
546 if (!cookies.empty()) 537 if (!cookies.empty())
547 request_info_.extra_headers += "Cookie: " + cookies + "\r\n"; 538 request_info_.extra_headers += "Cookie: " + cookies + "\r\n";
548 } 539 }
549 if (!context->accept_language().empty()) 540 if (!context->accept_language().empty())
550 request_info_.extra_headers += "Accept-Language: " + 541 request_info_.extra_headers += "Accept-Language: " +
551 context->accept_language() + "\r\n"; 542 context->accept_language() + "\r\n";
552 if (!context->accept_charset().empty()) 543 if (!context->accept_charset().empty())
553 request_info_.extra_headers += "Accept-Charset: " + 544 request_info_.extra_headers += "Accept-Charset: " +
554 context->accept_charset() + "\r\n"; 545 context->accept_charset() + "\r\n";
555 } 546 }
556
557 if (!SdchManager::Global() ||
558 !SdchManager::Global()->IsInSupportedDomain(request_->url())) {
559 // Tell the server what compression formats we support (other than SDCH).
560 request_info_.extra_headers += "Accept-Encoding: gzip,deflate,bzip2\r\n";
561 return;
562 }
563
564 // Supply SDCH related headers, as well as accepting that encoding.
565
566 // TODO(jar): See if it is worth optimizing away these bytes when the URL is
567 // probably an img or such. (and SDCH encoding is not likely).
568 std::string avail_dictionaries;
569 SdchManager::Global()->GetAvailDictionaryList(request_->url(),
570 &avail_dictionaries);
571 if (!avail_dictionaries.empty()) {
572 request_info_.extra_headers += "Avail-Dictionary: "
573 + avail_dictionaries + "\r\n";
574 request_info_.load_flags |= net::LOAD_SDCH_DICTIONARY_ADVERTISED;
575 }
576
577 scoped_ptr<FileVersionInfo> file_version_info(
578 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
579 request_info_.extra_headers += "X-SDCH: Chrome ";
580 request_info_.extra_headers +=
581 WideToASCII(file_version_info->product_version());
582 request_info_.extra_headers += "\r\n";
583
584 // Tell the server what compression formats we support.
585 request_info_.extra_headers += "Accept-Encoding: gzip,deflate,bzip2,sdch\r\n";
586 } 547 }
587 548
588 void URLRequestHttpJob::FetchResponseCookies() { 549 void URLRequestHttpJob::FetchResponseCookies() {
589 DCHECK(response_info_); 550 DCHECK(response_info_);
590 DCHECK(response_cookies_.empty()); 551 DCHECK(response_cookies_.empty());
591 552
592 std::string name = "Set-Cookie"; 553 std::string name = "Set-Cookie";
593 std::string value; 554 std::string value;
594 555
595 void* iter = NULL; 556 void* iter = NULL;
596 while (response_info_->headers->EnumerateHeader(&iter, name, &value)) 557 while (response_info_->headers->EnumerateHeader(&iter, name, &value))
597 response_cookies_.push_back(value); 558 response_cookies_.push_back(value);
598 } 559 }
599 560
OLDNEW
« no previous file with comments | « net/url_request/url_request_http_job.h ('k') | net/url_request/url_request_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698