| 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
|
|
|