OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 StatisticSelector statistic) const { | 165 StatisticSelector statistic) const { |
166 job_->RecordPacketStats(statistic); | 166 job_->RecordPacketStats(statistic); |
167 } | 167 } |
168 | 168 |
169 // TODO(darin): make sure the port blocking code is not lost | 169 // TODO(darin): make sure the port blocking code is not lost |
170 // static | 170 // static |
171 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 171 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
172 const std::string& scheme) { | 172 const std::string& scheme) { |
173 DCHECK(scheme == "http" || scheme == "https"); | 173 DCHECK(scheme == "http" || scheme == "https"); |
174 | 174 |
175 if (!request->context() || | 175 if (!request->context()->http_transaction_factory()) { |
176 !request->context()->http_transaction_factory()) { | |
177 NOTREACHED() << "requires a valid context"; | 176 NOTREACHED() << "requires a valid context"; |
178 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); | 177 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); |
179 } | 178 } |
180 | 179 |
181 GURL redirect_url; | 180 GURL redirect_url; |
182 if (request->GetHSTSRedirect(&redirect_url)) | 181 if (request->GetHSTSRedirect(&redirect_url)) |
183 return new URLRequestRedirectJob(request, redirect_url); | 182 return new URLRequestRedirectJob(request, redirect_url); |
184 return new URLRequestHttpJob(request); | 183 return new URLRequestHttpJob(request); |
185 } | 184 } |
186 | 185 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 286 |
288 void URLRequestHttpJob::DestroyTransaction() { | 287 void URLRequestHttpJob::DestroyTransaction() { |
289 DCHECK(transaction_.get()); | 288 DCHECK(transaction_.get()); |
290 | 289 |
291 DoneWithRequest(ABORTED); | 290 DoneWithRequest(ABORTED); |
292 transaction_.reset(); | 291 transaction_.reset(); |
293 response_info_ = NULL; | 292 response_info_ = NULL; |
294 } | 293 } |
295 | 294 |
296 void URLRequestHttpJob::StartTransaction() { | 295 void URLRequestHttpJob::StartTransaction() { |
297 if (request_->context() && request_->context()->network_delegate()) { | 296 if (request_->context()->network_delegate()) { |
298 int rv = request_->context()->network_delegate()->NotifyBeforeSendHeaders( | 297 int rv = request_->context()->network_delegate()->NotifyBeforeSendHeaders( |
299 request_, notify_before_headers_sent_callback_, | 298 request_, notify_before_headers_sent_callback_, |
300 &request_info_.extra_headers); | 299 &request_info_.extra_headers); |
301 // If an extension blocks the request, we rely on the callback to | 300 // If an extension blocks the request, we rely on the callback to |
302 // StartTransactionInternal(). | 301 // StartTransactionInternal(). |
303 if (rv == ERR_IO_PENDING) { | 302 if (rv == ERR_IO_PENDING) { |
304 SetBlockedOnDelegate(); | 303 SetBlockedOnDelegate(); |
305 return; | 304 return; |
306 } | 305 } |
307 } | 306 } |
(...skipping 17 matching lines...) Expand all Loading... |
325 } | 324 } |
326 | 325 |
327 void URLRequestHttpJob::StartTransactionInternal() { | 326 void URLRequestHttpJob::StartTransactionInternal() { |
328 // NOTE: This method assumes that request_info_ is already setup properly. | 327 // NOTE: This method assumes that request_info_ is already setup properly. |
329 | 328 |
330 // If we already have a transaction, then we should restart the transaction | 329 // If we already have a transaction, then we should restart the transaction |
331 // with auth provided by auth_credentials_. | 330 // with auth provided by auth_credentials_. |
332 | 331 |
333 int rv; | 332 int rv; |
334 | 333 |
335 if (request_->context() && request_->context()->network_delegate()) { | 334 if (request_->context()->network_delegate()) { |
336 request_->context()->network_delegate()->NotifySendHeaders( | 335 request_->context()->network_delegate()->NotifySendHeaders( |
337 request_, request_info_.extra_headers); | 336 request_, request_info_.extra_headers); |
338 } | 337 } |
339 | 338 |
340 if (transaction_.get()) { | 339 if (transaction_.get()) { |
341 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); | 340 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); |
342 auth_credentials_ = AuthCredentials(); | 341 auth_credentials_ = AuthCredentials(); |
343 } else { | 342 } else { |
344 DCHECK(request_->context()); | |
345 DCHECK(request_->context()->http_transaction_factory()); | 343 DCHECK(request_->context()->http_transaction_factory()); |
346 | 344 |
347 rv = request_->context()->http_transaction_factory()->CreateTransaction( | 345 rv = request_->context()->http_transaction_factory()->CreateTransaction( |
348 &transaction_, http_transaction_delegate_.get()); | 346 &transaction_, http_transaction_delegate_.get()); |
349 if (rv == OK) { | 347 if (rv == OK) { |
350 if (!throttling_entry_ || | 348 if (!throttling_entry_ || |
351 !throttling_entry_->ShouldRejectRequest(*request_)) { | 349 !throttling_entry_->ShouldRejectRequest(*request_)) { |
352 rv = transaction_->Start( | 350 rv = transaction_->Start( |
353 &request_info_, start_callback_, request_->net_log()); | 351 &request_info_, start_callback_, request_->net_log()); |
354 start_time_ = base::TimeTicks::Now(); | 352 start_time_ = base::TimeTicks::Now(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 // we'll definitely employ an SDCH filter (or tentative sdch filter) | 426 // we'll definitely employ an SDCH filter (or tentative sdch filter) |
429 // when we get a response. When done, we'll record histograms via | 427 // when we get a response. When done, we'll record histograms via |
430 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet | 428 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet |
431 // arrival times. | 429 // arrival times. |
432 packet_timing_enabled_ = true; | 430 packet_timing_enabled_ = true; |
433 } | 431 } |
434 } | 432 } |
435 } | 433 } |
436 | 434 |
437 const URLRequestContext* context = request_->context(); | 435 const URLRequestContext* context = request_->context(); |
438 if (context) { | 436 // Only add default Accept-Language and Accept-Charset if the request |
439 // Only add default Accept-Language and Accept-Charset if the request | 437 // didn't have them specified. |
440 // didn't have them specified. | 438 if (!context->accept_language().empty()) { |
441 if (!context->accept_language().empty()) { | 439 request_info_.extra_headers.SetHeaderIfMissing( |
442 request_info_.extra_headers.SetHeaderIfMissing( | 440 HttpRequestHeaders::kAcceptLanguage, |
443 HttpRequestHeaders::kAcceptLanguage, | 441 context->accept_language()); |
444 context->accept_language()); | 442 } |
445 } | 443 if (!context->accept_charset().empty()) { |
446 if (!context->accept_charset().empty()) { | 444 request_info_.extra_headers.SetHeaderIfMissing( |
447 request_info_.extra_headers.SetHeaderIfMissing( | 445 HttpRequestHeaders::kAcceptCharset, |
448 HttpRequestHeaders::kAcceptCharset, | 446 context->accept_charset()); |
449 context->accept_charset()); | |
450 } | |
451 } | 447 } |
452 } | 448 } |
453 | 449 |
454 void URLRequestHttpJob::AddCookieHeaderAndStart() { | 450 void URLRequestHttpJob::AddCookieHeaderAndStart() { |
455 // No matter what, we want to report our status as IO pending since we will | 451 // No matter what, we want to report our status as IO pending since we will |
456 // be notifying our consumer asynchronously via OnStartCompleted. | 452 // be notifying our consumer asynchronously via OnStartCompleted. |
457 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 453 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
458 | 454 |
459 // If the request was destroyed, then there is no more work to do. | 455 // If the request was destroyed, then there is no more work to do. |
460 if (!request_) | 456 if (!request_) |
461 return; | 457 return; |
462 | 458 |
463 CookieStore* cookie_store = | 459 CookieStore* cookie_store = request_->context()->cookie_store(); |
464 request_->context()->cookie_store(); | |
465 if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { | 460 if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { |
466 net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster(); | 461 net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster(); |
467 if (cookie_monster) { | 462 if (cookie_monster) { |
468 cookie_monster->GetAllCookiesForURLAsync( | 463 cookie_monster->GetAllCookiesForURLAsync( |
469 request_->url(), | 464 request_->url(), |
470 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, | 465 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, |
471 weak_factory_.GetWeakPtr())); | 466 weak_factory_.GetWeakPtr())); |
472 } else { | 467 } else { |
473 DoLoadCookies(); | 468 DoLoadCookies(); |
474 } | 469 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 // should resolve the conflict in favor of the more strict policy. | 638 // should resolve the conflict in favor of the more strict policy. |
644 void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { | 639 void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { |
645 DCHECK(response_info_); | 640 DCHECK(response_info_); |
646 | 641 |
647 const URLRequestContext* ctx = request_->context(); | 642 const URLRequestContext* ctx = request_->context(); |
648 const SSLInfo& ssl_info = response_info_->ssl_info; | 643 const SSLInfo& ssl_info = response_info_->ssl_info; |
649 | 644 |
650 // Only accept strict transport security headers on HTTPS connections that | 645 // Only accept strict transport security headers on HTTPS connections that |
651 // have no certificate errors. | 646 // have no certificate errors. |
652 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 647 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
653 !ctx || !ctx->transport_security_state()) { | 648 !ctx->transport_security_state()) { |
654 return; | 649 return; |
655 } | 650 } |
656 | 651 |
657 TransportSecurityState* security_state = ctx->transport_security_state(); | 652 TransportSecurityState* security_state = ctx->transport_security_state(); |
658 TransportSecurityState::DomainState domain_state; | 653 TransportSecurityState::DomainState domain_state; |
659 const std::string& host = request_info_.url.host(); | 654 const std::string& host = request_info_.url.host(); |
660 | 655 |
661 bool sni_available = | 656 bool sni_available = |
662 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 657 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); |
663 if (!security_state->GetDomainState(host, sni_available, &domain_state)) | 658 if (!security_state->GetDomainState(host, sni_available, &domain_state)) |
(...skipping 16 matching lines...) Expand all Loading... |
680 | 675 |
681 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { | 676 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { |
682 DCHECK(response_info_); | 677 DCHECK(response_info_); |
683 | 678 |
684 const URLRequestContext* ctx = request_->context(); | 679 const URLRequestContext* ctx = request_->context(); |
685 const SSLInfo& ssl_info = response_info_->ssl_info; | 680 const SSLInfo& ssl_info = response_info_->ssl_info; |
686 | 681 |
687 // Only accept public key pins headers on HTTPS connections that have no | 682 // Only accept public key pins headers on HTTPS connections that have no |
688 // certificate errors. | 683 // certificate errors. |
689 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 684 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
690 !ctx || !ctx->transport_security_state()) { | 685 !ctx->transport_security_state()) { |
691 return; | 686 return; |
692 } | 687 } |
693 | 688 |
694 TransportSecurityState* security_state = ctx->transport_security_state(); | 689 TransportSecurityState* security_state = ctx->transport_security_state(); |
695 TransportSecurityState::DomainState domain_state; | 690 TransportSecurityState::DomainState domain_state; |
696 const std::string& host = request_info_.url.host(); | 691 const std::string& host = request_info_.url.host(); |
697 | 692 |
698 bool sni_available = | 693 bool sni_available = |
699 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 694 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); |
700 if (!security_state->GetDomainState(host, sni_available, &domain_state)) | 695 if (!security_state->GetDomainState(host, sni_available, &domain_state)) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 bool sni_available = SSLConfigService::IsSNIAvailable( | 738 bool sni_available = SSLConfigService::IsSNIAvailable( |
744 context->ssl_config_service()); | 739 context->ssl_config_service()); |
745 const std::string& host = request_->url().host(); | 740 const std::string& host = request_->url().host(); |
746 | 741 |
747 reporter->SendReport(host, ssl_info, sni_available); | 742 reporter->SendReport(host, ssl_info, sni_available); |
748 } | 743 } |
749 } | 744 } |
750 | 745 |
751 if (result == OK) { | 746 if (result == OK) { |
752 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); | 747 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
753 if (context && context->network_delegate()) { | 748 if (context->network_delegate()) { |
754 // Note that |this| may not be deleted until | 749 // Note that |this| may not be deleted until |
755 // |on_headers_received_callback_| or | 750 // |on_headers_received_callback_| or |
756 // |NetworkDelegate::URLRequestDestroyed()| has been called. | 751 // |NetworkDelegate::URLRequestDestroyed()| has been called. |
757 int error = context->network_delegate()-> | 752 int error = context->network_delegate()-> |
758 NotifyHeadersReceived(request_, on_headers_received_callback_, | 753 NotifyHeadersReceived(request_, on_headers_received_callback_, |
759 headers, &override_response_headers_); | 754 headers, &override_response_headers_); |
760 if (error != net::OK) { | 755 if (error != net::OK) { |
761 if (error == net::ERR_IO_PENDING) { | 756 if (error == net::ERR_IO_PENDING) { |
762 awaiting_callback_ = true; | 757 awaiting_callback_ = true; |
763 request_->net_log().BeginEvent( | 758 request_->net_log().BeginEvent( |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 // plugin could set a referrer although sending the referrer is inhibited. | 864 // plugin could set a referrer although sending the referrer is inhibited. |
870 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); | 865 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); |
871 | 866 |
872 // Our consumer should have made sure that this is a safe referrer. See for | 867 // Our consumer should have made sure that this is a safe referrer. See for |
873 // instance WebCore::FrameLoader::HideReferrer. | 868 // instance WebCore::FrameLoader::HideReferrer. |
874 if (referrer.is_valid()) { | 869 if (referrer.is_valid()) { |
875 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, | 870 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, |
876 referrer.spec()); | 871 referrer.spec()); |
877 } | 872 } |
878 | 873 |
879 if (request_->context()) { | 874 request_info_.extra_headers.SetHeaderIfMissing( |
880 request_info_.extra_headers.SetHeaderIfMissing( | 875 HttpRequestHeaders::kUserAgent, |
881 HttpRequestHeaders::kUserAgent, | 876 request_->context()->GetUserAgent(request_->url())); |
882 request_->context()->GetUserAgent(request_->url())); | |
883 } | |
884 | 877 |
885 AddExtraHeaders(); | 878 AddExtraHeaders(); |
886 AddCookieHeaderAndStart(); | 879 AddCookieHeaderAndStart(); |
887 } | 880 } |
888 | 881 |
889 void URLRequestHttpJob::Kill() { | 882 void URLRequestHttpJob::Kill() { |
890 if (!transaction_.get()) | 883 if (!transaction_.get()) |
891 return; | 884 return; |
892 | 885 |
893 weak_factory_.InvalidateWeakPtrs(); | 886 weak_factory_.InvalidateWeakPtrs(); |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 | 1467 |
1475 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1468 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
1476 awaiting_callback_ = false; | 1469 awaiting_callback_ = false; |
1477 } | 1470 } |
1478 | 1471 |
1479 void URLRequestHttpJob::OnDetachRequest() { | 1472 void URLRequestHttpJob::OnDetachRequest() { |
1480 http_transaction_delegate_->OnDetachRequest(); | 1473 http_transaction_delegate_->OnDetachRequest(); |
1481 } | 1474 } |
1482 | 1475 |
1483 } // namespace net | 1476 } // namespace net |
OLD | NEW |