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 |