Index: net/proxy/proxy_script_fetcher_impl.cc |
diff --git a/net/proxy/proxy_script_fetcher_impl.cc b/net/proxy/proxy_script_fetcher_impl.cc |
deleted file mode 100644 |
index 4e57121f281a0c0629c6d927bd120b2e14209198..0000000000000000000000000000000000000000 |
--- a/net/proxy/proxy_script_fetcher_impl.cc |
+++ /dev/null |
@@ -1,331 +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/proxy/proxy_script_fetcher_impl.h" |
- |
-#include "base/compiler_specific.h" |
-#include "base/logging.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/profiler/scoped_tracker.h" |
-#include "base/strings/string_util.h" |
-#include "net/base/data_url.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/load_flags.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/net_string_util.h" |
-#include "net/base/request_priority.h" |
-#include "net/cert/cert_status_flags.h" |
-#include "net/http/http_response_headers.h" |
-#include "net/url_request/url_request_context.h" |
- |
-// TODO(eroman): |
-// - Support auth-prompts (http://crbug.com/77366) |
- |
-namespace net { |
- |
-namespace { |
- |
-// The maximum size (in bytes) allowed for a PAC script. Responses exceeding |
-// this will fail with ERR_FILE_TOO_BIG. |
-const int kDefaultMaxResponseBytes = 1048576; // 1 megabyte |
- |
-// The maximum duration (in milliseconds) allowed for fetching the PAC script. |
-// Responses exceeding this will fail with ERR_TIMED_OUT. |
-const int kDefaultMaxDurationMs = 300000; // 5 minutes |
- |
-// Returns true if |mime_type| is one of the known PAC mime type. |
-bool IsPacMimeType(const std::string& mime_type) { |
- static const char * const kSupportedPacMimeTypes[] = { |
- "application/x-ns-proxy-autoconfig", |
- "application/x-javascript-config", |
- }; |
- for (size_t i = 0; i < arraysize(kSupportedPacMimeTypes); ++i) { |
- if (LowerCaseEqualsASCII(mime_type, kSupportedPacMimeTypes[i])) |
- return true; |
- } |
- return false; |
-} |
- |
-// Converts |bytes| (which is encoded by |charset|) to UTF16, saving the resul |
-// to |*utf16|. |
-// If |charset| is empty, then we don't know what it was and guess. |
-void ConvertResponseToUTF16(const std::string& charset, |
- const std::string& bytes, |
- base::string16* utf16) { |
- const char* codepage; |
- |
- if (charset.empty()) { |
- // Assume ISO-8859-1 if no charset was specified. |
- codepage = kCharsetLatin1; |
- } else { |
- // Otherwise trust the charset that was provided. |
- codepage = charset.c_str(); |
- } |
- |
- // Be generous in the conversion -- if any characters lie outside of |charset| |
- // (i.e. invalid), then substitute them with U+FFFD rather than failing. |
- ConvertToUTF16WithSubstitutions(bytes, codepage, utf16); |
-} |
- |
-} // namespace |
- |
-ProxyScriptFetcherImpl::ProxyScriptFetcherImpl( |
- URLRequestContext* url_request_context) |
- : url_request_context_(url_request_context), |
- buf_(new IOBuffer(kBufSize)), |
- next_id_(0), |
- cur_request_id_(0), |
- result_code_(OK), |
- result_text_(NULL), |
- max_response_bytes_(kDefaultMaxResponseBytes), |
- max_duration_(base::TimeDelta::FromMilliseconds(kDefaultMaxDurationMs)), |
- weak_factory_(this) { |
- DCHECK(url_request_context); |
-} |
- |
-ProxyScriptFetcherImpl::~ProxyScriptFetcherImpl() { |
- // The URLRequest's destructor will cancel the outstanding request, and |
- // ensure that the delegate (this) is not called again. |
-} |
- |
-base::TimeDelta ProxyScriptFetcherImpl::SetTimeoutConstraint( |
- base::TimeDelta timeout) { |
- base::TimeDelta prev = max_duration_; |
- max_duration_ = timeout; |
- return prev; |
-} |
- |
-size_t ProxyScriptFetcherImpl::SetSizeConstraint(size_t size_bytes) { |
- size_t prev = max_response_bytes_; |
- max_response_bytes_ = size_bytes; |
- return prev; |
-} |
- |
-void ProxyScriptFetcherImpl::OnResponseCompleted(URLRequest* request) { |
- DCHECK_EQ(request, cur_request_.get()); |
- |
- // Use |result_code_| as the request's error if we have already set it to |
- // something specific. |
- if (result_code_ == OK && !request->status().is_success()) |
- result_code_ = request->status().error(); |
- |
- FetchCompleted(); |
-} |
- |
-int ProxyScriptFetcherImpl::Fetch( |
- const GURL& url, base::string16* text, const CompletionCallback& callback) { |
- // It is invalid to call Fetch() while a request is already in progress. |
- DCHECK(!cur_request_.get()); |
- DCHECK(!callback.is_null()); |
- DCHECK(text); |
- |
- // Handle base-64 encoded data-urls that contain custom PAC scripts. |
- if (url.SchemeIs("data")) { |
- std::string mime_type; |
- std::string charset; |
- std::string data; |
- if (!DataURL::Parse(url, &mime_type, &charset, &data)) |
- return ERR_FAILED; |
- |
- ConvertResponseToUTF16(charset, data, text); |
- return OK; |
- } |
- |
- cur_request_ = |
- url_request_context_->CreateRequest(url, DEFAULT_PRIORITY, this, NULL); |
- cur_request_->set_method("GET"); |
- |
- // Make sure that the PAC script is downloaded using a direct connection, |
- // to avoid circular dependencies (fetching is a part of proxy resolution). |
- // Also disable the use of the disk cache. The cache is disabled so that if |
- // the user switches networks we don't potentially use the cached response |
- // from old network when we should in fact be re-fetching on the new network. |
- // If the PAC script is hosted on an HTTPS server we bypass revocation |
- // checking in order to avoid a circular dependency when attempting to fetch |
- // the OCSP response or CRL. We could make the revocation check go direct but |
- // the proxy might be the only way to the outside world. |
- cur_request_->SetLoadFlags(LOAD_BYPASS_PROXY | LOAD_DISABLE_CACHE | |
- LOAD_DISABLE_CERT_REVOCATION_CHECKING); |
- |
- // Save the caller's info for notification on completion. |
- callback_ = callback; |
- result_text_ = text; |
- |
- bytes_read_so_far_.clear(); |
- |
- // Post a task to timeout this request if it takes too long. |
- cur_request_id_ = ++next_id_; |
- base::MessageLoop::current()->PostDelayedTask( |
- FROM_HERE, |
- base::Bind(&ProxyScriptFetcherImpl::OnTimeout, |
- weak_factory_.GetWeakPtr(), |
- cur_request_id_), |
- max_duration_); |
- |
- // Start the request. |
- cur_request_->Start(); |
- return ERR_IO_PENDING; |
-} |
- |
-void ProxyScriptFetcherImpl::Cancel() { |
- // ResetCurRequestState will free the URLRequest, which will cause |
- // cancellation. |
- ResetCurRequestState(); |
-} |
- |
-URLRequestContext* ProxyScriptFetcherImpl::GetRequestContext() const { |
- return url_request_context_; |
-} |
- |
-void ProxyScriptFetcherImpl::OnAuthRequired(URLRequest* request, |
- AuthChallengeInfo* auth_info) { |
- DCHECK_EQ(request, cur_request_.get()); |
- // TODO(eroman): http://crbug.com/77366 |
- LOG(WARNING) << "Auth required to fetch PAC script, aborting."; |
- result_code_ = ERR_NOT_IMPLEMENTED; |
- request->CancelAuth(); |
-} |
- |
-void ProxyScriptFetcherImpl::OnSSLCertificateError(URLRequest* request, |
- const SSLInfo& ssl_info, |
- bool fatal) { |
- DCHECK_EQ(request, cur_request_.get()); |
- // Revocation check failures are not fatal. |
- if (IsCertStatusMinorError(ssl_info.cert_status)) { |
- request->ContinueDespiteLastError(); |
- return; |
- } |
- LOG(WARNING) << "SSL certificate error when fetching PAC script, aborting."; |
- // Certificate errors are in same space as net errors. |
- result_code_ = MapCertStatusToNetError(ssl_info.cert_status); |
- request->Cancel(); |
-} |
- |
-void ProxyScriptFetcherImpl::OnResponseStarted(URLRequest* request) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 ProxyScriptFetcherImpl::OnResponseStarted")); |
- |
- DCHECK_EQ(request, cur_request_.get()); |
- |
- if (!request->status().is_success()) { |
- OnResponseCompleted(request); |
- return; |
- } |
- |
- // Require HTTP responses to have a success status code. |
- if (request->url().SchemeIsHTTPOrHTTPS()) { |
- // NOTE about status codes: We are like Firefox 3 in this respect. |
- // {IE 7, Safari 3, Opera 9.5} do not care about the status code. |
- if (request->GetResponseCode() != 200) { |
- VLOG(1) << "Fetched PAC script had (bad) status line: " |
- << request->response_headers()->GetStatusLine(); |
- result_code_ = ERR_PAC_STATUS_NOT_OK; |
- request->Cancel(); |
- return; |
- } |
- |
- // NOTE about mime types: We do not enforce mime types on PAC files. |
- // This is for compatibility with {IE 7, Firefox 3, Opera 9.5}. We will |
- // however log mismatches to help with debugging. |
- std::string mime_type; |
- cur_request_->GetMimeType(&mime_type); |
- if (!IsPacMimeType(mime_type)) { |
- VLOG(1) << "Fetched PAC script does not have a proper mime type: " |
- << mime_type; |
- } |
- } |
- |
- ReadBody(request); |
-} |
- |
-void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request, |
- int num_bytes) { |
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed. |
- tracked_objects::ScopedTracker tracking_profile( |
- FROM_HERE_WITH_EXPLICIT_FUNCTION( |
- "423948 ProxyScriptFetcherImpl::OnReadCompleted")); |
- |
- DCHECK_EQ(request, cur_request_.get()); |
- if (ConsumeBytesRead(request, num_bytes)) { |
- // Keep reading. |
- ReadBody(request); |
- } |
-} |
- |
-void ProxyScriptFetcherImpl::ReadBody(URLRequest* request) { |
- // Read as many bytes as are available synchronously. |
- while (true) { |
- int num_bytes; |
- if (!request->Read(buf_.get(), kBufSize, &num_bytes)) { |
- // Check whether the read failed synchronously. |
- if (!request->status().is_io_pending()) |
- OnResponseCompleted(request); |
- return; |
- } |
- if (!ConsumeBytesRead(request, num_bytes)) |
- return; |
- } |
-} |
- |
-bool ProxyScriptFetcherImpl::ConsumeBytesRead(URLRequest* request, |
- int num_bytes) { |
- if (num_bytes <= 0) { |
- // Error while reading, or EOF. |
- OnResponseCompleted(request); |
- return false; |
- } |
- |
- // Enforce maximum size bound. |
- if (num_bytes + bytes_read_so_far_.size() > |
- static_cast<size_t>(max_response_bytes_)) { |
- result_code_ = ERR_FILE_TOO_BIG; |
- request->Cancel(); |
- return false; |
- } |
- |
- bytes_read_so_far_.append(buf_->data(), num_bytes); |
- return true; |
-} |
- |
-void ProxyScriptFetcherImpl::FetchCompleted() { |
- if (result_code_ == OK) { |
- // The caller expects the response to be encoded as UTF16. |
- std::string charset; |
- cur_request_->GetCharset(&charset); |
- ConvertResponseToUTF16(charset, bytes_read_so_far_, result_text_); |
- } else { |
- // On error, the caller expects empty string for bytes. |
- result_text_->clear(); |
- } |
- |
- int result_code = result_code_; |
- CompletionCallback callback = callback_; |
- |
- ResetCurRequestState(); |
- |
- callback.Run(result_code); |
-} |
- |
-void ProxyScriptFetcherImpl::ResetCurRequestState() { |
- cur_request_.reset(); |
- cur_request_id_ = 0; |
- callback_.Reset(); |
- result_code_ = OK; |
- result_text_ = NULL; |
-} |
- |
-void ProxyScriptFetcherImpl::OnTimeout(int id) { |
- // Timeout tasks may outlive the URLRequest they reference. Make sure it |
- // is still applicable. |
- if (cur_request_id_ != id) |
- return; |
- |
- DCHECK(cur_request_.get()); |
- result_code_ = ERR_TIMED_OUT; |
- cur_request_->Cancel(); |
-} |
- |
-} // namespace net |