| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 if (!request->context() || | 137 if (!request->context() || |
| 138 !request->context()->http_transaction_factory()) { | 138 !request->context()->http_transaction_factory()) { |
| 139 NOTREACHED() << "requires a valid context"; | 139 NOTREACHED() << "requires a valid context"; |
| 140 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); | 140 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); |
| 141 } | 141 } |
| 142 | 142 |
| 143 TransportSecurityState::DomainState domain_state; | 143 TransportSecurityState::DomainState domain_state; |
| 144 if (scheme == "http" && | 144 if (scheme == "http" && |
| 145 request->context()->transport_security_state() && | 145 request->context()->transport_security_state() && |
| 146 request->context()->transport_security_state()->GetDomainState( | 146 request->context()->transport_security_state()->GetDomainState( |
| 147 &domain_state, | |
| 148 request->url().host(), | 147 request->url().host(), |
| 149 SSLConfigService::IsSNIAvailable( | 148 SSLConfigService::IsSNIAvailable( |
| 150 request->context()->ssl_config_service())) && | 149 request->context()->ssl_config_service()), |
| 150 &domain_state) && |
| 151 domain_state.ShouldRedirectHTTPToHTTPS()) { | 151 domain_state.ShouldRedirectHTTPToHTTPS()) { |
| 152 DCHECK_EQ(request->url().scheme(), "http"); | 152 DCHECK_EQ(request->url().scheme(), "http"); |
| 153 url_canon::Replacements<char> replacements; | 153 url_canon::Replacements<char> replacements; |
| 154 static const char kNewScheme[] = "https"; | 154 static const char kNewScheme[] = "https"; |
| 155 replacements.SetScheme(kNewScheme, | 155 replacements.SetScheme(kNewScheme, |
| 156 url_parse::Component(0, strlen(kNewScheme))); | 156 url_parse::Component(0, strlen(kNewScheme))); |
| 157 GURL new_location = request->url().ReplaceComponents(replacements); | 157 GURL new_location = request->url().ReplaceComponents(replacements); |
| 158 return new URLRequestRedirectJob(request, new_location); | 158 return new URLRequestRedirectJob(request, new_location); |
| 159 } | 159 } |
| 160 | 160 |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 !ctx || !ctx->transport_security_state()) { | 592 !ctx || !ctx->transport_security_state()) { |
| 593 return; | 593 return; |
| 594 } | 594 } |
| 595 | 595 |
| 596 TransportSecurityState* security_state = ctx->transport_security_state(); | 596 TransportSecurityState* security_state = ctx->transport_security_state(); |
| 597 TransportSecurityState::DomainState domain_state; | 597 TransportSecurityState::DomainState domain_state; |
| 598 const std::string& host = request_info_.url.host(); | 598 const std::string& host = request_info_.url.host(); |
| 599 | 599 |
| 600 bool sni_available = | 600 bool sni_available = |
| 601 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 601 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); |
| 602 if (!security_state->HasMetadata(&domain_state, host, sni_available)) { | 602 if (!security_state->GetDomainState(host, sni_available, &domain_state)) |
| 603 // |HasMetadata| may have altered |domain_state| while searching. If not | 603 // |GetDomainState| may have altered |domain_state| while searching. If |
| 604 // found, start with a fresh state. | 604 // not found, start with a fresh state. |
| 605 domain_state = TransportSecurityState::DomainState(); | 605 domain_state.upgrade_mode = |
| 606 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; | 606 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
| 607 } | |
| 608 | 607 |
| 609 HttpResponseHeaders* headers = GetResponseHeaders(); | 608 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 610 std::string value; | 609 std::string value; |
| 611 void* iter = NULL; | 610 void* iter = NULL; |
| 611 base::Time now = base::Time::Now(); |
| 612 | 612 |
| 613 while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { | 613 while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { |
| 614 int max_age; | 614 TransportSecurityState::DomainState domain_state; |
| 615 bool include_subdomains; | 615 if (domain_state.ParseSTSHeader(now, value)) |
| 616 if (TransportSecurityState::ParseHeader(value, &max_age, | |
| 617 &include_subdomains)) { | |
| 618 base::Time current_time(base::Time::Now()); | |
| 619 base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); | |
| 620 | |
| 621 domain_state.expiry = current_time + max_age_delta; | |
| 622 domain_state.include_subdomains = include_subdomains; | |
| 623 | |
| 624 security_state->EnableHost(host, domain_state); | 616 security_state->EnableHost(host, domain_state); |
| 625 } | |
| 626 } | 617 } |
| 627 } | 618 } |
| 628 | 619 |
| 629 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { | 620 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { |
| 630 DCHECK(response_info_); | 621 DCHECK(response_info_); |
| 631 | 622 |
| 632 const URLRequestContext* ctx = request_->context(); | 623 const URLRequestContext* ctx = request_->context(); |
| 633 const SSLInfo& ssl_info = response_info_->ssl_info; | 624 const SSLInfo& ssl_info = response_info_->ssl_info; |
| 634 | 625 |
| 635 // Only accept public key pins headers on HTTPS connections that have no | 626 // Only accept public key pins headers on HTTPS connections that have no |
| 636 // certificate errors. | 627 // certificate errors. |
| 637 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 628 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
| 638 !ctx || !ctx->transport_security_state()) { | 629 !ctx || !ctx->transport_security_state()) { |
| 639 return; | 630 return; |
| 640 } | 631 } |
| 641 | 632 |
| 642 TransportSecurityState* security_state = ctx->transport_security_state(); | 633 TransportSecurityState* security_state = ctx->transport_security_state(); |
| 643 TransportSecurityState::DomainState domain_state; | 634 TransportSecurityState::DomainState domain_state; |
| 644 const std::string& host = request_info_.url.host(); | 635 const std::string& host = request_info_.url.host(); |
| 645 | 636 |
| 646 bool sni_available = | 637 bool sni_available = |
| 647 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 638 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); |
| 648 if (!security_state->HasMetadata(&domain_state, host, sni_available)) { | 639 if (!security_state->GetDomainState(host, sni_available, &domain_state)) |
| 649 // |HasMetadata| may have altered |domain_state| while searching. If not | 640 // |GetDomainState| may have altered |domain_state| while searching. If |
| 650 // found, start with a fresh state. | 641 // not found, start with a fresh state. |
| 651 domain_state = TransportSecurityState::DomainState(); | 642 domain_state.upgrade_mode = |
| 652 domain_state.mode = TransportSecurityState::DomainState::MODE_PINNING_ONLY; | 643 TransportSecurityState::DomainState::MODE_DEFAULT; |
| 653 } | |
| 654 | 644 |
| 655 HttpResponseHeaders* headers = GetResponseHeaders(); | 645 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 656 void* iter = NULL; | 646 void* iter = NULL; |
| 657 std::string value; | 647 std::string value; |
| 648 base::Time now = base::Time::Now(); |
| 658 | 649 |
| 659 while (headers->EnumerateHeader(&iter, "Public-Key-Pins", &value)) { | 650 while (headers->EnumerateHeader(&iter, "Public-Key-Pins", &value)) { |
| 660 // Note that ParsePinsHeader updates |domain_state| (iff the header parses | 651 // Note that ParsePinsHeader updates |domain_state| (iff the header parses |
| 661 // correctly), but does not completely overwrite it. It just updates the | 652 // correctly), but does not completely overwrite it. It just updates the |
| 662 // dynamic pinning metadata. | 653 // dynamic pinning metadata. |
| 663 if (TransportSecurityState::ParsePinsHeader(value, ssl_info, | 654 if (domain_state.ParsePinsHeader(now, value, ssl_info)) |
| 664 &domain_state)) { | |
| 665 security_state->EnableHost(host, domain_state); | 655 security_state->EnableHost(host, domain_state); |
| 666 } | |
| 667 } | 656 } |
| 668 } | 657 } |
| 669 | 658 |
| 670 void URLRequestHttpJob::OnStartCompleted(int result) { | 659 void URLRequestHttpJob::OnStartCompleted(int result) { |
| 671 RecordTimer(); | 660 RecordTimer(); |
| 672 | 661 |
| 673 // If the request was destroyed, then there is no more work to do. | 662 // If the request was destroyed, then there is no more work to do. |
| 674 if (!request_) | 663 if (!request_) |
| 675 return; | 664 return; |
| 676 | 665 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 | 711 |
| 723 SaveCookiesAndNotifyHeadersComplete(net::OK); | 712 SaveCookiesAndNotifyHeadersComplete(net::OK); |
| 724 } else if (IsCertificateError(result)) { | 713 } else if (IsCertificateError(result)) { |
| 725 // We encountered an SSL certificate error. Ask our delegate to decide | 714 // We encountered an SSL certificate error. Ask our delegate to decide |
| 726 // what we should do. | 715 // what we should do. |
| 727 | 716 |
| 728 TransportSecurityState::DomainState domain_state; | 717 TransportSecurityState::DomainState domain_state; |
| 729 const bool fatal = | 718 const bool fatal = |
| 730 context_->transport_security_state() && | 719 context_->transport_security_state() && |
| 731 context_->transport_security_state()->GetDomainState( | 720 context_->transport_security_state()->GetDomainState( |
| 732 &domain_state, request_info_.url.host(), | 721 request_info_.url.host(), |
| 733 SSLConfigService::IsSNIAvailable(context_->ssl_config_service())); | 722 SSLConfigService::IsSNIAvailable(context_->ssl_config_service()), |
| 723 &domain_state); |
| 734 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal); | 724 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal); |
| 735 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 725 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 736 NotifyCertificateRequested( | 726 NotifyCertificateRequested( |
| 737 transaction_->GetResponseInfo()->cert_request_info); | 727 transaction_->GetResponseInfo()->cert_request_info); |
| 738 } else { | 728 } else { |
| 739 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); | 729 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| 740 } | 730 } |
| 741 } | 731 } |
| 742 | 732 |
| 743 void URLRequestHttpJob::OnHeadersReceivedCallback(int result) { | 733 void URLRequestHttpJob::OnHeadersReceivedCallback(int result) { |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 return override_response_headers_.get() ? | 1406 return override_response_headers_.get() ? |
| 1417 override_response_headers_ : | 1407 override_response_headers_ : |
| 1418 transaction_->GetResponseInfo()->headers; | 1408 transaction_->GetResponseInfo()->headers; |
| 1419 } | 1409 } |
| 1420 | 1410 |
| 1421 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1411 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
| 1422 awaiting_callback_ = false; | 1412 awaiting_callback_ = false; |
| 1423 } | 1413 } |
| 1424 | 1414 |
| 1425 } // namespace net | 1415 } // namespace net |
| OLD | NEW |