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 |