diff options
Diffstat (limited to 'net/url_request/url_request_job.cc')
-rw-r--r-- | net/url_request/url_request_job.cc | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 797caa6..f9043cc 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc @@ -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 @@ URLRequestJob::URLRequestJob(URLRequest* request) 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 @@ void URLRequestJob::ContinueDespiteLastError() { 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_; } @@ -175,6 +186,14 @@ bool URLRequestJob::ReadRawDataForFilter(int *bytes_read) { return rv; } +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)); +} + void URLRequestJob::FilteredDataRead(int bytes_read) { DCHECK(filter_.get()); // don't add data if there is no filter filter_->FlushStreamBuffer(bytes_read); @@ -322,8 +341,8 @@ void URLRequestJob::NotifyHeadersComplete() { // survival until we can get out of this method. scoped_refptr<URLRequestJob> self_preservation = this; - int http_status_code; GURL new_location; + int http_status_code; if (IsRedirectResponse(&new_location, &http_status_code)) { const GURL& url = request_->url(); @@ -338,19 +357,21 @@ void URLRequestJob::NotifyHeadersComplete() { 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 +528,6 @@ bool URLRequestJob::FilterHasData() { 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_); |