| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_service.h" | 5 #include "net/proxy/proxy_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "googleurl/src/gurl.h" | 13 #include "googleurl/src/gurl.h" |
| 14 #include "net/base/load_log.h" | 14 #include "net/base/net_log.h" |
| 15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 16 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
| 17 #include "net/proxy/init_proxy_resolver.h" | 17 #include "net/proxy/init_proxy_resolver.h" |
| 18 #include "net/proxy/proxy_config_service_fixed.h" | 18 #include "net/proxy/proxy_config_service_fixed.h" |
| 19 #include "net/proxy/proxy_script_fetcher.h" | 19 #include "net/proxy/proxy_script_fetcher.h" |
| 20 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
| 21 #include "net/proxy/proxy_config_service_win.h" | 21 #include "net/proxy/proxy_config_service_win.h" |
| 22 #include "net/proxy/proxy_resolver_winhttp.h" | 22 #include "net/proxy/proxy_resolver_winhttp.h" |
| 23 #elif defined(OS_MACOSX) | 23 #elif defined(OS_MACOSX) |
| 24 #include "net/proxy/proxy_config_service_mac.h" | 24 #include "net/proxy/proxy_config_service_mac.h" |
| 25 #include "net/proxy/proxy_resolver_mac.h" | 25 #include "net/proxy/proxy_resolver_mac.h" |
| 26 #elif defined(OS_LINUX) | 26 #elif defined(OS_LINUX) |
| 27 #include "net/proxy/proxy_config_service_linux.h" | 27 #include "net/proxy/proxy_config_service_linux.h" |
| 28 #endif | 28 #endif |
| 29 #include "net/proxy/proxy_resolver.h" | 29 #include "net/proxy/proxy_resolver.h" |
| 30 #include "net/proxy/proxy_resolver_js_bindings.h" | 30 #include "net/proxy/proxy_resolver_js_bindings.h" |
| 31 #include "net/proxy/proxy_resolver_v8.h" | 31 #include "net/proxy/proxy_resolver_v8.h" |
| 32 #include "net/proxy/single_threaded_proxy_resolver.h" | 32 #include "net/proxy/single_threaded_proxy_resolver.h" |
| 33 #include "net/url_request/url_request_context.h" | 33 #include "net/url_request/url_request_context.h" |
| 34 | 34 |
| 35 using base::TimeDelta; | 35 using base::TimeDelta; |
| 36 using base::TimeTicks; | 36 using base::TimeTicks; |
| 37 | 37 |
| 38 namespace net { | 38 namespace net { |
| 39 | 39 |
| 40 static const size_t kMaxNumLoadLogEntries = 100; | 40 static const size_t kMaxNumNetLogEntries = 100; |
| 41 | 41 |
| 42 // Config getter that fails every time. | 42 // Config getter that fails every time. |
| 43 class ProxyConfigServiceNull : public ProxyConfigService { | 43 class ProxyConfigServiceNull : public ProxyConfigService { |
| 44 public: | 44 public: |
| 45 // ProxyConfigService implementation: | 45 // ProxyConfigService implementation: |
| 46 virtual int GetProxyConfig(ProxyConfig* config) { | 46 virtual int GetProxyConfig(ProxyConfig* config) { |
| 47 return ERR_NOT_IMPLEMENTED; | 47 return ERR_NOT_IMPLEMENTED; |
| 48 } | 48 } |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 // Proxy resolver that fails every time. | 51 // Proxy resolver that fails every time. |
| 52 class ProxyResolverNull : public ProxyResolver { | 52 class ProxyResolverNull : public ProxyResolver { |
| 53 public: | 53 public: |
| 54 ProxyResolverNull() : ProxyResolver(false /*expects_pac_bytes*/) {} | 54 ProxyResolverNull() : ProxyResolver(false /*expects_pac_bytes*/) {} |
| 55 | 55 |
| 56 // ProxyResolver implementation: | 56 // ProxyResolver implementation: |
| 57 virtual int GetProxyForURL(const GURL& url, | 57 virtual int GetProxyForURL(const GURL& url, |
| 58 ProxyInfo* results, | 58 ProxyInfo* results, |
| 59 CompletionCallback* callback, | 59 CompletionCallback* callback, |
| 60 RequestHandle* request, | 60 RequestHandle* request, |
| 61 LoadLog* load_log) { | 61 const BoundNetLog& net_log) { |
| 62 return ERR_NOT_IMPLEMENTED; | 62 return ERR_NOT_IMPLEMENTED; |
| 63 } | 63 } |
| 64 | 64 |
| 65 virtual void CancelRequest(RequestHandle request) { | 65 virtual void CancelRequest(RequestHandle request) { |
| 66 NOTREACHED(); | 66 NOTREACHED(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 private: | 69 private: |
| 70 virtual int SetPacScript(const GURL& /*pac_url*/, | 70 virtual int SetPacScript(const GURL& /*pac_url*/, |
| 71 const std::string& /*pac_bytes*/, | 71 const std::string& /*pac_bytes*/, |
| 72 CompletionCallback* /*callback*/) { | 72 CompletionCallback* /*callback*/) { |
| 73 return ERR_NOT_IMPLEMENTED; | 73 return ERR_NOT_IMPLEMENTED; |
| 74 } | 74 } |
| 75 }; | 75 }; |
| 76 | 76 |
| 77 // ProxyService::PacRequest --------------------------------------------------- | 77 // ProxyService::PacRequest --------------------------------------------------- |
| 78 | 78 |
| 79 class ProxyService::PacRequest | 79 class ProxyService::PacRequest |
| 80 : public base::RefCounted<ProxyService::PacRequest> { | 80 : public base::RefCounted<ProxyService::PacRequest> { |
| 81 public: | 81 public: |
| 82 PacRequest(ProxyService* service, | 82 PacRequest(ProxyService* service, |
| 83 const GURL& url, | 83 const GURL& url, |
| 84 ProxyInfo* results, | 84 ProxyInfo* results, |
| 85 CompletionCallback* user_callback, | 85 CompletionCallback* user_callback, |
| 86 LoadLog* load_log) | 86 const BoundNetLog& net_log) |
| 87 : service_(service), | 87 : service_(service), |
| 88 user_callback_(user_callback), | 88 user_callback_(user_callback), |
| 89 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 89 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
| 90 this, &PacRequest::QueryComplete)), | 90 this, &PacRequest::QueryComplete)), |
| 91 results_(results), | 91 results_(results), |
| 92 url_(url), | 92 url_(url), |
| 93 resolve_job_(NULL), | 93 resolve_job_(NULL), |
| 94 config_id_(ProxyConfig::INVALID_ID), | 94 config_id_(ProxyConfig::INVALID_ID), |
| 95 load_log_(load_log) { | 95 net_log_(net_log) { |
| 96 DCHECK(user_callback); | 96 DCHECK(user_callback); |
| 97 } | 97 } |
| 98 | 98 |
| 99 // Starts the resolve proxy request. | 99 // Starts the resolve proxy request. |
| 100 int Start() { | 100 int Start() { |
| 101 DCHECK(!was_cancelled()); | 101 DCHECK(!was_cancelled()); |
| 102 DCHECK(!is_started()); | 102 DCHECK(!is_started()); |
| 103 | 103 |
| 104 config_id_ = service_->config_.id(); | 104 config_id_ = service_->config_.id(); |
| 105 | 105 |
| 106 return resolver()->GetProxyForURL( | 106 return resolver()->GetProxyForURL( |
| 107 url_, results_, &io_callback_, &resolve_job_, load_log_); | 107 url_, results_, &io_callback_, &resolve_job_, net_log_); |
| 108 } | 108 } |
| 109 | 109 |
| 110 bool is_started() const { | 110 bool is_started() const { |
| 111 // Note that !! casts to bool. (VS gives a warning otherwise). | 111 // Note that !! casts to bool. (VS gives a warning otherwise). |
| 112 return !!resolve_job_; | 112 return !!resolve_job_; |
| 113 } | 113 } |
| 114 | 114 |
| 115 void StartAndCompleteCheckingForSynchronous() { | 115 void StartAndCompleteCheckingForSynchronous() { |
| 116 int rv = service_->TryToCompleteSynchronously(url_, results_); | 116 int rv = service_->TryToCompleteSynchronously(url_, results_); |
| 117 if (rv == ERR_IO_PENDING) | 117 if (rv == ERR_IO_PENDING) |
| 118 rv = Start(); | 118 rv = Start(); |
| 119 if (rv != ERR_IO_PENDING) | 119 if (rv != ERR_IO_PENDING) |
| 120 QueryComplete(rv); | 120 QueryComplete(rv); |
| 121 } | 121 } |
| 122 | 122 |
| 123 void CancelResolveJob() { | 123 void CancelResolveJob() { |
| 124 DCHECK(is_started()); | 124 DCHECK(is_started()); |
| 125 // The request may already be running in the resolver. | 125 // The request may already be running in the resolver. |
| 126 resolver()->CancelRequest(resolve_job_); | 126 resolver()->CancelRequest(resolve_job_); |
| 127 resolve_job_ = NULL; | 127 resolve_job_ = NULL; |
| 128 DCHECK(!is_started()); | 128 DCHECK(!is_started()); |
| 129 } | 129 } |
| 130 | 130 |
| 131 void Cancel() { | 131 void Cancel() { |
| 132 LoadLog::AddEvent(load_log_, LoadLog::TYPE_CANCELLED); | 132 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
| 133 | 133 |
| 134 if (is_started()) | 134 if (is_started()) |
| 135 CancelResolveJob(); | 135 CancelResolveJob(); |
| 136 | 136 |
| 137 // Mark as cancelled, to prevent accessing this again later. | 137 // Mark as cancelled, to prevent accessing this again later. |
| 138 service_ = NULL; | 138 service_ = NULL; |
| 139 user_callback_ = NULL; | 139 user_callback_ = NULL; |
| 140 results_ = NULL; | 140 results_ = NULL; |
| 141 | 141 |
| 142 LoadLog::EndEvent(load_log_, LoadLog::TYPE_PROXY_SERVICE); | 142 net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE); |
| 143 } | 143 } |
| 144 | 144 |
| 145 // Returns true if Cancel() has been called. | 145 // Returns true if Cancel() has been called. |
| 146 bool was_cancelled() const { return user_callback_ == NULL; } | 146 bool was_cancelled() const { return user_callback_ == NULL; } |
| 147 | 147 |
| 148 // Helper to call after ProxyResolver completion (both synchronous and | 148 // Helper to call after ProxyResolver completion (both synchronous and |
| 149 // asynchronous). Fixes up the result that is to be returned to user. | 149 // asynchronous). Fixes up the result that is to be returned to user. |
| 150 int QueryDidComplete(int result_code) { | 150 int QueryDidComplete(int result_code) { |
| 151 DCHECK(!was_cancelled()); | 151 DCHECK(!was_cancelled()); |
| 152 | 152 |
| 153 // Make a note in the results which configuration was in use at the | 153 // Make a note in the results which configuration was in use at the |
| 154 // time of the resolve. | 154 // time of the resolve. |
| 155 results_->config_id_ = config_id_; | 155 results_->config_id_ = config_id_; |
| 156 | 156 |
| 157 // Reset the state associated with in-progress-resolve. | 157 // Reset the state associated with in-progress-resolve. |
| 158 resolve_job_ = NULL; | 158 resolve_job_ = NULL; |
| 159 config_id_ = ProxyConfig::INVALID_ID; | 159 config_id_ = ProxyConfig::INVALID_ID; |
| 160 | 160 |
| 161 return service_->DidFinishResolvingProxy(results_, result_code, load_log_); | 161 return service_->DidFinishResolvingProxy(results_, result_code, net_log_); |
| 162 } | 162 } |
| 163 | 163 |
| 164 LoadLog* load_log() const { return load_log_; } | 164 BoundNetLog* net_log() { return &net_log_; } |
| 165 | 165 |
| 166 private: | 166 private: |
| 167 friend class base::RefCounted<ProxyService::PacRequest>; | 167 friend class base::RefCounted<ProxyService::PacRequest>; |
| 168 | 168 |
| 169 ~PacRequest() {} | 169 ~PacRequest() {} |
| 170 | 170 |
| 171 // Callback for when the ProxyResolver request has completed. | 171 // Callback for when the ProxyResolver request has completed. |
| 172 void QueryComplete(int result_code) { | 172 void QueryComplete(int result_code) { |
| 173 result_code = QueryDidComplete(result_code); | 173 result_code = QueryDidComplete(result_code); |
| 174 | 174 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 185 // Note that we don't hold a reference to the ProxyService. Outstanding | 185 // Note that we don't hold a reference to the ProxyService. Outstanding |
| 186 // requests are cancelled during ~ProxyService, so this is guaranteed | 186 // requests are cancelled during ~ProxyService, so this is guaranteed |
| 187 // to be valid throughout our lifetime. | 187 // to be valid throughout our lifetime. |
| 188 ProxyService* service_; | 188 ProxyService* service_; |
| 189 CompletionCallback* user_callback_; | 189 CompletionCallback* user_callback_; |
| 190 CompletionCallbackImpl<PacRequest> io_callback_; | 190 CompletionCallbackImpl<PacRequest> io_callback_; |
| 191 ProxyInfo* results_; | 191 ProxyInfo* results_; |
| 192 GURL url_; | 192 GURL url_; |
| 193 ProxyResolver::RequestHandle resolve_job_; | 193 ProxyResolver::RequestHandle resolve_job_; |
| 194 ProxyConfig::ID config_id_; // The config id when the resolve was started. | 194 ProxyConfig::ID config_id_; // The config id when the resolve was started. |
| 195 scoped_refptr<LoadLog> load_log_; | 195 BoundNetLog net_log_; |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 // ProxyService --------------------------------------------------------------- | 198 // ProxyService --------------------------------------------------------------- |
| 199 | 199 |
| 200 ProxyService::ProxyService(ProxyConfigService* config_service, | 200 ProxyService::ProxyService(ProxyConfigService* config_service, |
| 201 ProxyResolver* resolver, | 201 ProxyResolver* resolver, |
| 202 NetworkChangeNotifier* network_change_notifier) | 202 NetworkChangeNotifier* network_change_notifier) |
| 203 : config_service_(config_service), | 203 : config_service_(config_service), |
| 204 resolver_(resolver), | 204 resolver_(resolver), |
| 205 next_config_id_(1), | 205 next_config_id_(1), |
| 206 should_use_proxy_resolver_(false), | 206 should_use_proxy_resolver_(false), |
| 207 ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_( | 207 ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_( |
| 208 this, &ProxyService::OnInitProxyResolverComplete)), | 208 this, &ProxyService::OnInitProxyResolverComplete)), |
| 209 init_proxy_resolver_log_(kMaxNumNetLogEntries), |
| 209 network_change_notifier_(network_change_notifier) { | 210 network_change_notifier_(network_change_notifier) { |
| 210 // Register to receive network change notifications. | 211 // Register to receive network change notifications. |
| 211 if (network_change_notifier_) | 212 if (network_change_notifier_) |
| 212 network_change_notifier_->AddObserver(this); | 213 network_change_notifier_->AddObserver(this); |
| 213 } | 214 } |
| 214 | 215 |
| 215 // static | 216 // static |
| 216 ProxyService* ProxyService::Create( | 217 ProxyService* ProxyService::Create( |
| 217 ProxyConfigService* proxy_config_service, | 218 ProxyConfigService* proxy_config_service, |
| 218 bool use_v8_resolver, | 219 bool use_v8_resolver, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // Use a configuration fetcher and proxy resolver which always fail. | 260 // Use a configuration fetcher and proxy resolver which always fail. |
| 260 return new ProxyService(new ProxyConfigServiceNull, | 261 return new ProxyService(new ProxyConfigServiceNull, |
| 261 new ProxyResolverNull, | 262 new ProxyResolverNull, |
| 262 NULL); | 263 NULL); |
| 263 } | 264 } |
| 264 | 265 |
| 265 int ProxyService::ResolveProxy(const GURL& raw_url, | 266 int ProxyService::ResolveProxy(const GURL& raw_url, |
| 266 ProxyInfo* result, | 267 ProxyInfo* result, |
| 267 CompletionCallback* callback, | 268 CompletionCallback* callback, |
| 268 PacRequest** pac_request, | 269 PacRequest** pac_request, |
| 269 LoadLog* load_log) { | 270 const BoundNetLog& net_log) { |
| 270 DCHECK(callback); | 271 DCHECK(callback); |
| 271 | 272 |
| 272 LoadLog::BeginEvent(load_log, LoadLog::TYPE_PROXY_SERVICE); | 273 net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE); |
| 273 | 274 |
| 274 // Strip away any reference fragments and the username/password, as they | 275 // Strip away any reference fragments and the username/password, as they |
| 275 // are not relevant to proxy resolution. | 276 // are not relevant to proxy resolution. |
| 276 GURL url = SimplifyUrlForRequest(raw_url); | 277 GURL url = SimplifyUrlForRequest(raw_url); |
| 277 | 278 |
| 278 // Check if the request can be completed right away. This is the case when | 279 // Check if the request can be completed right away. This is the case when |
| 279 // using a direct connection, or when the config is bad. | 280 // using a direct connection, or when the config is bad. |
| 280 UpdateConfigIfOld(load_log); | 281 UpdateConfigIfOld(net_log); |
| 281 int rv = TryToCompleteSynchronously(url, result); | 282 int rv = TryToCompleteSynchronously(url, result); |
| 282 if (rv != ERR_IO_PENDING) | 283 if (rv != ERR_IO_PENDING) |
| 283 return DidFinishResolvingProxy(result, rv, load_log); | 284 return DidFinishResolvingProxy(result, rv, net_log); |
| 284 | 285 |
| 285 scoped_refptr<PacRequest> req = | 286 scoped_refptr<PacRequest> req = |
| 286 new PacRequest(this, url, result, callback, load_log); | 287 new PacRequest(this, url, result, callback, net_log); |
| 287 | 288 |
| 288 bool resolver_is_ready = !IsInitializingProxyResolver(); | 289 bool resolver_is_ready = !IsInitializingProxyResolver(); |
| 289 | 290 |
| 290 if (resolver_is_ready) { | 291 if (resolver_is_ready) { |
| 291 // Start the resolve request. | 292 // Start the resolve request. |
| 292 rv = req->Start(); | 293 rv = req->Start(); |
| 293 if (rv != ERR_IO_PENDING) | 294 if (rv != ERR_IO_PENDING) |
| 294 return req->QueryDidComplete(rv); | 295 return req->QueryDidComplete(rv); |
| 295 } else { | 296 } else { |
| 296 LoadLog::BeginEvent(req->load_log(), | 297 req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); |
| 297 LoadLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); | |
| 298 } | 298 } |
| 299 | 299 |
| 300 DCHECK_EQ(ERR_IO_PENDING, rv); | 300 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 301 DCHECK(!ContainsPendingRequest(req)); | 301 DCHECK(!ContainsPendingRequest(req)); |
| 302 pending_requests_.push_back(req); | 302 pending_requests_.push_back(req); |
| 303 | 303 |
| 304 // Completion will be notifed through |callback|, unless the caller cancels | 304 // Completion will be notifed through |callback|, unless the caller cancels |
| 305 // the request using |pac_request|. | 305 // the request using |pac_request|. |
| 306 if (pac_request) | 306 if (pac_request) |
| 307 *pac_request = req.get(); | 307 *pac_request = req.get(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 328 // Unregister to receive network change notifications. | 328 // Unregister to receive network change notifications. |
| 329 if (network_change_notifier_) | 329 if (network_change_notifier_) |
| 330 network_change_notifier_->RemoveObserver(this); | 330 network_change_notifier_->RemoveObserver(this); |
| 331 | 331 |
| 332 // Cancel any inprogress requests. | 332 // Cancel any inprogress requests. |
| 333 for (PendingRequests::iterator it = pending_requests_.begin(); | 333 for (PendingRequests::iterator it = pending_requests_.begin(); |
| 334 it != pending_requests_.end(); | 334 it != pending_requests_.end(); |
| 335 ++it) { | 335 ++it) { |
| 336 (*it)->Cancel(); | 336 (*it)->Cancel(); |
| 337 } | 337 } |
| 338 |
| 339 // Make sure that InitProxyResolver gets destroyed BEFORE the |
| 340 // CapturingNetLog it is using is deleted. |
| 341 init_proxy_resolver_.reset(); |
| 338 } | 342 } |
| 339 | 343 |
| 340 void ProxyService::SuspendAllPendingRequests() { | 344 void ProxyService::SuspendAllPendingRequests() { |
| 341 for (PendingRequests::iterator it = pending_requests_.begin(); | 345 for (PendingRequests::iterator it = pending_requests_.begin(); |
| 342 it != pending_requests_.end(); | 346 it != pending_requests_.end(); |
| 343 ++it) { | 347 ++it) { |
| 344 PacRequest* req = it->get(); | 348 PacRequest* req = it->get(); |
| 345 if (req->is_started()) { | 349 if (req->is_started()) { |
| 346 req->CancelResolveJob(); | 350 req->CancelResolveJob(); |
| 347 | 351 |
| 348 LoadLog::BeginEvent(req->load_log(), | 352 req->net_log()->BeginEvent( |
| 349 LoadLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); | 353 NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); |
| 350 } | 354 } |
| 351 } | 355 } |
| 352 } | 356 } |
| 353 | 357 |
| 354 void ProxyService::ResumeAllPendingRequests() { | 358 void ProxyService::ResumeAllPendingRequests() { |
| 355 DCHECK(!IsInitializingProxyResolver()); | 359 DCHECK(!IsInitializingProxyResolver()); |
| 356 | 360 |
| 357 // Make a copy in case |this| is deleted during the synchronous completion | 361 // Make a copy in case |this| is deleted during the synchronous completion |
| 358 // of one of the requests. If |this| is deleted then all of the PacRequest | 362 // of one of the requests. If |this| is deleted then all of the PacRequest |
| 359 // instances will be Cancel()-ed. | 363 // instances will be Cancel()-ed. |
| 360 PendingRequests pending_copy = pending_requests_; | 364 PendingRequests pending_copy = pending_requests_; |
| 361 | 365 |
| 362 for (PendingRequests::iterator it = pending_copy.begin(); | 366 for (PendingRequests::iterator it = pending_copy.begin(); |
| 363 it != pending_copy.end(); | 367 it != pending_copy.end(); |
| 364 ++it) { | 368 ++it) { |
| 365 PacRequest* req = it->get(); | 369 PacRequest* req = it->get(); |
| 366 if (!req->is_started() && !req->was_cancelled()) { | 370 if (!req->is_started() && !req->was_cancelled()) { |
| 367 LoadLog::EndEvent(req->load_log(), | 371 req->net_log()->EndEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); |
| 368 LoadLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); | |
| 369 | 372 |
| 370 // Note that we re-check for synchronous completion, in case we are | 373 // Note that we re-check for synchronous completion, in case we are |
| 371 // no longer using a ProxyResolver (can happen if we fell-back to manual). | 374 // no longer using a ProxyResolver (can happen if we fell-back to manual). |
| 372 req->StartAndCompleteCheckingForSynchronous(); | 375 req->StartAndCompleteCheckingForSynchronous(); |
| 373 } | 376 } |
| 374 } | 377 } |
| 375 } | 378 } |
| 376 | 379 |
| 377 void ProxyService::OnInitProxyResolverComplete(int result) { | 380 void ProxyService::OnInitProxyResolverComplete(int result) { |
| 378 DCHECK(init_proxy_resolver_.get()); | 381 DCHECK(init_proxy_resolver_.get()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 389 | 392 |
| 390 // Resume any requests which we had to defer until the PAC script was | 393 // Resume any requests which we had to defer until the PAC script was |
| 391 // downloaded. | 394 // downloaded. |
| 392 ResumeAllPendingRequests(); | 395 ResumeAllPendingRequests(); |
| 393 } | 396 } |
| 394 | 397 |
| 395 int ProxyService::ReconsiderProxyAfterError(const GURL& url, | 398 int ProxyService::ReconsiderProxyAfterError(const GURL& url, |
| 396 ProxyInfo* result, | 399 ProxyInfo* result, |
| 397 CompletionCallback* callback, | 400 CompletionCallback* callback, |
| 398 PacRequest** pac_request, | 401 PacRequest** pac_request, |
| 399 LoadLog* load_log) { | 402 const BoundNetLog& net_log) { |
| 400 // Check to see if we have a new config since ResolveProxy was called. We | 403 // Check to see if we have a new config since ResolveProxy was called. We |
| 401 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a | 404 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a |
| 402 // direct connection failed and we never tried the current config. | 405 // direct connection failed and we never tried the current config. |
| 403 | 406 |
| 404 bool re_resolve = result->config_id_ != config_.id(); | 407 bool re_resolve = result->config_id_ != config_.id(); |
| 405 if (!re_resolve) { | 408 if (!re_resolve) { |
| 406 UpdateConfig(load_log); | 409 UpdateConfig(net_log); |
| 407 if (result->config_id_ != config_.id()) { | 410 if (result->config_id_ != config_.id()) { |
| 408 // A new configuration! | 411 // A new configuration! |
| 409 re_resolve = true; | 412 re_resolve = true; |
| 410 } | 413 } |
| 411 } | 414 } |
| 412 if (re_resolve) { | 415 if (re_resolve) { |
| 413 // If we have a new config or the config was never tried, we delete the | 416 // If we have a new config or the config was never tried, we delete the |
| 414 // list of bad proxies and we try again. | 417 // list of bad proxies and we try again. |
| 415 proxy_retry_info_.clear(); | 418 proxy_retry_info_.clear(); |
| 416 return ResolveProxy(url, result, callback, pac_request, load_log); | 419 return ResolveProxy(url, result, callback, pac_request, net_log); |
| 417 } | 420 } |
| 418 | 421 |
| 419 // We don't have new proxy settings to try, try to fallback to the next proxy | 422 // We don't have new proxy settings to try, try to fallback to the next proxy |
| 420 // in the list. | 423 // in the list. |
| 421 bool did_fallback = result->Fallback(&proxy_retry_info_); | 424 bool did_fallback = result->Fallback(&proxy_retry_info_); |
| 422 | 425 |
| 423 // Return synchronous failure if there is nothing left to fall-back to. | 426 // Return synchronous failure if there is nothing left to fall-back to. |
| 424 // TODO(eroman): This is a yucky API, clean it up. | 427 // TODO(eroman): This is a yucky API, clean it up. |
| 425 return did_fallback ? OK : ERR_FAILED; | 428 return did_fallback ? OK : ERR_FAILED; |
| 426 } | 429 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 439 | 442 |
| 440 void ProxyService::RemovePendingRequest(PacRequest* req) { | 443 void ProxyService::RemovePendingRequest(PacRequest* req) { |
| 441 DCHECK(ContainsPendingRequest(req)); | 444 DCHECK(ContainsPendingRequest(req)); |
| 442 PendingRequests::iterator it = std::find( | 445 PendingRequests::iterator it = std::find( |
| 443 pending_requests_.begin(), pending_requests_.end(), req); | 446 pending_requests_.begin(), pending_requests_.end(), req); |
| 444 pending_requests_.erase(it); | 447 pending_requests_.erase(it); |
| 445 } | 448 } |
| 446 | 449 |
| 447 int ProxyService::DidFinishResolvingProxy(ProxyInfo* result, | 450 int ProxyService::DidFinishResolvingProxy(ProxyInfo* result, |
| 448 int result_code, | 451 int result_code, |
| 449 LoadLog* load_log) { | 452 const BoundNetLog& net_log) { |
| 450 // Log the result of the proxy resolution. | 453 // Log the result of the proxy resolution. |
| 451 if (result_code == OK) { | 454 if (result_code == OK) { |
| 452 // When full logging is enabled, dump the proxy list. | 455 // When full logging is enabled, dump the proxy list. |
| 453 if (LoadLog::IsUnbounded(load_log)) { | 456 if (net_log.HasListener()) { |
| 454 LoadLog::AddString( | 457 net_log.AddString( |
| 455 load_log, | |
| 456 std::string("Resolved proxy list: ") + result->ToPacString()); | 458 std::string("Resolved proxy list: ") + result->ToPacString()); |
| 457 } | 459 } |
| 458 result->DeprioritizeBadProxies(proxy_retry_info_); | 460 result->DeprioritizeBadProxies(proxy_retry_info_); |
| 459 } else { | 461 } else { |
| 460 LoadLog::AddStringLiteral( | 462 net_log.AddStringLiteral( |
| 461 load_log, | |
| 462 "Got an error from proxy resolver, falling-back to DIRECT."); | 463 "Got an error from proxy resolver, falling-back to DIRECT."); |
| 463 LoadLog::AddErrorCode(load_log, result_code); | 464 net_log.AddErrorCode(result_code); |
| 464 | 465 |
| 465 // Fall-back to direct when the proxy resolver fails. This corresponds | 466 // Fall-back to direct when the proxy resolver fails. This corresponds |
| 466 // with a javascript runtime error in the PAC script. | 467 // with a javascript runtime error in the PAC script. |
| 467 // | 468 // |
| 468 // This implicit fall-back to direct matches Firefox 3.5 and | 469 // This implicit fall-back to direct matches Firefox 3.5 and |
| 469 // Internet Explorer 8. For more information, see: | 470 // Internet Explorer 8. For more information, see: |
| 470 // | 471 // |
| 471 // http://www.chromium.org/developers/design-documents/proxy-settings-fallba
ck | 472 // http://www.chromium.org/developers/design-documents/proxy-settings-fallba
ck |
| 472 result->UseDirect(); | 473 result->UseDirect(); |
| 473 result_code = OK; | 474 result_code = OK; |
| 474 } | 475 } |
| 475 | 476 |
| 476 LoadLog::EndEvent(load_log, LoadLog::TYPE_PROXY_SERVICE); | 477 net_log.EndEvent(NetLog::TYPE_PROXY_SERVICE); |
| 477 return result_code; | 478 return result_code; |
| 478 } | 479 } |
| 479 | 480 |
| 480 void ProxyService::SetProxyScriptFetcher( | 481 void ProxyService::SetProxyScriptFetcher( |
| 481 ProxyScriptFetcher* proxy_script_fetcher) { | 482 ProxyScriptFetcher* proxy_script_fetcher) { |
| 482 if (init_proxy_resolver_.get()) { | 483 if (init_proxy_resolver_.get()) { |
| 483 // We need to be careful to first cancel |init_proxy_resolver_|, since it | 484 // We need to be careful to first cancel |init_proxy_resolver_|, since it |
| 484 // holds a pointer to the old proxy script fetcher we are about to delete. | 485 // holds a pointer to the old proxy script fetcher we are about to delete. |
| 485 | 486 |
| 486 DCHECK(IsInitializingProxyResolver()); | 487 DCHECK(IsInitializingProxyResolver()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 return new ProxyResolverWinHttp(); | 558 return new ProxyResolverWinHttp(); |
| 558 #elif defined(OS_MACOSX) | 559 #elif defined(OS_MACOSX) |
| 559 return new ProxyResolverMac(); | 560 return new ProxyResolverMac(); |
| 560 #else | 561 #else |
| 561 LOG(WARNING) << "PAC support disabled because there is no fallback " | 562 LOG(WARNING) << "PAC support disabled because there is no fallback " |
| 562 "non-V8 implementation"; | 563 "non-V8 implementation"; |
| 563 return new ProxyResolverNull(); | 564 return new ProxyResolverNull(); |
| 564 #endif | 565 #endif |
| 565 } | 566 } |
| 566 | 567 |
| 567 void ProxyService::UpdateConfig(LoadLog* load_log) { | 568 void ProxyService::UpdateConfig(const BoundNetLog& net_log) { |
| 568 bool is_first_update = !config_has_been_initialized(); | 569 bool is_first_update = !config_has_been_initialized(); |
| 569 | 570 |
| 570 ProxyConfig latest; | 571 ProxyConfig latest; |
| 571 | 572 |
| 572 // Fetch the proxy settings. | 573 // Fetch the proxy settings. |
| 573 TimeTicks start_time = TimeTicks::Now(); | 574 TimeTicks start_time = TimeTicks::Now(); |
| 574 LoadLog::BeginEvent(load_log, | 575 net_log.BeginEvent( |
| 575 LoadLog::TYPE_PROXY_SERVICE_POLL_CONFIG_SERVICE_FOR_CHANGES); | 576 NetLog::TYPE_PROXY_SERVICE_POLL_CONFIG_SERVICE_FOR_CHANGES); |
| 576 int rv = config_service_->GetProxyConfig(&latest); | 577 int rv = config_service_->GetProxyConfig(&latest); |
| 577 LoadLog::EndEvent(load_log, | 578 net_log.EndEvent(NetLog::TYPE_PROXY_SERVICE_POLL_CONFIG_SERVICE_FOR_CHANGES); |
| 578 LoadLog::TYPE_PROXY_SERVICE_POLL_CONFIG_SERVICE_FOR_CHANGES); | |
| 579 TimeTicks end_time = TimeTicks::Now(); | 579 TimeTicks end_time = TimeTicks::Now(); |
| 580 | 580 |
| 581 // Record how long the call to config_service_->GetConfig() above took. | 581 // Record how long the call to config_service_->GetConfig() above took. |
| 582 // On some setups of Windows, we have reports that querying the system | 582 // On some setups of Windows, we have reports that querying the system |
| 583 // proxy settings can take multiple seconds (http://crbug.com/12189). | 583 // proxy settings can take multiple seconds (http://crbug.com/12189). |
| 584 UMA_HISTOGRAM_CUSTOM_TIMES("Net.ProxyPollConfigurationTime", | 584 UMA_HISTOGRAM_CUSTOM_TIMES("Net.ProxyPollConfigurationTime", |
| 585 end_time - start_time, | 585 end_time - start_time, |
| 586 TimeDelta::FromMilliseconds(1), | 586 TimeDelta::FromMilliseconds(1), |
| 587 TimeDelta::FromSeconds(30), | 587 TimeDelta::FromSeconds(30), |
| 588 50); | 588 50); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 StartInitProxyResolver(); | 629 StartInitProxyResolver(); |
| 630 } | 630 } |
| 631 } | 631 } |
| 632 | 632 |
| 633 void ProxyService::StartInitProxyResolver() { | 633 void ProxyService::StartInitProxyResolver() { |
| 634 DCHECK(!init_proxy_resolver_.get()); | 634 DCHECK(!init_proxy_resolver_.get()); |
| 635 | 635 |
| 636 init_proxy_resolver_.reset( | 636 init_proxy_resolver_.reset( |
| 637 new InitProxyResolver(resolver_.get(), proxy_script_fetcher_.get())); | 637 new InitProxyResolver(resolver_.get(), proxy_script_fetcher_.get())); |
| 638 | 638 |
| 639 init_proxy_resolver_log_ = new LoadLog(kMaxNumLoadLogEntries); | 639 init_proxy_resolver_log_.Clear(); |
| 640 | 640 |
| 641 int rv = init_proxy_resolver_->Init( | 641 int rv = init_proxy_resolver_->Init( |
| 642 config_, &init_proxy_resolver_callback_, init_proxy_resolver_log_); | 642 config_, &init_proxy_resolver_callback_, |
| 643 init_proxy_resolver_log_.bound()); |
| 643 | 644 |
| 644 if (rv != ERR_IO_PENDING) | 645 if (rv != ERR_IO_PENDING) |
| 645 OnInitProxyResolverComplete(rv); | 646 OnInitProxyResolverComplete(rv); |
| 646 } | 647 } |
| 647 | 648 |
| 648 void ProxyService::UpdateConfigIfOld(LoadLog* load_log) { | 649 void ProxyService::UpdateConfigIfOld(const BoundNetLog& net_log) { |
| 649 // The overhead of calling ProxyConfigService::GetProxyConfig is very low. | 650 // The overhead of calling ProxyConfigService::GetProxyConfig is very low. |
| 650 const TimeDelta kProxyConfigMaxAge = TimeDelta::FromSeconds(5); | 651 const TimeDelta kProxyConfigMaxAge = TimeDelta::FromSeconds(5); |
| 651 | 652 |
| 652 // Periodically check for a new config. | 653 // Periodically check for a new config. |
| 653 if (!config_has_been_initialized() || | 654 if (!config_has_been_initialized() || |
| 654 (TimeTicks::Now() - config_last_update_time_) > kProxyConfigMaxAge) | 655 (TimeTicks::Now() - config_last_update_time_) > kProxyConfigMaxAge) |
| 655 UpdateConfig(load_log); | 656 UpdateConfig(net_log); |
| 656 } | 657 } |
| 657 | 658 |
| 658 | 659 |
| 659 void ProxyService::OnIPAddressChanged() { | 660 void ProxyService::OnIPAddressChanged() { |
| 660 DCHECK(network_change_notifier_); | 661 DCHECK(network_change_notifier_); |
| 661 | 662 |
| 662 // Mark the current configuration as being un-initialized. | 663 // Mark the current configuration as being un-initialized. |
| 663 // | 664 // |
| 664 // This will force us to re-fetch the configuration (and re-run all of | 665 // This will force us to re-fetch the configuration (and re-run all of |
| 665 // the initialization steps) on the next ResolveProxy() request, as part | 666 // the initialization steps) on the next ResolveProxy() request, as part |
| 666 // of UpdateConfigIfOld(). | 667 // of UpdateConfigIfOld(). |
| 667 config_.set_id(ProxyConfig::INVALID_ID); | 668 config_.set_id(ProxyConfig::INVALID_ID); |
| 668 } | 669 } |
| 669 | 670 |
| 670 SyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop, | 671 SyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop, |
| 671 ProxyService* proxy_service) | 672 ProxyService* proxy_service) |
| 672 : io_message_loop_(io_message_loop), | 673 : io_message_loop_(io_message_loop), |
| 673 proxy_service_(proxy_service), | 674 proxy_service_(proxy_service), |
| 674 event_(false, false), | 675 event_(false, false), |
| 675 ALLOW_THIS_IN_INITIALIZER_LIST(callback_( | 676 ALLOW_THIS_IN_INITIALIZER_LIST(callback_( |
| 676 this, &SyncProxyServiceHelper::OnCompletion)) { | 677 this, &SyncProxyServiceHelper::OnCompletion)) { |
| 677 DCHECK(io_message_loop_ != MessageLoop::current()); | 678 DCHECK(io_message_loop_ != MessageLoop::current()); |
| 678 } | 679 } |
| 679 | 680 |
| 680 int SyncProxyServiceHelper::ResolveProxy(const GURL& url, | 681 int SyncProxyServiceHelper::ResolveProxy(const GURL& url, |
| 681 ProxyInfo* proxy_info, | 682 ProxyInfo* proxy_info, |
| 682 LoadLog* load_log) { | 683 const BoundNetLog& net_log) { |
| 683 DCHECK(io_message_loop_ != MessageLoop::current()); | 684 DCHECK(io_message_loop_ != MessageLoop::current()); |
| 684 | 685 |
| 685 io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 686 io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 686 this, &SyncProxyServiceHelper::StartAsyncResolve, url, load_log)); | 687 this, &SyncProxyServiceHelper::StartAsyncResolve, url, net_log)); |
| 687 | 688 |
| 688 event_.Wait(); | 689 event_.Wait(); |
| 689 | 690 |
| 690 if (result_ == net::OK) { | 691 if (result_ == net::OK) { |
| 691 *proxy_info = proxy_info_; | 692 *proxy_info = proxy_info_; |
| 692 } | 693 } |
| 693 return result_; | 694 return result_; |
| 694 } | 695 } |
| 695 | 696 |
| 696 int SyncProxyServiceHelper::ReconsiderProxyAfterError( | 697 int SyncProxyServiceHelper::ReconsiderProxyAfterError( |
| 697 const GURL& url, ProxyInfo* proxy_info, LoadLog* load_log) { | 698 const GURL& url, ProxyInfo* proxy_info, const BoundNetLog& net_log) { |
| 698 DCHECK(io_message_loop_ != MessageLoop::current()); | 699 DCHECK(io_message_loop_ != MessageLoop::current()); |
| 699 | 700 |
| 700 io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 701 io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 701 this, &SyncProxyServiceHelper::StartAsyncReconsider, url, load_log)); | 702 this, &SyncProxyServiceHelper::StartAsyncReconsider, url, net_log)); |
| 702 | 703 |
| 703 event_.Wait(); | 704 event_.Wait(); |
| 704 | 705 |
| 705 if (result_ == net::OK) { | 706 if (result_ == net::OK) { |
| 706 *proxy_info = proxy_info_; | 707 *proxy_info = proxy_info_; |
| 707 } | 708 } |
| 708 return result_; | 709 return result_; |
| 709 } | 710 } |
| 710 | 711 |
| 711 void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, | 712 void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, |
| 712 LoadLog* load_log) { | 713 const BoundNetLog& net_log) { |
| 713 result_ = proxy_service_->ResolveProxy( | 714 result_ = proxy_service_->ResolveProxy( |
| 714 url, &proxy_info_, &callback_, NULL, load_log); | 715 url, &proxy_info_, &callback_, NULL, net_log); |
| 715 if (result_ != net::ERR_IO_PENDING) { | 716 if (result_ != net::ERR_IO_PENDING) { |
| 716 OnCompletion(result_); | 717 OnCompletion(result_); |
| 717 } | 718 } |
| 718 } | 719 } |
| 719 | 720 |
| 720 void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, | 721 void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, |
| 721 LoadLog* load_log) { | 722 const BoundNetLog& net_log) { |
| 722 result_ = proxy_service_->ReconsiderProxyAfterError( | 723 result_ = proxy_service_->ReconsiderProxyAfterError( |
| 723 url, &proxy_info_, &callback_, NULL, load_log); | 724 url, &proxy_info_, &callback_, NULL, net_log); |
| 724 if (result_ != net::ERR_IO_PENDING) { | 725 if (result_ != net::ERR_IO_PENDING) { |
| 725 OnCompletion(result_); | 726 OnCompletion(result_); |
| 726 } | 727 } |
| 727 } | 728 } |
| 728 | 729 |
| 729 void SyncProxyServiceHelper::OnCompletion(int rv) { | 730 void SyncProxyServiceHelper::OnCompletion(int rv) { |
| 730 result_ = rv; | 731 result_ = rv; |
| 731 event_.Signal(); | 732 event_.Signal(); |
| 732 } | 733 } |
| 733 | 734 |
| 734 } // namespace net | 735 } // namespace net |
| OLD | NEW |