| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/base_switches.h" | 7 #include "base/base_switches.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/file_version_info.h" | 11 #include "base/file_version_info.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "net/base/cert_status_flags.h" | 15 #include "net/base/cert_status_flags.h" |
| 16 #include "net/base/cookie_policy.h" | 16 #include "net/base/cookie_policy.h" |
| 17 #include "net/base/filter.h" | 17 #include "net/base/filter.h" |
| 18 #include "net/base/https_prober.h" | 18 #include "net/base/https_prober.h" |
| 19 #include "net/base/transport_security_state.h" | 19 #include "net/base/transport_security_state.h" |
| 20 #include "net/base/load_flags.h" | 20 #include "net/base/load_flags.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 #include "net/base/net_util.h" | 22 #include "net/base/net_util.h" |
| 23 #include "net/base/sdch_manager.h" | 23 #include "net/base/sdch_manager.h" |
| 24 #include "net/base/ssl_cert_request_info.h" | 24 #include "net/base/ssl_cert_request_info.h" |
| 25 #include "net/http/http_request_headers.h" |
| 25 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
| 26 #include "net/http/http_response_info.h" | 27 #include "net/http/http_response_info.h" |
| 27 #include "net/http/http_transaction.h" | 28 #include "net/http/http_transaction.h" |
| 28 #include "net/http/http_transaction_factory.h" | 29 #include "net/http/http_transaction_factory.h" |
| 29 #include "net/http/http_util.h" | 30 #include "net/http/http_util.h" |
| 30 #include "net/url_request/url_request.h" | 31 #include "net/url_request/url_request.h" |
| 31 #include "net/url_request/url_request_context.h" | 32 #include "net/url_request/url_request_context.h" |
| 32 #include "net/url_request/url_request_error_job.h" | 33 #include "net/url_request/url_request_error_job.h" |
| 33 #include "net/url_request/url_request_redirect_job.h" | 34 #include "net/url_request/url_request_redirect_job.h" |
| 34 | 35 |
| 36 static const char kAvailDictionaryHeader[] = "Avail-Dictionary"; |
| 37 |
| 35 // TODO(darin): make sure the port blocking code is not lost | 38 // TODO(darin): make sure the port blocking code is not lost |
| 36 // static | 39 // static |
| 37 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 40 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
| 38 const std::string& scheme) { | 41 const std::string& scheme) { |
| 39 DCHECK(scheme == "http" || scheme == "https"); | 42 DCHECK(scheme == "http" || scheme == "https"); |
| 40 | 43 |
| 41 int port = request->url().IntPort(); | 44 int port = request->url().IntPort(); |
| 42 if (!net::IsPortAllowedByDefault(port) && !net::IsPortAllowedByOverride(port)) | 45 if (!net::IsPortAllowedByDefault(port) && !net::IsPortAllowedByOverride(port)) |
| 43 return new URLRequestErrorJob(request, net::ERR_UNSAFE_PORT); | 46 return new URLRequestErrorJob(request, net::ERR_UNSAFE_PORT); |
| 44 | 47 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 } | 126 } |
| 124 | 127 |
| 125 void URLRequestHttpJob::SetUpload(net::UploadData* upload) { | 128 void URLRequestHttpJob::SetUpload(net::UploadData* upload) { |
| 126 DCHECK(!transaction_.get()) << "cannot change once started"; | 129 DCHECK(!transaction_.get()) << "cannot change once started"; |
| 127 request_info_.upload_data = upload; | 130 request_info_.upload_data = upload; |
| 128 } | 131 } |
| 129 | 132 |
| 130 void URLRequestHttpJob::SetExtraRequestHeaders( | 133 void URLRequestHttpJob::SetExtraRequestHeaders( |
| 131 const std::string& headers) { | 134 const std::string& headers) { |
| 132 DCHECK(!transaction_.get()) << "cannot change once started"; | 135 DCHECK(!transaction_.get()) << "cannot change once started"; |
| 133 request_info_.extra_headers = headers; | 136 request_info_.extra_headers.AddHeadersFromString(headers); |
| 134 } | 137 } |
| 135 | 138 |
| 136 void URLRequestHttpJob::Start() { | 139 void URLRequestHttpJob::Start() { |
| 137 DCHECK(!transaction_.get()); | 140 DCHECK(!transaction_.get()); |
| 138 | 141 |
| 139 // Ensure that we do not send username and password fields in the referrer. | 142 // Ensure that we do not send username and password fields in the referrer. |
| 140 GURL referrer(request_->GetSanitizedReferrer()); | 143 GURL referrer(request_->GetSanitizedReferrer()); |
| 141 | 144 |
| 142 request_info_.url = request_->url(); | 145 request_info_.url = request_->url(); |
| 143 request_info_.referrer = referrer; | 146 request_info_.referrer = referrer; |
| 144 request_info_.method = request_->method(); | 147 request_info_.method = request_->method(); |
| 145 request_info_.load_flags = request_->load_flags(); | 148 request_info_.load_flags = request_->load_flags(); |
| 146 request_info_.priority = request_->priority(); | 149 request_info_.priority = request_->priority(); |
| 147 | 150 |
| 148 if (request_->context()) { | 151 if (request_->context()) { |
| 149 request_info_.user_agent = | 152 request_info_.extra_headers.SetHeader( |
| 150 request_->context()->GetUserAgent(request_->url()); | 153 net::HttpRequestHeaders::kUserAgent, |
| 154 request_->context()->GetUserAgent(request_->url())); |
| 151 } | 155 } |
| 152 | 156 |
| 153 AddExtraHeaders(); | 157 AddExtraHeaders(); |
| 154 AddCookieHeaderAndStart(); | 158 AddCookieHeaderAndStart(); |
| 155 } | 159 } |
| 156 | 160 |
| 157 void URLRequestHttpJob::Kill() { | 161 void URLRequestHttpJob::Kill() { |
| 158 if (!transaction_.get()) | 162 if (!transaction_.get()) |
| 159 return; | 163 return; |
| 160 | 164 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 username_ = username; | 331 username_ = username; |
| 328 password_ = password; | 332 password_ = password; |
| 329 | 333 |
| 330 // These will be reset in OnStartCompleted. | 334 // These will be reset in OnStartCompleted. |
| 331 response_info_ = NULL; | 335 response_info_ = NULL; |
| 332 response_cookies_.clear(); | 336 response_cookies_.clear(); |
| 333 | 337 |
| 334 // Update the cookies, since the cookie store may have been updated from the | 338 // Update the cookies, since the cookie store may have been updated from the |
| 335 // headers in the 401/407. Since cookies were already appended to | 339 // headers in the 401/407. Since cookies were already appended to |
| 336 // extra_headers, we need to strip them out before adding them again. | 340 // extra_headers, we need to strip them out before adding them again. |
| 337 static const char* const cookie_name[] = { "cookie" }; | 341 request_info_.extra_headers.RemoveHeader( |
| 338 request_info_.extra_headers = net::HttpUtil::StripHeaders( | 342 net::HttpRequestHeaders::kCookie); |
| 339 request_info_.extra_headers, cookie_name, arraysize(cookie_name)); | |
| 340 | 343 |
| 341 AddCookieHeaderAndStart(); | 344 AddCookieHeaderAndStart(); |
| 342 } | 345 } |
| 343 | 346 |
| 344 void URLRequestHttpJob::CancelAuth() { | 347 void URLRequestHttpJob::CancelAuth() { |
| 345 // Proxy gets set first, then WWW. | 348 // Proxy gets set first, then WWW. |
| 346 if (proxy_auth_state_ == net::AUTH_STATE_NEED_AUTH) { | 349 if (proxy_auth_state_ == net::AUTH_STATE_NEED_AUTH) { |
| 347 proxy_auth_state_ = net::AUTH_STATE_CANCELED; | 350 proxy_auth_state_ = net::AUTH_STATE_CANCELED; |
| 348 } else { | 351 } else { |
| 349 DCHECK(server_auth_state_ == net::AUTH_STATE_NEED_AUTH); | 352 DCHECK(server_auth_state_ == net::AUTH_STATE_NEED_AUTH); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 if (request_ && request_->delegate()) { | 442 if (request_ && request_->delegate()) { |
| 440 if (policy == net::ERR_ACCESS_DENIED) { | 443 if (policy == net::ERR_ACCESS_DENIED) { |
| 441 request_->delegate()->OnGetCookiesBlocked(request_); | 444 request_->delegate()->OnGetCookiesBlocked(request_); |
| 442 } else if (policy == net::OK && request_->context()->cookie_store()) { | 445 } else if (policy == net::OK && request_->context()->cookie_store()) { |
| 443 net::CookieOptions options; | 446 net::CookieOptions options; |
| 444 options.set_include_httponly(); | 447 options.set_include_httponly(); |
| 445 std::string cookies = | 448 std::string cookies = |
| 446 request_->context()->cookie_store()->GetCookiesWithOptions( | 449 request_->context()->cookie_store()->GetCookiesWithOptions( |
| 447 request_->url(), options); | 450 request_->url(), options); |
| 448 if (request_->context()->InterceptRequestCookies(request_, cookies) && | 451 if (request_->context()->InterceptRequestCookies(request_, cookies) && |
| 449 !cookies.empty()) | 452 !cookies.empty()) { |
| 450 request_info_.extra_headers += "Cookie: " + cookies + "\r\n"; | 453 request_info_.extra_headers.SetHeader( |
| 454 net::HttpRequestHeaders::kCookie, cookies); |
| 455 } |
| 451 } | 456 } |
| 452 // We may have been canceled within OnGetCookiesBlocked. | 457 // We may have been canceled within OnGetCookiesBlocked. |
| 453 if (GetStatus().is_success()) { | 458 if (GetStatus().is_success()) { |
| 454 StartTransaction(); | 459 StartTransaction(); |
| 455 } else { | 460 } else { |
| 456 NotifyCanceled(); | 461 NotifyCanceled(); |
| 457 } | 462 } |
| 458 } | 463 } |
| 459 Release(); // Balance AddRef taken in AddCookieHeaderAndStart | 464 Release(); // Balance AddRef taken in AddCookieHeaderAndStart |
| 460 } | 465 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 } | 663 } |
| 659 } | 664 } |
| 660 } | 665 } |
| 661 | 666 |
| 662 // Supply Accept-Encoding headers first so that it is more likely that they | 667 // Supply Accept-Encoding headers first so that it is more likely that they |
| 663 // will be in the first transmitted packet. This can sometimes make it easier | 668 // will be in the first transmitted packet. This can sometimes make it easier |
| 664 // to filter and analyze the streams to assure that a proxy has not damaged | 669 // to filter and analyze the streams to assure that a proxy has not damaged |
| 665 // these headers. Some proxies deliberately corrupt Accept-Encoding headers. | 670 // these headers. Some proxies deliberately corrupt Accept-Encoding headers. |
| 666 if (!advertise_sdch) { | 671 if (!advertise_sdch) { |
| 667 // Tell the server what compression formats we support (other than SDCH). | 672 // Tell the server what compression formats we support (other than SDCH). |
| 668 request_info_.extra_headers += "Accept-Encoding: gzip,deflate\r\n"; | 673 request_info_.extra_headers.SetHeader( |
| 674 net::HttpRequestHeaders::kAcceptEncoding, "gzip,deflate"); |
| 669 } else { | 675 } else { |
| 670 // Include SDCH in acceptable list. | 676 // Include SDCH in acceptable list. |
| 671 request_info_.extra_headers += "Accept-Encoding: " | 677 request_info_.extra_headers.SetHeader( |
| 672 "gzip,deflate,sdch\r\n"; | 678 net::HttpRequestHeaders::kAcceptEncoding, "gzip,deflate,sdch"); |
| 673 if (!avail_dictionaries.empty()) { | 679 if (!avail_dictionaries.empty()) { |
| 674 request_info_.extra_headers += "Avail-Dictionary: " | 680 request_info_.extra_headers.SetHeader( |
| 675 + avail_dictionaries + "\r\n"; | 681 kAvailDictionaryHeader, |
| 682 avail_dictionaries); |
| 676 sdch_dictionary_advertised_ = true; | 683 sdch_dictionary_advertised_ = true; |
| 677 // Since we're tagging this transaction as advertising a dictionary, we'll | 684 // Since we're tagging this transaction as advertising a dictionary, we'll |
| 678 // definately employ an SDCH filter (or tentative sdch filter) when we get | 685 // definately employ an SDCH filter (or tentative sdch filter) when we get |
| 679 // a response. When done, we'll record histograms via SDCH_DECODE or | 686 // a response. When done, we'll record histograms via SDCH_DECODE or |
| 680 // SDCH_PASSTHROUGH. Hence we need to record packet arrival times. | 687 // SDCH_PASSTHROUGH. Hence we need to record packet arrival times. |
| 681 EnablePacketCounting(kSdchPacketHistogramCount); | 688 EnablePacketCounting(kSdchPacketHistogramCount); |
| 682 } | 689 } |
| 683 } | 690 } |
| 684 | 691 |
| 685 URLRequestContext* context = request_->context(); | 692 URLRequestContext* context = request_->context(); |
| 686 if (context) { | 693 if (context) { |
| 687 // Only add default Accept-Language and Accept-Charset if the request | 694 // Only add default Accept-Language and Accept-Charset if the request |
| 688 // didn't have them specified. | 695 // didn't have them specified. |
| 689 net::HttpUtil::AppendHeaderIfMissing("Accept-Language", | 696 if (!request_info_.extra_headers.HasHeader( |
| 690 context->accept_language(), | 697 net::HttpRequestHeaders::kAcceptLanguage)) { |
| 691 &request_info_.extra_headers); | 698 request_info_.extra_headers.SetHeader( |
| 692 net::HttpUtil::AppendHeaderIfMissing("Accept-Charset", | 699 net::HttpRequestHeaders::kAcceptLanguage, |
| 693 context->accept_charset(), | 700 context->accept_language()); |
| 694 &request_info_.extra_headers); | 701 } |
| 702 if (!request_info_.extra_headers.HasHeader( |
| 703 net::HttpRequestHeaders::kAcceptCharset)) { |
| 704 request_info_.extra_headers.SetHeader( |
| 705 net::HttpRequestHeaders::kAcceptCharset, |
| 706 context->accept_charset()); |
| 707 } |
| 695 } | 708 } |
| 696 } | 709 } |
| 697 | 710 |
| 698 void URLRequestHttpJob::AddCookieHeaderAndStart() { | 711 void URLRequestHttpJob::AddCookieHeaderAndStart() { |
| 699 // No matter what, we want to report our status as IO pending since we will | 712 // No matter what, we want to report our status as IO pending since we will |
| 700 // be notifying our consumer asynchronously via OnStartCompleted. | 713 // be notifying our consumer asynchronously via OnStartCompleted. |
| 701 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 714 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 702 | 715 |
| 703 AddRef(); // Balanced in OnCanGetCookiesCompleted | 716 AddRef(); // Balanced in OnCanGetCookiesCompleted |
| 704 | 717 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 net::HTTPSProberDelegate* delegate = | 906 net::HTTPSProberDelegate* delegate = |
| 894 new HTTPSProberDelegate(request_info_.url.host(), max_age, | 907 new HTTPSProberDelegate(request_info_.url.host(), max_age, |
| 895 include_subdomains, | 908 include_subdomains, |
| 896 ctx->transport_security_state()); | 909 ctx->transport_security_state()); |
| 897 if (!prober->ProbeHost(request_info_.url.host(), request()->context(), | 910 if (!prober->ProbeHost(request_info_.url.host(), request()->context(), |
| 898 delegate)) { | 911 delegate)) { |
| 899 delete delegate; | 912 delete delegate; |
| 900 } | 913 } |
| 901 } | 914 } |
| 902 } | 915 } |
| OLD | NEW |