Index: net/url_request/url_request_job.cc |
=================================================================== |
--- net/url_request/url_request_job.cc (revision 21335) |
+++ net/url_request/url_request_job.cc (working copy) |
@@ -6,7 +6,6 @@ |
#include "base/message_loop.h" |
#include "base/string_util.h" |
-#include "googleurl/src/gurl.h" |
#include "net/base/auth.h" |
#include "net/base/io_buffer.h" |
#include "net/base/load_flags.h" |
@@ -30,6 +29,7 @@ |
read_buffer_len_(0), |
has_handled_response_(false), |
expected_content_size_(-1), |
+ deferred_redirect_status_code_(-1), |
packet_timing_enabled_(false), |
filter_input_byte_count_(0), |
bytes_observed_in_packets_(0), |
@@ -103,6 +103,17 @@ |
NOTREACHED(); |
} |
+void URLRequestJob::FollowDeferredRedirect() { |
+ DCHECK(deferred_redirect_status_code_ != -1); |
+ // 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. |
+ |
+ FollowRedirect(deferred_redirect_url_, deferred_redirect_status_code_); |
+ deferred_redirect_url_ = GURL(); |
+ deferred_redirect_status_code_ = -1; |
+} |
+ |
int64 URLRequestJob::GetByteReadCount() const { |
return filter_input_byte_count_; |
} |
@@ -322,8 +333,8 @@ |
// survival until we can get out of this method. |
scoped_refptr<URLRequestJob> self_preservation = this; |
+ GURL new_location; |
int http_status_code; |
- GURL new_location; |
if (IsRedirectResponse(&new_location, &http_status_code)) { |
const GURL& url = request_->url(); |
@@ -338,19 +349,21 @@ |
new_location = new_location.ReplaceComponents(replacements); |
} |
- // Toggle this flag to true so the consumer can access response headers. |
- // Then toggle it back if we choose to follow the redirect. |
- has_handled_response_ = true; |
- request_->ReceivedRedirect(new_location); |
+ bool defer_redirect = false; |
+ request_->ReceivedRedirect(new_location, &defer_redirect); |
// Ensure that the request wasn't detached or destroyed in ReceivedRedirect |
if (!request_ || !request_->delegate()) |
return; |
- // If we were not cancelled, then follow the redirect. |
+ // If we were not cancelled, then maybe follow the redirect. |
if (request_->status().is_success()) { |
- has_handled_response_ = false; |
- FollowRedirect(new_location, http_status_code); |
+ if (defer_redirect) { |
+ deferred_redirect_url_ = new_location; |
+ deferred_redirect_status_code_ = http_status_code; |
+ } else { |
+ FollowRedirect(new_location, http_status_code); |
+ } |
return; |
} |
} else if (NeedsAuth()) { |
@@ -507,19 +520,6 @@ |
return filter_.get() && filter_->stream_data_len(); |
} |
-void URLRequestJob::FollowRedirect(const GURL& location, |
- int http_status_code) { |
- g_url_request_job_tracker.OnJobRedirect(this, location, http_status_code); |
- Kill(); |
- // Kill could have notified the Delegate and destroyed the request. |
- if (!request_) |
- return; |
- |
- int rv = request_->Redirect(location, http_status_code); |
- if (rv != net::OK) |
- NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, rv)); |
-} |
- |
void URLRequestJob::RecordBytesRead(int bytes_read) { |
if (is_profiling()) { |
++(metrics_->number_of_read_IO_); |
@@ -710,3 +710,11 @@ |
return; |
} |
} |
+ |
+void URLRequestJob::FollowRedirect(const GURL& location, int http_status_code) { |
+ g_url_request_job_tracker.OnJobRedirect(this, location, http_status_code); |
+ |
+ int rv = request_->Redirect(location, http_status_code); |
+ if (rv != net::OK) |
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); |
+} |