Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: net/url_request/url_request_job.cc

Issue 398903002: Plumb redirect info out of net, through content, and into child processes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add a TODO Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_job.h" 5 #include "net/url_request/url_request_job.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/power_monitor/power_monitor.h" 10 #include "base/power_monitor/power_monitor.h"
(...skipping 15 matching lines...) Expand all
26 NetworkDelegate* network_delegate) 26 NetworkDelegate* network_delegate)
27 : request_(request), 27 : request_(request),
28 done_(false), 28 done_(false),
29 prefilter_bytes_read_(0), 29 prefilter_bytes_read_(0),
30 postfilter_bytes_read_(0), 30 postfilter_bytes_read_(0),
31 filter_input_byte_count_(0), 31 filter_input_byte_count_(0),
32 filter_needs_more_output_space_(false), 32 filter_needs_more_output_space_(false),
33 filtered_read_buffer_len_(0), 33 filtered_read_buffer_len_(0),
34 has_handled_response_(false), 34 has_handled_response_(false),
35 expected_content_size_(-1), 35 expected_content_size_(-1),
36 deferred_redirect_status_code_(-1),
37 network_delegate_(network_delegate), 36 network_delegate_(network_delegate),
38 weak_factory_(this) { 37 weak_factory_(this) {
39 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); 38 base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
40 if (power_monitor) 39 if (power_monitor)
41 power_monitor->AddObserver(this); 40 power_monitor->AddObserver(this);
42 } 41 }
43 42
44 void URLRequestJob::SetUpload(UploadDataStream* upload) { 43 void URLRequestJob::SetUpload(UploadDataStream* upload) {
45 } 44 }
46 45
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 } 195 }
197 196
198 void URLRequestJob::ContinueDespiteLastError() { 197 void URLRequestJob::ContinueDespiteLastError() {
199 // Implementations should know how to recover from errors they generate. 198 // Implementations should know how to recover from errors they generate.
200 // If this code was reached, we are trying to recover from an error that 199 // If this code was reached, we are trying to recover from an error that
201 // we don't know how to recover from. 200 // we don't know how to recover from.
202 NOTREACHED(); 201 NOTREACHED();
203 } 202 }
204 203
205 void URLRequestJob::FollowDeferredRedirect() { 204 void URLRequestJob::FollowDeferredRedirect() {
206 DCHECK(deferred_redirect_status_code_ != -1); 205 DCHECK_NE(-1, deferred_redirect_info_.status_code);
207 206
208 // NOTE: deferred_redirect_url_ may be invalid, and attempting to redirect to 207 // NOTE: deferred_redirect_info_ may be invalid, and attempting to follow it
209 // such an URL will fail inside FollowRedirect. The DCHECK above asserts 208 // will fail inside FollowRedirect. The DCHECK above asserts that we called
210 // that we called OnReceivedRedirect. 209 // OnReceivedRedirect.
211 210
212 // It is also possible that FollowRedirect will drop the last reference to 211 // It is also possible that FollowRedirect will drop the last reference to
213 // this job, so we need to reset our members before calling it. 212 // this job, so we need to reset our members before calling it.
214 213
215 GURL redirect_url = deferred_redirect_url_; 214 RedirectInfo redirect_info = deferred_redirect_info_;
216 int redirect_status_code = deferred_redirect_status_code_; 215 deferred_redirect_info_ = RedirectInfo();
217 216 FollowRedirect(redirect_info);
218 deferred_redirect_url_ = GURL();
219 deferred_redirect_status_code_ = -1;
220
221 FollowRedirect(redirect_url, redirect_status_code);
222 } 217 }
223 218
224 void URLRequestJob::ResumeNetworkStart() { 219 void URLRequestJob::ResumeNetworkStart() {
225 // This should only be called for HTTP Jobs, and implemented in the derived 220 // This should only be called for HTTP Jobs, and implemented in the derived
226 // class. 221 // class.
227 NOTREACHED(); 222 NOTREACHED();
228 } 223 }
229 224
230 bool URLRequestJob::GetMimeType(std::string* mime_type) const { 225 bool URLRequestJob::GetMimeType(std::string* mime_type) const {
231 return false; 226 return false;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 if (request_) 323 if (request_)
329 request_->OnHeadersComplete(); 324 request_->OnHeadersComplete();
330 325
331 GURL new_location; 326 GURL new_location;
332 int http_status_code; 327 int http_status_code;
333 if (IsRedirectResponse(&new_location, &http_status_code)) { 328 if (IsRedirectResponse(&new_location, &http_status_code)) {
334 // Redirect response bodies are not read. Notify the transaction 329 // Redirect response bodies are not read. Notify the transaction
335 // so it does not treat being stopped as an error. 330 // so it does not treat being stopped as an error.
336 DoneReadingRedirectResponse(); 331 DoneReadingRedirectResponse();
337 332
338 const GURL& url = request_->url(); 333 RedirectInfo redirect_info =
339 334 ComputeRedirectInfo(new_location, http_status_code);
340 // Move the reference fragment of the old location to the new one if the
341 // new one has none. This duplicates mozilla's behavior.
342 if (url.is_valid() && url.has_ref() && !new_location.has_ref() &&
343 CopyFragmentOnRedirect(new_location)) {
344 GURL::Replacements replacements;
345 // Reference the |ref| directly out of the original URL to avoid a
346 // malloc.
347 replacements.SetRef(url.spec().data(),
348 url.parsed_for_possibly_invalid_spec().ref);
349 new_location = new_location.ReplaceComponents(replacements);
350 }
351 335
352 bool defer_redirect = false; 336 bool defer_redirect = false;
353 request_->NotifyReceivedRedirect(new_location, &defer_redirect); 337 request_->NotifyReceivedRedirect(redirect_info, &defer_redirect);
354 338
355 // Ensure that the request wasn't detached or destroyed in 339 // Ensure that the request wasn't detached or destroyed in
356 // NotifyReceivedRedirect 340 // NotifyReceivedRedirect
357 if (!request_ || !request_->has_delegate()) 341 if (!request_ || !request_->has_delegate())
358 return; 342 return;
359 343
360 // If we were not cancelled, then maybe follow the redirect. 344 // If we were not cancelled, then maybe follow the redirect.
361 if (request_->status().is_success()) { 345 if (request_->status().is_success()) {
362 if (defer_redirect) { 346 if (defer_redirect) {
363 deferred_redirect_url_ = new_location; 347 deferred_redirect_info_ = redirect_info;
364 deferred_redirect_status_code_ = http_status_code;
365 } else { 348 } else {
366 FollowRedirect(new_location, http_status_code); 349 FollowRedirect(redirect_info);
367 } 350 }
368 return; 351 return;
369 } 352 }
370 } else if (NeedsAuth()) { 353 } else if (NeedsAuth()) {
371 scoped_refptr<AuthChallengeInfo> auth_info; 354 scoped_refptr<AuthChallengeInfo> auth_info;
372 GetAuthChallengeInfo(&auth_info); 355 GetAuthChallengeInfo(&auth_info);
373 // Need to check for a NULL auth_info because the server may have failed 356 // Need to check for a NULL auth_info because the server may have failed
374 // to send a challenge with the 401 response. 357 // to send a challenge with the 401 response.
375 if (auth_info.get()) { 358 if (auth_info.get()) {
376 request_->NotifyAuthRequired(auth_info.get()); 359 request_->NotifyAuthRequired(auth_info.get());
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 702
720 if (!request_->status().is_io_pending()) { 703 if (!request_->status().is_io_pending()) {
721 // If the read completes synchronously, either success or failure, 704 // If the read completes synchronously, either success or failure,
722 // invoke the OnRawReadComplete callback so we can account for the 705 // invoke the OnRawReadComplete callback so we can account for the
723 // completed read. 706 // completed read.
724 OnRawReadComplete(*bytes_read); 707 OnRawReadComplete(*bytes_read);
725 } 708 }
726 return rv; 709 return rv;
727 } 710 }
728 711
729 void URLRequestJob::FollowRedirect(const GURL& location, int http_status_code) { 712 void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) {
730 int rv = request_->Redirect(location, http_status_code); 713 int rv = request_->Redirect(redirect_info);
731 if (rv != OK) 714 if (rv != OK)
732 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 715 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
733 } 716 }
734 717
735 void URLRequestJob::OnRawReadComplete(int bytes_read) { 718 void URLRequestJob::OnRawReadComplete(int bytes_read) {
736 DCHECK(raw_read_buffer_.get()); 719 DCHECK(raw_read_buffer_.get());
737 // If |filter_| is non-NULL, bytes will be logged after it is applied instead. 720 // If |filter_| is non-NULL, bytes will be logged after it is applied instead.
738 if (!filter_.get() && request() && request()->net_log().IsLoggingBytes() && 721 if (!filter_.get() && request() && request()->net_log().IsLoggingBytes() &&
739 bytes_read > 0) { 722 bytes_read > 0) {
740 request()->net_log().AddByteTransferEvent( 723 request()->net_log().AddByteTransferEvent(
(...skipping 22 matching lines...) Expand all
763 network_delegate_->NotifyRawBytesRead(*request_, bytes_read); 746 network_delegate_->NotifyRawBytesRead(*request_, bytes_read);
764 } 747 }
765 748
766 bool URLRequestJob::FilterHasData() { 749 bool URLRequestJob::FilterHasData() {
767 return filter_.get() && filter_->stream_data_len(); 750 return filter_.get() && filter_->stream_data_len();
768 } 751 }
769 752
770 void URLRequestJob::UpdatePacketReadTimes() { 753 void URLRequestJob::UpdatePacketReadTimes() {
771 } 754 }
772 755
756 RedirectInfo URLRequestJob::ComputeRedirectInfo(const GURL& location,
757 int http_status_code) {
758 const GURL& url = request_->url();
759
760 // Move the reference fragment of the old location to the new one if the
761 // new one has none. This duplicates mozilla's behavior.
762 GURL new_location = location;
763 if (url.is_valid() && url.has_ref() && !new_location.has_ref() &&
764 CopyFragmentOnRedirect(new_location)) {
765 GURL::Replacements replacements;
766 // Reference the |ref| directly out of the original URL to avoid a
767 // malloc.
768 replacements.SetRef(url.spec().data(),
769 url.parsed_for_possibly_invalid_spec().ref);
770 new_location = new_location.ReplaceComponents(replacements);
771 }
772
773 RedirectInfo redirect_info;
774
775 redirect_info.status_code = http_status_code;
776
777 // The request method may change, depending on the status code.
778 redirect_info.method = URLRequest::ComputeMethodForRedirect(
779 request_->method(), http_status_code);
780
781 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.
782
783 // Update the first-party URL if appropriate.
784 if (request_->first_party_url_policy() ==
785 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.
786 redirect_info.first_party_for_cookies = new_location;
787 } else {
788 redirect_info.first_party_for_cookies = request_->first_party_for_cookies();
789 }
790
791 // Suppress the referrer if we're redirecting out of https.
792 if (request_->referrer_policy() ==
793 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE &&
794 GURL(request_->referrer()).SchemeIsSecure() &&
795 !new_location.SchemeIsSecure()) {
796 redirect_info.referrer.clear();
797 } else {
798 redirect_info.referrer = request_->referrer();
799 }
800
801 return redirect_info;
802 }
803
773 } // namespace net 804 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698