Chromium Code Reviews| Index: net/url_request/url_request_job.cc |
| diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc |
| index a66a3f553f9e16c49b8101b1f4d86bdf22dd249e..5c9431ede7f79ad62a11643c3e21f176e228a7d5 100644 |
| --- a/net/url_request/url_request_job.cc |
| +++ b/net/url_request/url_request_job.cc |
| @@ -33,7 +33,6 @@ URLRequestJob::URLRequestJob(URLRequest* request, |
| filtered_read_buffer_len_(0), |
| has_handled_response_(false), |
| expected_content_size_(-1), |
| - deferred_redirect_status_code_(-1), |
| network_delegate_(network_delegate), |
| weak_factory_(this) { |
| base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
| @@ -203,22 +202,18 @@ void URLRequestJob::ContinueDespiteLastError() { |
| } |
| void URLRequestJob::FollowDeferredRedirect() { |
| - DCHECK(deferred_redirect_status_code_ != -1); |
| + DCHECK_NE(-1, deferred_redirect_info_.status_code); |
| - // NOTE: deferred_redirect_url_ may be invalid, and attempting to redirect to |
| - // such an URL will fail inside FollowRedirect. The DCHECK above asserts |
| - // that we called OnReceivedRedirect. |
| + // NOTE: deferred_redirect_info_ may be invalid, and attempting to follow it |
| + // will fail inside FollowRedirect. The DCHECK above asserts that we called |
| + // OnReceivedRedirect. |
| // It is also possible that FollowRedirect will drop the last reference to |
| // this job, so we need to reset our members before calling it. |
| - GURL redirect_url = deferred_redirect_url_; |
| - int redirect_status_code = deferred_redirect_status_code_; |
| - |
| - deferred_redirect_url_ = GURL(); |
| - deferred_redirect_status_code_ = -1; |
| - |
| - FollowRedirect(redirect_url, redirect_status_code); |
| + RedirectInfo redirect_info = deferred_redirect_info_; |
| + deferred_redirect_info_ = RedirectInfo(); |
| + FollowRedirect(redirect_info); |
| } |
| void URLRequestJob::ResumeNetworkStart() { |
| @@ -335,22 +330,11 @@ void URLRequestJob::NotifyHeadersComplete() { |
| // so it does not treat being stopped as an error. |
| DoneReadingRedirectResponse(); |
| - const GURL& url = request_->url(); |
| - |
| - // Move the reference fragment of the old location to the new one if the |
| - // new one has none. This duplicates mozilla's behavior. |
| - if (url.is_valid() && url.has_ref() && !new_location.has_ref() && |
| - CopyFragmentOnRedirect(new_location)) { |
| - GURL::Replacements replacements; |
| - // Reference the |ref| directly out of the original URL to avoid a |
| - // malloc. |
| - replacements.SetRef(url.spec().data(), |
| - url.parsed_for_possibly_invalid_spec().ref); |
| - new_location = new_location.ReplaceComponents(replacements); |
| - } |
| + RedirectInfo redirect_info = |
| + ComputeRedirectInfo(new_location, http_status_code); |
| bool defer_redirect = false; |
| - request_->NotifyReceivedRedirect(new_location, &defer_redirect); |
| + request_->NotifyReceivedRedirect(redirect_info, &defer_redirect); |
| // Ensure that the request wasn't detached or destroyed in |
| // NotifyReceivedRedirect |
| @@ -360,10 +344,9 @@ void URLRequestJob::NotifyHeadersComplete() { |
| // If we were not cancelled, then maybe follow the redirect. |
| if (request_->status().is_success()) { |
| if (defer_redirect) { |
| - deferred_redirect_url_ = new_location; |
| - deferred_redirect_status_code_ = http_status_code; |
| + deferred_redirect_info_ = redirect_info; |
| } else { |
| - FollowRedirect(new_location, http_status_code); |
| + FollowRedirect(redirect_info); |
| } |
| return; |
| } |
| @@ -726,8 +709,8 @@ bool URLRequestJob::ReadRawDataHelper(IOBuffer* buf, int buf_size, |
| return rv; |
| } |
| -void URLRequestJob::FollowRedirect(const GURL& location, int http_status_code) { |
| - int rv = request_->Redirect(location, http_status_code); |
| +void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) { |
| + int rv = request_->Redirect(redirect_info); |
| if (rv != OK) |
| NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); |
| } |
| @@ -770,4 +753,52 @@ bool URLRequestJob::FilterHasData() { |
| void URLRequestJob::UpdatePacketReadTimes() { |
| } |
| +RedirectInfo URLRequestJob::ComputeRedirectInfo(const GURL& location, |
| + int http_status_code) { |
| + const GURL& url = request_->url(); |
| + |
| + // Move the reference fragment of the old location to the new one if the |
| + // new one has none. This duplicates mozilla's behavior. |
| + GURL new_location = location; |
| + if (url.is_valid() && url.has_ref() && !new_location.has_ref() && |
| + CopyFragmentOnRedirect(new_location)) { |
| + GURL::Replacements replacements; |
| + // Reference the |ref| directly out of the original URL to avoid a |
| + // malloc. |
| + replacements.SetRef(url.spec().data(), |
| + url.parsed_for_possibly_invalid_spec().ref); |
| + new_location = new_location.ReplaceComponents(replacements); |
| + } |
| + |
| + RedirectInfo redirect_info; |
| + |
| + redirect_info.status_code = http_status_code; |
| + |
| + // The request method may change, depending on the status code. |
| + redirect_info.method = URLRequest::ComputeMethodForRedirect( |
| + request_->method(), http_status_code); |
| + |
| + redirect_info.url = new_location; |
|
mmenke
2014/07/17 16:55:09
Could avoid this copy by getting rid of new_locati
davidben
2014/07/17 22:03:55
Done.
|
| + |
| + // Update the first-party URL if appropriate. |
| + if (request_->first_party_url_policy() == |
| + URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT) { |
|
mmenke
2014/07/17 16:55:09
Sure there are integration tests for this (At leas
davidben
2014/07/17 22:03:55
Done.
|
| + redirect_info.first_party_for_cookies = new_location; |
| + } else { |
| + redirect_info.first_party_for_cookies = request_->first_party_for_cookies(); |
| + } |
| + |
| + // Suppress the referrer if we're redirecting out of https. |
| + if (request_->referrer_policy() == |
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE && |
| + GURL(request_->referrer()).SchemeIsSecure() && |
| + !new_location.SchemeIsSecure()) { |
| + redirect_info.referrer.clear(); |
| + } else { |
| + redirect_info.referrer = request_->referrer(); |
| + } |
| + |
| + return redirect_info; |
| +} |
| + |
| } // namespace net |