| Index: net/proxy/proxy_service.cc
|
| diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
|
| index d6d410c205ef380d4f2209a2848fa08c6db8eae6..511264b9bee419b168ffba461a2719210a81bc21 100644
|
| --- a/net/proxy/proxy_service.cc
|
| +++ b/net/proxy/proxy_service.cc
|
| @@ -760,29 +760,31 @@ class ProxyService::ProxyScriptDeciderPoller {
|
| const ProxyService::PacPollPolicy*
|
| ProxyService::ProxyScriptDeciderPoller::poll_policy_ = NULL;
|
|
|
| // ProxyService::PacRequest ---------------------------------------------------
|
|
|
| class ProxyService::PacRequest
|
| : public base::RefCounted<ProxyService::PacRequest> {
|
| public:
|
| PacRequest(ProxyService* service,
|
| const GURL& url,
|
| + const std::string& method,
|
| int load_flags,
|
| ProxyDelegate* proxy_delegate,
|
| ProxyInfo* results,
|
| const CompletionCallback& user_callback,
|
| const BoundNetLog& net_log)
|
| : service_(service),
|
| user_callback_(user_callback),
|
| results_(results),
|
| url_(url),
|
| + method_(method),
|
| load_flags_(load_flags),
|
| proxy_delegate_(proxy_delegate),
|
| resolve_job_(NULL),
|
| config_id_(ProxyConfig::kInvalidConfigID),
|
| config_source_(PROXY_CONFIG_SOURCE_UNKNOWN),
|
| net_log_(net_log),
|
| creation_time_(TimeTicks::Now()) {
|
| DCHECK(!user_callback.is_null());
|
| }
|
|
|
| @@ -850,22 +852,22 @@ class ProxyService::PacRequest
|
|
|
| // This state is cleared when resolve_job_ is set to nullptr below.
|
| bool script_executed = is_started();
|
|
|
| // Clear |resolve_job_| so is_started() returns false while
|
| // DidFinishResolvingProxy() runs.
|
| resolve_job_ = nullptr;
|
|
|
| // Note that DidFinishResolvingProxy might modify |results_|.
|
| int rv = service_->DidFinishResolvingProxy(
|
| - url_, load_flags_, proxy_delegate_, results_, result_code, net_log_,
|
| - creation_time_, script_executed);
|
| + url_, method_, load_flags_, proxy_delegate_, results_, result_code,
|
| + net_log_, creation_time_, script_executed);
|
|
|
| // Make a note in the results which configuration was in use at the
|
| // time of the resolve.
|
| results_->config_id_ = config_id_;
|
| results_->config_source_ = config_source_;
|
| results_->did_use_pac_script_ = true;
|
| results_->proxy_resolve_start_time_ = creation_time_;
|
| results_->proxy_resolve_end_time_ = TimeTicks::Now();
|
|
|
| // Reset the state associated with in-progress-resolve.
|
| @@ -903,20 +905,21 @@ class ProxyService::PacRequest
|
|
|
| ProxyResolver* resolver() const { return service_->resolver_.get(); }
|
|
|
| // Note that we don't hold a reference to the ProxyService. Outstanding
|
| // requests are cancelled during ~ProxyService, so this is guaranteed
|
| // to be valid throughout our lifetime.
|
| ProxyService* service_;
|
| CompletionCallback user_callback_;
|
| ProxyInfo* results_;
|
| GURL url_;
|
| + std::string method_;
|
| int load_flags_;
|
| ProxyDelegate* proxy_delegate_;
|
| ProxyResolver::RequestHandle resolve_job_;
|
| ProxyConfig::ID config_id_; // The config id when the resolve was started.
|
| ProxyConfigSource config_source_; // The source of proxy settings.
|
| BoundNetLog net_log_;
|
| // Time when the request was created. Stored here rather than in |results_|
|
| // because the time in |results_| will be cleared.
|
| TimeTicks creation_time_;
|
| };
|
| @@ -1002,38 +1005,41 @@ scoped_ptr<ProxyService> ProxyService::CreateFixedFromPacResult(
|
| // ProxyResolver dependency we give it will never be used.
|
| scoped_ptr<ProxyConfigService> proxy_config_service(
|
| new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect()));
|
|
|
| return make_scoped_ptr(new ProxyService(
|
| std::move(proxy_config_service),
|
| make_scoped_ptr(new ProxyResolverFactoryForPacResult(pac_string)), NULL));
|
| }
|
|
|
| int ProxyService::ResolveProxy(const GURL& raw_url,
|
| + const std::string& method,
|
| int load_flags,
|
| ProxyInfo* result,
|
| const CompletionCallback& callback,
|
| PacRequest** pac_request,
|
| ProxyDelegate* proxy_delegate,
|
| const BoundNetLog& net_log) {
|
| DCHECK(!callback.is_null());
|
| - return ResolveProxyHelper(raw_url, load_flags, result, callback, pac_request,
|
| - proxy_delegate, net_log);
|
| + return ResolveProxyHelper(raw_url, method, load_flags, result, callback,
|
| + pac_request, proxy_delegate, net_log);
|
| }
|
|
|
| int ProxyService::ResolveProxyHelper(const GURL& raw_url,
|
| + const std::string& method,
|
| int load_flags,
|
| ProxyInfo* result,
|
| const CompletionCallback& callback,
|
| PacRequest** pac_request,
|
| ProxyDelegate* proxy_delegate,
|
| const BoundNetLog& net_log) {
|
| + DCHECK((proxy_delegate && !method.empty()) || !proxy_delegate);
|
| DCHECK(CalledOnValidThread());
|
|
|
| net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE);
|
|
|
| // Notify our polling-based dependencies that a resolve is taking place.
|
| // This way they can schedule their polls in response to network activity.
|
| config_service_->OnLazyPoll();
|
| if (script_poller_.get())
|
| script_poller_->OnLazyPoll();
|
|
|
| @@ -1042,30 +1048,31 @@ int ProxyService::ResolveProxyHelper(const GURL& raw_url,
|
|
|
| // Strip away any reference fragments and the username/password, as they
|
| // are not relevant to proxy resolution.
|
| GURL url = SimplifyUrlForRequest(raw_url);
|
|
|
| // Check if the request can be completed right away. (This is the case when
|
| // using a direct connection for example).
|
| int rv = TryToCompleteSynchronously(url, load_flags, proxy_delegate, result);
|
| if (rv != ERR_IO_PENDING) {
|
| rv = DidFinishResolvingProxy(
|
| - url, load_flags, proxy_delegate, result, rv, net_log,
|
| + url, method, load_flags, proxy_delegate, result, rv, net_log,
|
| callback.is_null() ? TimeTicks() : TimeTicks::Now(), false);
|
| return rv;
|
| }
|
|
|
| if (callback.is_null())
|
| return ERR_IO_PENDING;
|
|
|
| - scoped_refptr<PacRequest> req(new PacRequest(
|
| - this, url, load_flags, proxy_delegate, result, callback, net_log));
|
| + scoped_refptr<PacRequest> req(new PacRequest(this, url, method, load_flags,
|
| + proxy_delegate, result, callback,
|
| + net_log));
|
|
|
| if (current_state_ == STATE_READY) {
|
| // Start the resolve request.
|
| rv = req->Start();
|
| if (rv != ERR_IO_PENDING)
|
| return req->QueryDidComplete(rv);
|
| } else {
|
| req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC);
|
| }
|
|
|
| @@ -1074,26 +1081,27 @@ int ProxyService::ResolveProxyHelper(const GURL& raw_url,
|
| pending_requests_.insert(req);
|
|
|
| // Completion will be notified through |callback|, unless the caller cancels
|
| // the request using |pac_request|.
|
| if (pac_request)
|
| *pac_request = req.get();
|
| return rv; // ERR_IO_PENDING
|
| }
|
|
|
| bool ProxyService::TryResolveProxySynchronously(const GURL& raw_url,
|
| + const std::string& method,
|
| int load_flags,
|
| ProxyInfo* result,
|
| ProxyDelegate* proxy_delegate,
|
| const BoundNetLog& net_log) {
|
| CompletionCallback null_callback;
|
| - return ResolveProxyHelper(raw_url, load_flags, result, null_callback,
|
| + return ResolveProxyHelper(raw_url, method, load_flags, result, null_callback,
|
| nullptr /* pac_request*/, proxy_delegate,
|
| net_log) == OK;
|
| }
|
|
|
| int ProxyService::TryToCompleteSynchronously(const GURL& url,
|
| int load_flags,
|
| ProxyDelegate* proxy_delegate,
|
| ProxyInfo* result) {
|
| DCHECK_NE(STATE_NONE, current_state_);
|
|
|
| @@ -1239,41 +1247,42 @@ void ProxyService::OnInitProxyResolverComplete(int result) {
|
| // due to ProxyScriptDeciderPoller.
|
| config_.set_id(fetched_config_.id());
|
| config_.set_source(fetched_config_.source());
|
|
|
| // Resume any requests which we had to defer until the PAC script was
|
| // downloaded.
|
| SetReady();
|
| }
|
|
|
| int ProxyService::ReconsiderProxyAfterError(const GURL& url,
|
| + const std::string& method,
|
| int load_flags,
|
| int net_error,
|
| ProxyInfo* result,
|
| const CompletionCallback& callback,
|
| PacRequest** pac_request,
|
| ProxyDelegate* proxy_delegate,
|
| const BoundNetLog& net_log) {
|
| DCHECK(CalledOnValidThread());
|
|
|
| // Check to see if we have a new config since ResolveProxy was called. We
|
| // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a
|
| // direct connection failed and we never tried the current config.
|
|
|
| DCHECK(result);
|
| bool re_resolve = result->config_id_ != config_.id();
|
|
|
| if (re_resolve) {
|
| // If we have a new config or the config was never tried, we delete the
|
| // list of bad proxies and we try again.
|
| proxy_retry_info_.clear();
|
| - return ResolveProxy(url, load_flags, result, callback, pac_request,
|
| + return ResolveProxy(url, method, load_flags, result, callback, pac_request,
|
| proxy_delegate, net_log);
|
| }
|
|
|
| DCHECK(!result->is_empty());
|
| ProxyServer bad_proxy = result->proxy_server();
|
|
|
| // We don't have new proxy settings to try, try to fallback to the next proxy
|
| // in the list.
|
| bool did_fallback = result->Fallback(net_error, net_log);
|
|
|
| @@ -1340,20 +1349,21 @@ LoadState ProxyService::GetLoadState(const PacRequest* req) const {
|
| bool ProxyService::ContainsPendingRequest(PacRequest* req) {
|
| return pending_requests_.count(req) == 1;
|
| }
|
|
|
| void ProxyService::RemovePendingRequest(PacRequest* req) {
|
| DCHECK(ContainsPendingRequest(req));
|
| pending_requests_.erase(req);
|
| }
|
|
|
| int ProxyService::DidFinishResolvingProxy(const GURL& url,
|
| + const std::string& method,
|
| int load_flags,
|
| ProxyDelegate* proxy_delegate,
|
| ProxyInfo* result,
|
| int result_code,
|
| const BoundNetLog& net_log,
|
| base::TimeTicks start_time,
|
| bool script_executed) {
|
| // Don't track any metrics if start_time is 0, which will happen when the user
|
| // calls |TryResolveProxySynchronously|.
|
| if (!start_time.is_null()) {
|
| @@ -1369,26 +1379,27 @@ int ProxyService::DidFinishResolvingProxy(const GURL& url,
|
| base::TimeDelta::FromSeconds(20), 50);
|
| UMA_HISTOGRAM_SPARSE_SLOWLY("Net.ProxyService.GetProxyUsingScriptResult",
|
| std::abs(result_code));
|
| }
|
| UMA_HISTOGRAM_BOOLEAN("Net.ProxyService.ResolvedUsingScript",
|
| script_executed);
|
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.ProxyService.ResolveProxyTime", diff,
|
| base::TimeDelta::FromMicroseconds(100),
|
| base::TimeDelta::FromSeconds(20), 50);
|
| }
|
| +
|
| // Log the result of the proxy resolution.
|
| if (result_code == OK) {
|
| // Allow the proxy delegate to interpose on the resolution decision,
|
| // possibly modifying the ProxyInfo.
|
| if (proxy_delegate)
|
| - proxy_delegate->OnResolveProxy(url, load_flags, *this, result);
|
| + proxy_delegate->OnResolveProxy(url, method, load_flags, *this, result);
|
|
|
| net_log.AddEvent(NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
|
| base::Bind(&NetLogFinishedResolvingProxyCallback, result));
|
|
|
| // This check is done to only log the NetLog event when necessary, it's
|
| // not a performance optimization.
|
| if (!proxy_retry_info_.empty()) {
|
| result->DeprioritizeBadProxies(proxy_retry_info_);
|
| net_log.AddEvent(
|
| NetLog::TYPE_PROXY_SERVICE_DEPRIORITIZED_BAD_PROXIES,
|
| @@ -1406,21 +1417,21 @@ int ProxyService::DidFinishResolvingProxy(const GURL& url,
|
| // This implicit fall-back to direct matches Firefox 3.5 and
|
| // Internet Explorer 8. For more information, see:
|
| //
|
| // http://www.chromium.org/developers/design-documents/proxy-settings-fallback
|
| result->UseDirect();
|
| result_code = OK;
|
|
|
| // Allow the proxy delegate to interpose on the resolution decision,
|
| // possibly modifying the ProxyInfo.
|
| if (proxy_delegate)
|
| - proxy_delegate->OnResolveProxy(url, load_flags, *this, result);
|
| + proxy_delegate->OnResolveProxy(url, method, load_flags, *this, result);
|
| } else {
|
| result_code = ERR_MANDATORY_PROXY_CONFIGURATION_FAILED;
|
| }
|
| if (reset_config) {
|
| ResetProxyConfig(false);
|
| // If the ProxyResolver crashed, force it to be re-initialized for the
|
| // next request by resetting the proxy config. If there are other pending
|
| // requests, trigger the recreation immediately so those requests retry.
|
| if (pending_requests_.size() > 1)
|
| ApplyProxyConfigIfAvailable();
|
|
|