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 |
deleted file mode 100644 |
index 6f84babdb67a2e08d70f70857d6868c423002fb8..0000000000000000000000000000000000000000 |
--- a/net/url_request/url_request_job.cc |
+++ /dev/null |
@@ -1,964 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/url_request/url_request_job.h" |
- |
-#include "base/bind.h" |
-#include "base/compiler_specific.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/power_monitor/power_monitor.h" |
-#include "base/profiler/scoped_tracker.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_util.h" |
-#include "base/values.h" |
-#include "net/base/auth.h" |
-#include "net/base/host_port_pair.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/load_states.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/network_delegate.h" |
-#include "net/filter/filter.h" |
-#include "net/http/http_response_headers.h" |
- |
-namespace net { |
- |
-namespace { |
- |
-// Callback for TYPE_URL_REQUEST_FILTERS_SET net-internals event. |
-base::Value* FiltersSetCallback(Filter* filter, |
- NetLog::LogLevel /* log_level */) { |
- base::DictionaryValue* event_params = new base::DictionaryValue(); |
- event_params->SetString("filters", filter->OrderedFilterList()); |
- return event_params; |
-} |
- |
-std::string ComputeMethodForRedirect(const std::string& method, |
- int http_status_code) { |
- // For 303 redirects, all request methods except HEAD are converted to GET, |
- // as per the latest httpbis draft. The draft also allows POST requests to |
- // be converted to GETs when following 301/302 redirects, for historical |
- // reasons. Most major browsers do this and so shall we. Both RFC 2616 and |
- // the httpbis draft say to prompt the user to confirm the generation of new |
- // requests, other than GET and HEAD requests, but IE omits these prompts and |
- // so shall we. |
- // See: |
- // https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3 |
- if ((http_status_code == 303 && method != "HEAD") || |
- ((http_status_code == 301 || http_status_code == 302) && |
- method == "POST")) { |
- return "GET"; |
- } |
- return method; |
-} |
- |
-} // namespace |
- |
-URLRequestJob::URLRequestJob(URLRequest* request, |
- NetworkDelegate* network_delegate) |
- : request_(request), |
- done_(false), |
- prefilter_bytes_read_(0), |
- postfilter_bytes_read_(0), |
- filter_input_byte_count_(0), |
- filter_needs_more_output_space_(false), |
- filtered_read_buffer_len_(0), |
- has_handled_response_(false), |
- expected_content_size_(-1), |
- network_delegate_(network_delegate), |
- weak_factory_(this) { |
- base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
- if (power_monitor) |
- power_monitor->AddObserver(this); |
-} |
- |
-void URLRequestJob::SetUpload(UploadDataStream* upload) { |
-} |
- |
-void URLRequestJob::SetExtraRequestHeaders(const HttpRequestHeaders& headers) { |
-} |
- |
-void URLRequestJob::SetPriority(RequestPriority priority) { |
-} |
- |
-void URLRequestJob::Kill() { |
- weak_factory_.InvalidateWeakPtrs(); |
- // Make sure the request is notified that we are done. We assume that the |
- // request took care of setting its error status before calling Kill. |
- if (request_) |
- NotifyCanceled(); |
-} |
- |
-void URLRequestJob::DetachRequest() { |
- request_ = NULL; |
-} |
- |
-// This function calls ReadData to get stream data. If a filter exists, passes |
-// the data to the attached filter. Then returns the output from filter back to |
-// the caller. |
-bool URLRequestJob::Read(IOBuffer* buf, int buf_size, int *bytes_read) { |
- bool rv = false; |
- |
- DCHECK_LT(buf_size, 1000000); // Sanity check. |
- DCHECK(buf); |
- DCHECK(bytes_read); |
- DCHECK(filtered_read_buffer_.get() == NULL); |
- DCHECK_EQ(0, filtered_read_buffer_len_); |
- |
- *bytes_read = 0; |
- |
- // Skip Filter if not present. |
- if (!filter_.get()) { |
- rv = ReadRawDataHelper(buf, buf_size, bytes_read); |
- } else { |
- // Save the caller's buffers while we do IO |
- // in the filter's buffers. |
- filtered_read_buffer_ = buf; |
- filtered_read_buffer_len_ = buf_size; |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile2( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 URLRequestJob::Read2")); |
- |
- if (ReadFilteredData(bytes_read)) { |
- rv = true; // We have data to return. |
- |
- // It is fine to call DoneReading even if ReadFilteredData receives 0 |
- // bytes from the net, but we avoid making that call if we know for |
- // sure that's the case (ReadRawDataHelper path). |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is |
- // fixed. |
- tracked_objects::ScopedTracker tracking_profile3( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 URLRequestJob::Read3")); |
- |
- if (*bytes_read == 0) |
- DoneReading(); |
- } else { |
- rv = false; // Error, or a new IO is pending. |
- } |
- } |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile4( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 URLRequestJob::Read4")); |
- |
- if (rv && *bytes_read == 0) |
- NotifyDone(URLRequestStatus()); |
- return rv; |
-} |
- |
-void URLRequestJob::StopCaching() { |
- // Nothing to do here. |
-} |
- |
-bool URLRequestJob::GetFullRequestHeaders(HttpRequestHeaders* headers) const { |
- // Most job types don't send request headers. |
- return false; |
-} |
- |
-int64 URLRequestJob::GetTotalReceivedBytes() const { |
- return 0; |
-} |
- |
-LoadState URLRequestJob::GetLoadState() const { |
- return LOAD_STATE_IDLE; |
-} |
- |
-UploadProgress URLRequestJob::GetUploadProgress() const { |
- return UploadProgress(); |
-} |
- |
-bool URLRequestJob::GetCharset(std::string* charset) { |
- return false; |
-} |
- |
-void URLRequestJob::GetResponseInfo(HttpResponseInfo* info) { |
-} |
- |
-void URLRequestJob::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { |
- // Only certain request types return more than just request start times. |
-} |
- |
-bool URLRequestJob::GetResponseCookies(std::vector<std::string>* cookies) { |
- return false; |
-} |
- |
-Filter* URLRequestJob::SetupFilter() const { |
- return NULL; |
-} |
- |
-bool URLRequestJob::IsRedirectResponse(GURL* location, |
- int* http_status_code) { |
- // For non-HTTP jobs, headers will be null. |
- HttpResponseHeaders* headers = request_->response_headers(); |
- if (!headers) |
- return false; |
- |
- std::string value; |
- if (!headers->IsRedirect(&value)) |
- return false; |
- |
- *location = request_->url().Resolve(value); |
- *http_status_code = headers->response_code(); |
- return true; |
-} |
- |
-bool URLRequestJob::CopyFragmentOnRedirect(const GURL& location) const { |
- return true; |
-} |
- |
-bool URLRequestJob::IsSafeRedirect(const GURL& location) { |
- return true; |
-} |
- |
-bool URLRequestJob::NeedsAuth() { |
- return false; |
-} |
- |
-void URLRequestJob::GetAuthChallengeInfo( |
- scoped_refptr<AuthChallengeInfo>* auth_info) { |
- // This will only be called if NeedsAuth() returns true, in which |
- // case the derived class should implement this! |
- NOTREACHED(); |
-} |
- |
-void URLRequestJob::SetAuth(const AuthCredentials& credentials) { |
- // This will only be called if NeedsAuth() returns true, in which |
- // case the derived class should implement this! |
- NOTREACHED(); |
-} |
- |
-void URLRequestJob::CancelAuth() { |
- // This will only be called if NeedsAuth() returns true, in which |
- // case the derived class should implement this! |
- NOTREACHED(); |
-} |
- |
-void URLRequestJob::ContinueWithCertificate( |
- X509Certificate* client_cert) { |
- // The derived class should implement this! |
- NOTREACHED(); |
-} |
- |
-void URLRequestJob::ContinueDespiteLastError() { |
- // Implementations should know how to recover from errors they generate. |
- // If this code was reached, we are trying to recover from an error that |
- // we don't know how to recover from. |
- NOTREACHED(); |
-} |
- |
-void URLRequestJob::FollowDeferredRedirect() { |
- DCHECK_NE(-1, deferred_redirect_info_.status_code); |
- |
- // 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. |
- |
- RedirectInfo redirect_info = deferred_redirect_info_; |
- deferred_redirect_info_ = RedirectInfo(); |
- FollowRedirect(redirect_info); |
-} |
- |
-void URLRequestJob::ResumeNetworkStart() { |
- // This should only be called for HTTP Jobs, and implemented in the derived |
- // class. |
- NOTREACHED(); |
-} |
- |
-bool URLRequestJob::GetMimeType(std::string* mime_type) const { |
- return false; |
-} |
- |
-int URLRequestJob::GetResponseCode() const { |
- return -1; |
-} |
- |
-HostPortPair URLRequestJob::GetSocketAddress() const { |
- return HostPortPair(); |
-} |
- |
-void URLRequestJob::OnSuspend() { |
- Kill(); |
-} |
- |
-void URLRequestJob::NotifyURLRequestDestroyed() { |
-} |
- |
-// static |
-GURL URLRequestJob::ComputeReferrerForRedirect( |
- URLRequest::ReferrerPolicy policy, |
- const std::string& referrer, |
- const GURL& redirect_destination) { |
- GURL original_referrer(referrer); |
- bool secure_referrer_but_insecure_destination = |
- original_referrer.SchemeIsSecure() && |
- !redirect_destination.SchemeIsSecure(); |
- bool same_origin = |
- original_referrer.GetOrigin() == redirect_destination.GetOrigin(); |
- switch (policy) { |
- case URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE: |
- return secure_referrer_but_insecure_destination ? GURL() |
- : original_referrer; |
- |
- case URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN: |
- if (same_origin) { |
- return original_referrer; |
- } else if (secure_referrer_but_insecure_destination) { |
- return GURL(); |
- } else { |
- return original_referrer.GetOrigin(); |
- } |
- |
- case URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN: |
- return same_origin ? original_referrer : original_referrer.GetOrigin(); |
- |
- case URLRequest::NEVER_CLEAR_REFERRER: |
- return original_referrer; |
- } |
- |
- NOTREACHED(); |
- return GURL(); |
-} |
- |
-URLRequestJob::~URLRequestJob() { |
- base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
- if (power_monitor) |
- power_monitor->RemoveObserver(this); |
-} |
- |
-void URLRequestJob::NotifyCertificateRequested( |
- SSLCertRequestInfo* cert_request_info) { |
- if (!request_) |
- return; // The request was destroyed, so there is no more work to do. |
- |
- request_->NotifyCertificateRequested(cert_request_info); |
-} |
- |
-void URLRequestJob::NotifySSLCertificateError(const SSLInfo& ssl_info, |
- bool fatal) { |
- if (!request_) |
- return; // The request was destroyed, so there is no more work to do. |
- |
- request_->NotifySSLCertificateError(ssl_info, fatal); |
-} |
- |
-bool URLRequestJob::CanGetCookies(const CookieList& cookie_list) const { |
- if (!request_) |
- return false; // The request was destroyed, so there is no more work to do. |
- |
- return request_->CanGetCookies(cookie_list); |
-} |
- |
-bool URLRequestJob::CanSetCookie(const std::string& cookie_line, |
- CookieOptions* options) const { |
- if (!request_) |
- return false; // The request was destroyed, so there is no more work to do. |
- |
- return request_->CanSetCookie(cookie_line, options); |
-} |
- |
-bool URLRequestJob::CanEnablePrivacyMode() const { |
- if (!request_) |
- return false; // The request was destroyed, so there is no more work to do. |
- |
- return request_->CanEnablePrivacyMode(); |
-} |
- |
-CookieStore* URLRequestJob::GetCookieStore() const { |
- DCHECK(request_); |
- |
- return request_->cookie_store(); |
-} |
- |
-void URLRequestJob::NotifyBeforeNetworkStart(bool* defer) { |
- if (!request_) |
- return; |
- |
- request_->NotifyBeforeNetworkStart(defer); |
-} |
- |
-void URLRequestJob::NotifyHeadersComplete() { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete")); |
- |
- if (!request_ || !request_->has_delegate()) |
- return; // The request was destroyed, so there is no more work to do. |
- |
- if (has_handled_response_) |
- return; |
- |
- DCHECK(!request_->status().is_io_pending()); |
- |
- // Initialize to the current time, and let the subclass optionally override |
- // the time stamps if it has that information. The default request_time is |
- // set by URLRequest before it calls our Start method. |
- request_->response_info_.response_time = base::Time::Now(); |
- GetResponseInfo(&request_->response_info_); |
- |
- // When notifying the delegate, the delegate can release the request |
- // (and thus release 'this'). After calling to the delgate, we must |
- // check the request pointer to see if it still exists, and return |
- // immediately if it has been destroyed. self_preservation ensures our |
- // survival until we can get out of this method. |
- scoped_refptr<URLRequestJob> self_preservation(this); |
- |
- if (request_) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile1( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 1")); |
- |
- request_->OnHeadersComplete(); |
- } |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile2( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 2")); |
- |
- GURL new_location; |
- int http_status_code; |
- if (IsRedirectResponse(&new_location, &http_status_code)) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile3( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 3")); |
- |
- // Redirect response bodies are not read. Notify the transaction |
- // so it does not treat being stopped as an error. |
- DoneReadingRedirectResponse(); |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile4( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 4")); |
- |
- RedirectInfo redirect_info = |
- ComputeRedirectInfo(new_location, http_status_code); |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile5( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 5")); |
- |
- bool defer_redirect = false; |
- request_->NotifyReceivedRedirect(redirect_info, &defer_redirect); |
- |
- // Ensure that the request wasn't detached or destroyed in |
- // NotifyReceivedRedirect |
- if (!request_ || !request_->has_delegate()) |
- return; |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile6( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 6")); |
- |
- // If we were not cancelled, then maybe follow the redirect. |
- if (request_->status().is_success()) { |
- if (defer_redirect) { |
- deferred_redirect_info_ = redirect_info; |
- } else { |
- FollowRedirect(redirect_info); |
- } |
- return; |
- } |
- } else if (NeedsAuth()) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile7( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 7")); |
- |
- scoped_refptr<AuthChallengeInfo> auth_info; |
- GetAuthChallengeInfo(&auth_info); |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile8( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 8")); |
- |
- // Need to check for a NULL auth_info because the server may have failed |
- // to send a challenge with the 401 response. |
- if (auth_info.get()) { |
- request_->NotifyAuthRequired(auth_info.get()); |
- // Wait for SetAuth or CancelAuth to be called. |
- return; |
- } |
- } |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile9( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 9")); |
- |
- has_handled_response_ = true; |
- if (request_->status().is_success()) |
- filter_.reset(SetupFilter()); |
- |
- if (!filter_.get()) { |
- std::string content_length; |
- request_->GetResponseHeaderByName("content-length", &content_length); |
- if (!content_length.empty()) |
- base::StringToInt64(content_length, &expected_content_size_); |
- } else { |
- request_->net_log().AddEvent( |
- NetLog::TYPE_URL_REQUEST_FILTERS_SET, |
- base::Bind(&FiltersSetCallback, base::Unretained(filter_.get()))); |
- } |
- |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile10( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyHeadersComplete 10")); |
- |
- request_->NotifyResponseStarted(); |
-} |
- |
-void URLRequestJob::NotifyReadComplete(int bytes_read) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::NotifyReadComplete")); |
- |
- if (!request_ || !request_->has_delegate()) |
- return; // The request was destroyed, so there is no more work to do. |
- |
- // TODO(darin): Bug 1004233. Re-enable this test once all of the chrome |
- // unit_tests have been fixed to not trip this. |
-#if 0 |
- DCHECK(!request_->status().is_io_pending()); |
-#endif |
- // The headers should be complete before reads complete |
- DCHECK(has_handled_response_); |
- |
- OnRawReadComplete(bytes_read); |
- |
- // Don't notify if we had an error. |
- if (!request_->status().is_success()) |
- return; |
- |
- // When notifying the delegate, the delegate can release the request |
- // (and thus release 'this'). After calling to the delegate, we must |
- // check the request pointer to see if it still exists, and return |
- // immediately if it has been destroyed. self_preservation ensures our |
- // survival until we can get out of this method. |
- scoped_refptr<URLRequestJob> self_preservation(this); |
- |
- if (filter_.get()) { |
- // Tell the filter that it has more data |
- FilteredDataRead(bytes_read); |
- |
- // Filter the data. |
- int filter_bytes_read = 0; |
- if (ReadFilteredData(&filter_bytes_read)) { |
- if (!filter_bytes_read) |
- DoneReading(); |
- request_->NotifyReadCompleted(filter_bytes_read); |
- } |
- } else { |
- request_->NotifyReadCompleted(bytes_read); |
- } |
- DVLOG(1) << __FUNCTION__ << "() " |
- << "\"" << (request_ ? request_->url().spec() : "???") << "\"" |
- << " pre bytes read = " << bytes_read |
- << " pre total = " << prefilter_bytes_read_ |
- << " post total = " << postfilter_bytes_read_; |
-} |
- |
-void URLRequestJob::NotifyStartError(const URLRequestStatus &status) { |
- DCHECK(!has_handled_response_); |
- has_handled_response_ = true; |
- if (request_) { |
- // There may be relevant information in the response info even in the |
- // error case. |
- GetResponseInfo(&request_->response_info_); |
- |
- request_->set_status(status); |
- request_->NotifyResponseStarted(); |
- // We may have been deleted. |
- } |
-} |
- |
-void URLRequestJob::NotifyDone(const URLRequestStatus &status) { |
- DCHECK(!done_) << "Job sending done notification twice"; |
- if (done_) |
- return; |
- done_ = true; |
- |
- // Unless there was an error, we should have at least tried to handle |
- // the response before getting here. |
- DCHECK(has_handled_response_ || !status.is_success()); |
- |
- // As with NotifyReadComplete, we need to take care to notice if we were |
- // destroyed during a delegate callback. |
- if (request_) { |
- request_->set_is_pending(false); |
- // With async IO, it's quite possible to have a few outstanding |
- // requests. We could receive a request to Cancel, followed shortly |
- // by a successful IO. For tracking the status(), once there is |
- // an error, we do not change the status back to success. To |
- // enforce this, only set the status if the job is so far |
- // successful. |
- if (request_->status().is_success()) { |
- if (status.status() == URLRequestStatus::FAILED) { |
- request_->net_log().AddEventWithNetErrorCode(NetLog::TYPE_FAILED, |
- status.error()); |
- } |
- request_->set_status(status); |
- } |
- } |
- |
- // Complete this notification later. This prevents us from re-entering the |
- // delegate if we're done because of a synchronous call. |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&URLRequestJob::CompleteNotifyDone, |
- weak_factory_.GetWeakPtr())); |
-} |
- |
-void URLRequestJob::CompleteNotifyDone() { |
- // Check if we should notify the delegate that we're done because of an error. |
- if (request_ && |
- !request_->status().is_success() && |
- request_->has_delegate()) { |
- // We report the error differently depending on whether we've called |
- // OnResponseStarted yet. |
- if (has_handled_response_) { |
- // We signal the error by calling OnReadComplete with a bytes_read of -1. |
- request_->NotifyReadCompleted(-1); |
- } else { |
- has_handled_response_ = true; |
- request_->NotifyResponseStarted(); |
- } |
- } |
-} |
- |
-void URLRequestJob::NotifyCanceled() { |
- if (!done_) { |
- NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); |
- } |
-} |
- |
-void URLRequestJob::NotifyRestartRequired() { |
- DCHECK(!has_handled_response_); |
- if (GetStatus().status() != URLRequestStatus::CANCELED) |
- request_->Restart(); |
-} |
- |
-void URLRequestJob::OnCallToDelegate() { |
- request_->OnCallToDelegate(); |
-} |
- |
-void URLRequestJob::OnCallToDelegateComplete() { |
- request_->OnCallToDelegateComplete(); |
-} |
- |
-bool URLRequestJob::ReadRawData(IOBuffer* buf, int buf_size, |
- int *bytes_read) { |
- DCHECK(bytes_read); |
- *bytes_read = 0; |
- return true; |
-} |
- |
-void URLRequestJob::DoneReading() { |
- // Do nothing. |
-} |
- |
-void URLRequestJob::DoneReadingRedirectResponse() { |
-} |
- |
-void URLRequestJob::FilteredDataRead(int bytes_read) { |
- DCHECK(filter_); |
- filter_->FlushStreamBuffer(bytes_read); |
-} |
- |
-bool URLRequestJob::ReadFilteredData(int* bytes_read) { |
- DCHECK(filter_); |
- DCHECK(filtered_read_buffer_.get()); |
- DCHECK_GT(filtered_read_buffer_len_, 0); |
- DCHECK_LT(filtered_read_buffer_len_, 1000000); // Sanity check. |
- DCHECK(!raw_read_buffer_.get()); |
- |
- *bytes_read = 0; |
- bool rv = false; |
- |
- for (;;) { |
- if (is_done()) |
- return true; |
- |
- if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) { |
- // We don't have any raw data to work with, so read from the transaction. |
- int filtered_data_read; |
- if (ReadRawDataForFilter(&filtered_data_read)) { |
- if (filtered_data_read > 0) { |
- // Give data to filter. |
- filter_->FlushStreamBuffer(filtered_data_read); |
- } else { |
- return true; // EOF. |
- } |
- } else { |
- return false; // IO Pending (or error). |
- } |
- } |
- |
- if ((filter_->stream_data_len() || filter_needs_more_output_space_) && |
- !is_done()) { |
- // Get filtered data. |
- int filtered_data_len = filtered_read_buffer_len_; |
- int output_buffer_size = filtered_data_len; |
- Filter::FilterStatus status = |
- filter_->ReadData(filtered_read_buffer_->data(), &filtered_data_len); |
- |
- if (filter_needs_more_output_space_ && !filtered_data_len) { |
- // filter_needs_more_output_space_ was mistaken... there are no more |
- // bytes and we should have at least tried to fill up the filter's input |
- // buffer. Correct the state, and try again. |
- filter_needs_more_output_space_ = false; |
- continue; |
- } |
- filter_needs_more_output_space_ = |
- (filtered_data_len == output_buffer_size); |
- |
- switch (status) { |
- case Filter::FILTER_DONE: { |
- filter_needs_more_output_space_ = false; |
- *bytes_read = filtered_data_len; |
- postfilter_bytes_read_ += filtered_data_len; |
- rv = true; |
- break; |
- } |
- case Filter::FILTER_NEED_MORE_DATA: { |
- // We have finished filtering all data currently in the buffer. |
- // There might be some space left in the output buffer. One can |
- // consider reading more data from the stream to feed the filter |
- // and filling up the output buffer. This leads to more complicated |
- // buffer management and data notification mechanisms. |
- // We can revisit this issue if there is a real perf need. |
- if (filtered_data_len > 0) { |
- *bytes_read = filtered_data_len; |
- postfilter_bytes_read_ += filtered_data_len; |
- rv = true; |
- } else { |
- // Read again since we haven't received enough data yet (e.g., we |
- // may not have a complete gzip header yet). |
- continue; |
- } |
- break; |
- } |
- case Filter::FILTER_OK: { |
- *bytes_read = filtered_data_len; |
- postfilter_bytes_read_ += filtered_data_len; |
- rv = true; |
- break; |
- } |
- case Filter::FILTER_ERROR: { |
- DVLOG(1) << __FUNCTION__ << "() " |
- << "\"" << (request_ ? request_->url().spec() : "???") |
- << "\"" << " Filter Error"; |
- filter_needs_more_output_space_ = false; |
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, |
- ERR_CONTENT_DECODING_FAILED)); |
- rv = false; |
- break; |
- } |
- default: { |
- NOTREACHED(); |
- filter_needs_more_output_space_ = false; |
- rv = false; |
- break; |
- } |
- } |
- |
- // If logging all bytes is enabled, log the filtered bytes read. |
- if (rv && request() && request()->net_log().IsLoggingBytes() && |
- filtered_data_len > 0) { |
- request()->net_log().AddByteTransferEvent( |
- NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ, |
- filtered_data_len, filtered_read_buffer_->data()); |
- } |
- } else { |
- // we are done, or there is no data left. |
- rv = true; |
- } |
- break; |
- } |
- |
- if (rv) { |
- // When we successfully finished a read, we no longer need to save the |
- // caller's buffers. Release our reference. |
- filtered_read_buffer_ = NULL; |
- filtered_read_buffer_len_ = 0; |
- } |
- return rv; |
-} |
- |
-void URLRequestJob::DestroyFilters() { |
- filter_.reset(); |
-} |
- |
-const URLRequestStatus URLRequestJob::GetStatus() { |
- if (request_) |
- return request_->status(); |
- // If the request is gone, we must be cancelled. |
- return URLRequestStatus(URLRequestStatus::CANCELED, |
- ERR_ABORTED); |
-} |
- |
-void URLRequestJob::SetStatus(const URLRequestStatus &status) { |
- if (request_) |
- request_->set_status(status); |
-} |
- |
-void URLRequestJob::SetProxyServer(const HostPortPair& proxy_server) { |
- request_->proxy_server_ = proxy_server; |
-} |
- |
-bool URLRequestJob::ReadRawDataForFilter(int* bytes_read) { |
- bool rv = false; |
- |
- DCHECK(bytes_read); |
- DCHECK(filter_.get()); |
- |
- *bytes_read = 0; |
- |
- // Get more pre-filtered data if needed. |
- // TODO(mbelshe): is it possible that the filter needs *MORE* data |
- // when there is some data already in the buffer? |
- if (!filter_->stream_data_len() && !is_done()) { |
- IOBuffer* stream_buffer = filter_->stream_buffer(); |
- int stream_buffer_size = filter_->stream_buffer_size(); |
- rv = ReadRawDataHelper(stream_buffer, stream_buffer_size, bytes_read); |
- } |
- return rv; |
-} |
- |
-bool URLRequestJob::ReadRawDataHelper(IOBuffer* buf, int buf_size, |
- int* bytes_read) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::ReadRawDataHelper")); |
- |
- DCHECK(!request_->status().is_io_pending()); |
- DCHECK(raw_read_buffer_.get() == NULL); |
- |
- // Keep a pointer to the read buffer, so we have access to it in the |
- // OnRawReadComplete() callback in the event that the read completes |
- // asynchronously. |
- raw_read_buffer_ = buf; |
- bool rv = ReadRawData(buf, buf_size, bytes_read); |
- |
- if (!request_->status().is_io_pending()) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile1( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::ReadRawDataHelper1")); |
- |
- // If the read completes synchronously, either success or failure, |
- // invoke the OnRawReadComplete callback so we can account for the |
- // completed read. |
- OnRawReadComplete(*bytes_read); |
- } |
- return rv; |
-} |
- |
-void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) { |
- int rv = request_->Redirect(redirect_info); |
- if (rv != OK) |
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); |
-} |
- |
-void URLRequestJob::OnRawReadComplete(int bytes_read) { |
- DCHECK(raw_read_buffer_.get()); |
- // If |filter_| is non-NULL, bytes will be logged after it is applied instead. |
- if (!filter_.get() && request() && request()->net_log().IsLoggingBytes() && |
- bytes_read > 0) { |
- request()->net_log().AddByteTransferEvent( |
- NetLog::TYPE_URL_REQUEST_JOB_BYTES_READ, |
- bytes_read, raw_read_buffer_->data()); |
- } |
- |
- if (bytes_read > 0) { |
- RecordBytesRead(bytes_read); |
- } |
- raw_read_buffer_ = NULL; |
-} |
- |
-void URLRequestJob::RecordBytesRead(int bytes_read) { |
- filter_input_byte_count_ += bytes_read; |
- prefilter_bytes_read_ += bytes_read; |
- if (!filter_.get()) |
- postfilter_bytes_read_ += bytes_read; |
- DVLOG(2) << __FUNCTION__ << "() " |
- << "\"" << (request_ ? request_->url().spec() : "???") << "\"" |
- << " pre bytes read = " << bytes_read |
- << " pre total = " << prefilter_bytes_read_ |
- << " post total = " << postfilter_bytes_read_; |
- UpdatePacketReadTimes(); // Facilitate stats recording if it is active. |
- if (network_delegate_) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 URLRequestJob::RecordBytesRead NotifyRawBytesRead")); |
- |
- network_delegate_->NotifyRawBytesRead(*request_, bytes_read); |
- } |
-} |
- |
-bool URLRequestJob::FilterHasData() { |
- return filter_.get() && filter_->stream_data_len(); |
-} |
- |
-void URLRequestJob::UpdatePacketReadTimes() { |
-} |
- |
-RedirectInfo URLRequestJob::ComputeRedirectInfo(const GURL& location, |
- int http_status_code) { |
- const GURL& url = request_->url(); |
- |
- RedirectInfo redirect_info; |
- |
- redirect_info.status_code = http_status_code; |
- |
- // The request method may change, depending on the status code. |
- redirect_info.new_method = |
- ComputeMethodForRedirect(request_->method(), http_status_code); |
- |
- // 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() && !location.has_ref() && |
- CopyFragmentOnRedirect(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); |
- redirect_info.new_url = location.ReplaceComponents(replacements); |
- } else { |
- redirect_info.new_url = location; |
- } |
- |
- // Update the first-party URL if appropriate. |
- if (request_->first_party_url_policy() == |
- URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT) { |
- redirect_info.new_first_party_for_cookies = redirect_info.new_url; |
- } else { |
- redirect_info.new_first_party_for_cookies = |
- request_->first_party_for_cookies(); |
- } |
- |
- // Alter the referrer if redirecting cross-origin (especially HTTP->HTTPS). |
- redirect_info.new_referrer = |
- ComputeReferrerForRedirect(request_->referrer_policy(), |
- request_->referrer(), |
- redirect_info.new_url).spec(); |
- |
- return redirect_info; |
-} |
- |
-} // namespace net |