diff options
-rw-r--r-- | chrome/browser/renderer_host/offline_resource_throttle.cc | 15 | ||||
-rw-r--r-- | net/url_request/url_request.cc | 21 | ||||
-rw-r--r-- | net/url_request/url_request.h | 4 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.cc | 21 |
4 files changed, 41 insertions, 20 deletions
diff --git a/chrome/browser/renderer_host/offline_resource_throttle.cc b/chrome/browser/renderer_host/offline_resource_throttle.cc index 5de95a6..b5afb31 100644 --- a/chrome/browser/renderer_host/offline_resource_throttle.cc +++ b/chrome/browser/renderer_host/offline_resource_throttle.cc @@ -83,6 +83,18 @@ void OfflineResourceThrottle::WillStartRequest(bool* defer) { DVLOG(1) << "WillStartRequest: this=" << this << ", url=" << request_->url(); + const GURL* url = &(request_->url()); + const GURL* first_party = &(request_->first_party_for_cookies()); + + // Anticipate a client-side HSTS based redirect from HTTP to HTTPS, and + // ask the appcache about the HTTPS url instead of the HTTP url. + GURL redirect_url; + if (request_->GetHSTSRedirect(&redirect_url)) { + if (url->GetOrigin() == first_party->GetOrigin()) + first_party = &redirect_url; + url = &redirect_url; + } + DCHECK(appcache_completion_callback_.IsCancelled()); appcache_completion_callback_.Reset( @@ -90,8 +102,7 @@ void OfflineResourceThrottle::WillStartRequest(bool* defer) { AsWeakPtr())); ResourceContext::GetAppCacheService(resource_context_)-> CanHandleMainResourceOffline( - request_->url(), - request_->first_party_for_cookies(), + *url, *first_party, appcache_completion_callback_.callback()); *defer = true; diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index d3fa6d1..f3d813d 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -769,6 +769,27 @@ int64 URLRequest::GetExpectedContentSize() const { return expected_content_size; } +bool URLRequest::GetHSTSRedirect(GURL* redirect_url) const { + const GURL& url = this->url(); + if (!url.SchemeIs("http")) + return false; + TransportSecurityState::DomainState domain_state; + if (context()->transport_security_state() && + context()->transport_security_state()->GetDomainState( + url.host(), + SSLConfigService::IsSNIAvailable(context()->ssl_config_service()), + &domain_state) && + domain_state.ShouldRedirectHTTPToHTTPS()) { + url_canon::Replacements<char> replacements; + const char kNewScheme[] = "https"; + replacements.SetScheme(kNewScheme, + url_parse::Component(0, strlen(kNewScheme))); + *redirect_url = url.ReplaceComponents(replacements); + return true; + } + return false; +} + void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) { NetworkDelegate::AuthRequiredResponse rv = NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index bff16d7..b00cf88 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h @@ -585,6 +585,10 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe), priority_ = priority; } + // Returns true iff this request would be internally redirected to HTTPS + // due to HSTS. If so, |redirect_url| is rewritten to the new HTTPS URL. + bool GetHSTSRedirect(GURL* redirect_url) const; + // This method is intended only for unit tests, but it is being used by // unit tests outside of net :(. URLRequestJob* job() { return job_; } diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 4e31963..1062563 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -140,24 +140,9 @@ URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); } - TransportSecurityState::DomainState domain_state; - if (scheme == "http" && - request->context()->transport_security_state() && - request->context()->transport_security_state()->GetDomainState( - request->url().host(), - SSLConfigService::IsSNIAvailable( - request->context()->ssl_config_service()), - &domain_state) && - domain_state.ShouldRedirectHTTPToHTTPS()) { - DCHECK_EQ(request->url().scheme(), "http"); - url_canon::Replacements<char> replacements; - static const char kNewScheme[] = "https"; - replacements.SetScheme(kNewScheme, - url_parse::Component(0, strlen(kNewScheme))); - GURL new_location = request->url().ReplaceComponents(replacements); - return new URLRequestRedirectJob(request, new_location); - } - + GURL redirect_url; + if (request->GetHSTSRedirect(&redirect_url)) + return new URLRequestRedirectJob(request, redirect_url); return new URLRequestHttpJob(request); } |