Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: net/proxy/mock_proxy_resolver.h

Issue 160619: Remove dependency on SingleThreadedProxyResolver from resolve_proxy_msg_helper_unittest (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Address willchan's comments + sync Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/net.gyp ('k') | net/proxy/proxy_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #ifndef NET_PROXY_MOCK_PROXY_RESOLVER_H_
6 #define NET_PROXY_MOCK_PROXY_RESOLVER_H_
7
5 #include <vector> 8 #include <vector>
6 9
7 #include "base/logging.h" 10 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "googleurl/src/gurl.h" 11 #include "googleurl/src/gurl.h"
10 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
11 #include "net/base/test_completion_callback.h"
12 #include "net/proxy/proxy_config_service.h"
13 #include "net/proxy/proxy_resolver.h" 13 #include "net/proxy/proxy_resolver.h"
14 #include "net/proxy/proxy_script_fetcher.h"
15 #include "net/proxy/proxy_service.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 14
18 // TODO(eroman): Write a test which exercises
19 // ProxyService::SuspendAllPendingRequests().
20 namespace net { 15 namespace net {
21 namespace {
22
23 class MockProxyConfigService: public ProxyConfigService {
24 public:
25 MockProxyConfigService() {} // Direct connect.
26 explicit MockProxyConfigService(const ProxyConfig& pc) : config(pc) {}
27 explicit MockProxyConfigService(const std::string& pac_url) {
28 config.pac_url = GURL(pac_url);
29 }
30
31 virtual int GetProxyConfig(ProxyConfig* results) {
32 *results = config;
33 return OK;
34 }
35
36 ProxyConfig config;
37 };
38 16
39 // Asynchronous mock proxy resolver. All requests complete asynchronously, 17 // Asynchronous mock proxy resolver. All requests complete asynchronously,
40 // user must call Request::CompleteNow() on a pending request to signal it. 18 // user must call Request::CompleteNow() on a pending request to signal it.
41 class MockAsyncProxyResolverBase : public ProxyResolver { 19 class MockAsyncProxyResolverBase : public ProxyResolver {
42 public: 20 public:
43 class Request : public base::RefCounted<Request> { 21 class Request : public base::RefCounted<Request> {
44 public: 22 public:
45 Request(MockAsyncProxyResolverBase* resolver, 23 Request(MockAsyncProxyResolverBase* resolver,
46 const GURL& url, 24 const GURL& url,
47 ProxyInfo* results, 25 ProxyInfo* results,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 104
127 virtual void CancelRequest(RequestHandle request_handle) { 105 virtual void CancelRequest(RequestHandle request_handle) {
128 scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle); 106 scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle);
129 cancelled_requests_.push_back(request); 107 cancelled_requests_.push_back(request);
130 RemovePendingRequest(request); 108 RemovePendingRequest(request);
131 } 109 }
132 110
133 virtual int SetPacScript(const GURL& pac_url, 111 virtual int SetPacScript(const GURL& pac_url,
134 const std::string& pac_bytes, 112 const std::string& pac_bytes,
135 CompletionCallback* callback) { 113 CompletionCallback* callback) {
136 EXPECT_EQ(NULL, pending_set_pac_script_request_.get()); 114 DCHECK(!pending_set_pac_script_request_.get());
137 pending_set_pac_script_request_.reset( 115 pending_set_pac_script_request_.reset(
138 new SetPacScriptRequest(this, pac_url, pac_bytes, callback)); 116 new SetPacScriptRequest(this, pac_url, pac_bytes, callback));
139 // Finished when user calls SetPacScriptRequest::CompleteNow(). 117 // Finished when user calls SetPacScriptRequest::CompleteNow().
140 return ERR_IO_PENDING; 118 return ERR_IO_PENDING;
141 } 119 }
142 120
143 const RequestsList& pending_requests() const { 121 const RequestsList& pending_requests() const {
144 return pending_requests_; 122 return pending_requests_;
145 } 123 }
146 124
147 const RequestsList& cancelled_requests() const { 125 const RequestsList& cancelled_requests() const {
148 return cancelled_requests_; 126 return cancelled_requests_;
149 } 127 }
150 128
151 SetPacScriptRequest* pending_set_pac_script_request() const { 129 SetPacScriptRequest* pending_set_pac_script_request() const {
152 return pending_set_pac_script_request_.get(); 130 return pending_set_pac_script_request_.get();
153 } 131 }
154 132
155 void RemovePendingRequest(Request* request) { 133 void RemovePendingRequest(Request* request) {
156 RequestsList::iterator it = std::find( 134 RequestsList::iterator it = std::find(
157 pending_requests_.begin(), pending_requests_.end(), request); 135 pending_requests_.begin(), pending_requests_.end(), request);
158 DCHECK(it != pending_requests_.end()); 136 DCHECK(it != pending_requests_.end());
159 pending_requests_.erase(it); 137 pending_requests_.erase(it);
160 } 138 }
161 139
162 void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) { 140 void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) {
163 EXPECT_EQ(request, pending_set_pac_script_request()); 141 DCHECK_EQ(request, pending_set_pac_script_request());
164 pending_set_pac_script_request_.reset(); 142 pending_set_pac_script_request_.reset();
165 } 143 }
166 144
167 protected: 145 protected:
168 explicit MockAsyncProxyResolverBase(bool expects_pac_bytes) 146 explicit MockAsyncProxyResolverBase(bool expects_pac_bytes)
169 : ProxyResolver(expects_pac_bytes) {} 147 : ProxyResolver(expects_pac_bytes) {}
170 148
171 private: 149 private:
172 RequestsList pending_requests_; 150 RequestsList pending_requests_;
173 RequestsList cancelled_requests_; 151 RequestsList cancelled_requests_;
174 scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_; 152 scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_;
175 }; 153 };
176 154
177 class MockAsyncProxyResolver : public MockAsyncProxyResolverBase { 155 class MockAsyncProxyResolver : public MockAsyncProxyResolverBase {
178 public: 156 public:
179 MockAsyncProxyResolver() 157 MockAsyncProxyResolver()
180 : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {} 158 : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {}
181 }; 159 };
182 160
183 class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase { 161 class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase {
184 public: 162 public:
185 MockAsyncProxyResolverExpectsBytes() 163 MockAsyncProxyResolverExpectsBytes()
186 : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {} 164 : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {}
187 }; 165 };
188 166
189 } // namespace 167 } // namespace net
190 168
191 // A mock ProxyScriptFetcher. No result will be returned to the fetch client 169 #endif // NET_PROXY_MOCK_PROXY_RESOLVER_H_
192 // until we call NotifyFetchCompletion() to set the results.
193 class MockProxyScriptFetcher : public ProxyScriptFetcher {
194 public:
195 MockProxyScriptFetcher()
196 : pending_request_callback_(NULL), pending_request_bytes_(NULL) {
197 }
198
199 // ProxyScriptFetcher implementation.
200 virtual int Fetch(const GURL& url,
201 std::string* bytes,
202 CompletionCallback* callback) {
203 DCHECK(!has_pending_request());
204
205 // Save the caller's information, and have them wait.
206 pending_request_url_ = url;
207 pending_request_callback_ = callback;
208 pending_request_bytes_ = bytes;
209 return ERR_IO_PENDING;
210 }
211
212 void NotifyFetchCompletion(int result, const std::string& bytes) {
213 DCHECK(has_pending_request());
214 *pending_request_bytes_ = bytes;
215 CompletionCallback* callback = pending_request_callback_;
216 pending_request_callback_ = NULL;
217 callback->Run(result);
218 }
219
220 virtual void Cancel() {}
221
222 const GURL& pending_request_url() const {
223 return pending_request_url_;
224 }
225
226 bool has_pending_request() const {
227 return pending_request_callback_ != NULL;
228 }
229
230 private:
231 GURL pending_request_url_;
232 CompletionCallback* pending_request_callback_;
233 std::string* pending_request_bytes_;
234 };
235
236 TEST(ProxyServiceTest, Direct) {
237 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
238 ProxyService service(new MockProxyConfigService, resolver);
239
240 GURL url("http://www.google.com/");
241
242 ProxyInfo info;
243 TestCompletionCallback callback;
244 int rv = service.ResolveProxy(url, &info, &callback, NULL);
245 EXPECT_EQ(OK, rv);
246 EXPECT_TRUE(resolver->pending_requests().empty());
247
248 EXPECT_TRUE(info.is_direct());
249 }
250
251 TEST(ProxyServiceTest, PAC) {
252 MockProxyConfigService* config_service =
253 new MockProxyConfigService("http://foopy/proxy.pac");
254
255 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
256
257 ProxyService service(config_service, resolver);
258
259 GURL url("http://www.google.com/");
260
261 ProxyInfo info;
262 TestCompletionCallback callback;
263 int rv = service.ResolveProxy(url, &info, &callback, NULL);
264 EXPECT_EQ(ERR_IO_PENDING, rv);
265
266 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
267 resolver->pending_set_pac_script_request()->pac_url());
268 resolver->pending_set_pac_script_request()->CompleteNow(OK);
269
270 ASSERT_EQ(1u, resolver->pending_requests().size());
271 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
272
273 // Set the result in proxy resolver.
274 resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
275 resolver->pending_requests()[0]->CompleteNow(OK);
276
277 EXPECT_EQ(OK, callback.WaitForResult());
278 EXPECT_FALSE(info.is_direct());
279 EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
280 }
281
282 // Test that the proxy resolver does not see the URL's username/password
283 // or its reference section.
284 TEST(ProxyServiceTest, PAC_NoIdentityOrHash) {
285 MockProxyConfigService* config_service =
286 new MockProxyConfigService("http://foopy/proxy.pac");
287
288 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
289
290 ProxyService service(config_service, resolver);
291
292 GURL url("http://username:password@www.google.com/?ref#hash#hash");
293
294 ProxyInfo info;
295 TestCompletionCallback callback;
296 int rv = service.ResolveProxy(url, &info, &callback, NULL);
297 EXPECT_EQ(ERR_IO_PENDING, rv);
298
299 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
300 resolver->pending_set_pac_script_request()->pac_url());
301 resolver->pending_set_pac_script_request()->CompleteNow(OK);
302
303 ASSERT_EQ(1u, resolver->pending_requests().size());
304 // The URL should have been simplified, stripping the username/password/hash.
305 EXPECT_EQ(GURL("http://www.google.com/?ref"),
306 resolver->pending_requests()[0]->url());
307
308 // We end here without ever completing the request -- destruction of
309 // ProxyService will cancel the outstanding request.
310 }
311
312 TEST(ProxyServiceTest, PAC_FailoverToDirect) {
313 MockProxyConfigService* config_service =
314 new MockProxyConfigService("http://foopy/proxy.pac");
315 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
316
317 ProxyService service(config_service, resolver);
318
319 GURL url("http://www.google.com/");
320
321 ProxyInfo info;
322 TestCompletionCallback callback1;
323 int rv = service.ResolveProxy(url, &info, &callback1, NULL);
324 EXPECT_EQ(ERR_IO_PENDING, rv);
325
326 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
327 resolver->pending_set_pac_script_request()->pac_url());
328 resolver->pending_set_pac_script_request()->CompleteNow(OK);
329
330 ASSERT_EQ(1u, resolver->pending_requests().size());
331 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
332
333 // Set the result in proxy resolver.
334 resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
335 resolver->pending_requests()[0]->CompleteNow(OK);
336
337 EXPECT_EQ(OK, callback1.WaitForResult());
338 EXPECT_FALSE(info.is_direct());
339 EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
340
341 // Now, imagine that connecting to foopy:8080 fails.
342 TestCompletionCallback callback2;
343 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL);
344 EXPECT_EQ(OK, rv);
345 EXPECT_TRUE(info.is_direct());
346 }
347
348 TEST(ProxyServiceTest, ProxyResolverFails) {
349 // Test what happens when the ProxyResolver fails (this could represent
350 // a failure to download the PAC script in the case of ProxyResolvers which
351 // do the fetch internally.)
352 // TODO(eroman): change this comment.
353
354 MockProxyConfigService* config_service =
355 new MockProxyConfigService("http://foopy/proxy.pac");
356
357 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
358
359 ProxyService service(config_service, resolver);
360
361 // Start first resolve request.
362 GURL url("http://www.google.com/");
363 ProxyInfo info;
364 TestCompletionCallback callback1;
365 int rv = service.ResolveProxy(url, &info, &callback1, NULL);
366 EXPECT_EQ(ERR_IO_PENDING, rv);
367
368 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
369 resolver->pending_set_pac_script_request()->pac_url());
370 resolver->pending_set_pac_script_request()->CompleteNow(OK);
371
372 ASSERT_EQ(1u, resolver->pending_requests().size());
373 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
374
375 // Fail the first resolve request in MockAsyncProxyResolver.
376 resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
377
378 EXPECT_EQ(ERR_FAILED, callback1.WaitForResult());
379
380 // The second resolve request will automatically select direct connect,
381 // because it has cached the configuration as being bad.
382 TestCompletionCallback callback2;
383 rv = service.ResolveProxy(url, &info, &callback2, NULL);
384 EXPECT_EQ(OK, rv);
385 EXPECT_TRUE(info.is_direct());
386 EXPECT_TRUE(resolver->pending_requests().empty());
387
388 // But, if that fails, then we should give the proxy config another shot
389 // since we have never tried it with this URL before.
390 TestCompletionCallback callback3;
391 rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL);
392 EXPECT_EQ(ERR_IO_PENDING, rv);
393
394 ASSERT_EQ(1u, resolver->pending_requests().size());
395 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
396
397 // Set the result in proxy resolver.
398 resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
399 resolver->pending_requests()[0]->CompleteNow(OK);
400
401 EXPECT_EQ(OK, callback3.WaitForResult());
402 EXPECT_FALSE(info.is_direct());
403 EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
404 }
405
406 TEST(ProxyServiceTest, ProxyFallback) {
407 // Test what happens when we specify multiple proxy servers and some of them
408 // are bad.
409
410 MockProxyConfigService* config_service =
411 new MockProxyConfigService("http://foopy/proxy.pac");
412
413 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
414
415 ProxyService service(config_service, resolver);
416
417 GURL url("http://www.google.com/");
418
419 // Get the proxy information.
420 ProxyInfo info;
421 TestCompletionCallback callback1;
422 int rv = service.ResolveProxy(url, &info, &callback1, NULL);
423 EXPECT_EQ(ERR_IO_PENDING, rv);
424
425 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
426 resolver->pending_set_pac_script_request()->pac_url());
427 resolver->pending_set_pac_script_request()->CompleteNow(OK);
428
429 ASSERT_EQ(1u, resolver->pending_requests().size());
430 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
431
432 // Set the result in proxy resolver.
433 resolver->pending_requests()[0]->results()->UseNamedProxy(
434 "foopy1:8080;foopy2:9090");
435 resolver->pending_requests()[0]->CompleteNow(OK);
436
437 // The first item is valid.
438 EXPECT_EQ(OK, callback1.WaitForResult());
439 EXPECT_FALSE(info.is_direct());
440 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
441
442 // Fake an error on the proxy.
443 TestCompletionCallback callback2;
444 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL);
445 EXPECT_EQ(OK, rv);
446
447 // The second proxy should be specified.
448 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
449
450 TestCompletionCallback callback3;
451 rv = service.ResolveProxy(url, &info, &callback3, NULL);
452 EXPECT_EQ(ERR_IO_PENDING, rv);
453
454 ASSERT_EQ(1u, resolver->pending_requests().size());
455 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
456
457 // Set the result in proxy resolver -- the second result is already known
458 // to be bad.
459 resolver->pending_requests()[0]->results()->UseNamedProxy(
460 "foopy3:7070;foopy1:8080;foopy2:9090");
461 resolver->pending_requests()[0]->CompleteNow(OK);
462
463 EXPECT_EQ(OK, callback3.WaitForResult());
464 EXPECT_FALSE(info.is_direct());
465 EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
466
467 // We fake another error. It should now try the third one.
468 TestCompletionCallback callback4;
469 rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL);
470 EXPECT_EQ(OK, rv);
471 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
472
473 // Fake another error, the last proxy is gone, the list should now be empty.
474 TestCompletionCallback callback5;
475 rv = service.ReconsiderProxyAfterError(url, &info, &callback5, NULL);
476 EXPECT_EQ(OK, rv); // We try direct.
477 EXPECT_TRUE(info.is_direct());
478
479 // If it fails again, we don't have anything else to try.
480 TestCompletionCallback callback6;
481 rv = service.ReconsiderProxyAfterError(url, &info, &callback6, NULL);
482 EXPECT_EQ(ERR_FAILED, rv);
483
484 // TODO(nsylvain): Test that the proxy can be retried after the delay.
485 }
486
487 TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
488 // Test proxy failover when new settings are available.
489
490 MockProxyConfigService* config_service =
491 new MockProxyConfigService("http://foopy/proxy.pac");
492
493 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
494
495 ProxyService service(config_service, resolver);
496
497 GURL url("http://www.google.com/");
498
499 // Get the proxy information.
500 ProxyInfo info;
501 TestCompletionCallback callback1;
502 int rv = service.ResolveProxy(url, &info, &callback1, NULL);
503 EXPECT_EQ(ERR_IO_PENDING, rv);
504
505 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
506 resolver->pending_set_pac_script_request()->pac_url());
507 resolver->pending_set_pac_script_request()->CompleteNow(OK);
508
509 ASSERT_EQ(1u, resolver->pending_requests().size());
510 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
511
512 // Set the result in proxy resolver.
513 resolver->pending_requests()[0]->results()->UseNamedProxy(
514 "foopy1:8080;foopy2:9090");
515 resolver->pending_requests()[0]->CompleteNow(OK);
516
517 // The first item is valid.
518 EXPECT_EQ(OK, callback1.WaitForResult());
519 EXPECT_FALSE(info.is_direct());
520 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
521
522 // Fake an error on the proxy, and also a new configuration on the proxy.
523 config_service->config = ProxyConfig();
524 config_service->config.pac_url = GURL("http://foopy-new/proxy.pac");
525
526 TestCompletionCallback callback2;
527 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL);
528 EXPECT_EQ(ERR_IO_PENDING, rv);
529
530 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
531 resolver->pending_set_pac_script_request()->pac_url());
532 resolver->pending_set_pac_script_request()->CompleteNow(OK);
533
534 ASSERT_EQ(1u, resolver->pending_requests().size());
535 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
536
537 resolver->pending_requests()[0]->results()->UseNamedProxy(
538 "foopy1:8080;foopy2:9090");
539 resolver->pending_requests()[0]->CompleteNow(OK);
540
541 // The first proxy is still there since the configuration changed.
542 EXPECT_EQ(OK, callback2.WaitForResult());
543 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
544
545 // We fake another error. It should now ignore the first one.
546 TestCompletionCallback callback3;
547 rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL);
548 EXPECT_EQ(OK, rv);
549 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
550
551 // We simulate a new configuration.
552 config_service->config = ProxyConfig();
553 config_service->config.pac_url = GURL("http://foopy-new2/proxy.pac");
554
555 // We fake another error. It should go back to the first proxy.
556 TestCompletionCallback callback4;
557 rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL);
558 EXPECT_EQ(ERR_IO_PENDING, rv);
559
560 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
561 resolver->pending_set_pac_script_request()->pac_url());
562 resolver->pending_set_pac_script_request()->CompleteNow(OK);
563
564 ASSERT_EQ(1u, resolver->pending_requests().size());
565 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
566
567 resolver->pending_requests()[0]->results()->UseNamedProxy(
568 "foopy1:8080;foopy2:9090");
569 resolver->pending_requests()[0]->CompleteNow(OK);
570
571 EXPECT_EQ(OK, callback4.WaitForResult());
572 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
573 }
574
575 TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
576 // Test proxy failover when the configuration is bad.
577
578 MockProxyConfigService* config_service =
579 new MockProxyConfigService("http://foopy/proxy.pac");
580
581 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
582
583 ProxyService service(config_service, resolver);
584
585 GURL url("http://www.google.com/");
586
587 // Get the proxy information.
588 ProxyInfo info;
589 TestCompletionCallback callback1;
590 int rv = service.ResolveProxy(url, &info, &callback1, NULL);
591 EXPECT_EQ(ERR_IO_PENDING, rv);
592
593 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
594 resolver->pending_set_pac_script_request()->pac_url());
595 resolver->pending_set_pac_script_request()->CompleteNow(OK);
596 ASSERT_EQ(1u, resolver->pending_requests().size());
597 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
598
599 resolver->pending_requests()[0]->results()->UseNamedProxy(
600 "foopy1:8080;foopy2:9090");
601 resolver->pending_requests()[0]->CompleteNow(OK);
602
603 // The first item is valid.
604 EXPECT_EQ(OK, callback1.WaitForResult());
605 EXPECT_FALSE(info.is_direct());
606 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
607
608 // Fake a proxy error.
609 TestCompletionCallback callback2;
610 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL);
611 EXPECT_EQ(OK, rv);
612
613 // The first proxy is ignored, and the second one is selected.
614 EXPECT_FALSE(info.is_direct());
615 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
616
617 // Fake a PAC failure.
618 ProxyInfo info2;
619 TestCompletionCallback callback3;
620 rv = service.ResolveProxy(url, &info2, &callback3, NULL);
621 EXPECT_EQ(ERR_IO_PENDING, rv);
622
623 ASSERT_EQ(1u, resolver->pending_requests().size());
624 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
625
626 resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
627
628 // No proxy servers are returned. It's a direct connection.
629 EXPECT_EQ(ERR_FAILED, callback3.WaitForResult());
630 EXPECT_TRUE(info2.is_direct());
631
632 // The PAC will now be fixed and will return a proxy server.
633 // It should also clear the list of bad proxies.
634
635 // Try to resolve, it will still return "direct" because we have no reason
636 // to check the config since everything works.
637 ProxyInfo info3;
638 TestCompletionCallback callback4;
639 rv = service.ResolveProxy(url, &info3, &callback4, NULL);
640 EXPECT_EQ(OK, rv);
641 EXPECT_TRUE(info3.is_direct());
642
643 // But if the direct connection fails, we check if the ProxyInfo tried to
644 // resolve the proxy before, and if not (like in this case), we give the
645 // PAC another try.
646 TestCompletionCallback callback5;
647 rv = service.ReconsiderProxyAfterError(url, &info3, &callback5, NULL);
648 EXPECT_EQ(ERR_IO_PENDING, rv);
649
650 ASSERT_EQ(1u, resolver->pending_requests().size());
651 EXPECT_EQ(url, resolver->pending_requests()[0]->url());
652
653 resolver->pending_requests()[0]->results()->UseNamedProxy(
654 "foopy1:8080;foopy2:9090");
655 resolver->pending_requests()[0]->CompleteNow(OK);
656
657 // The first proxy is still there since the list of bad proxies got cleared.
658 EXPECT_EQ(OK, callback5.WaitForResult());
659 EXPECT_FALSE(info3.is_direct());
660 EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
661 }
662
663 TEST(ProxyServiceTest, ProxyBypassList) {
664 // Test what happens when a proxy bypass list is specified.
665
666 ProxyInfo info;
667 ProxyConfig config;
668 config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090");
669 config.auto_detect = false;
670 config.proxy_bypass_local_names = true;
671
672 {
673 ProxyService service(new MockProxyConfigService(config),
674 new MockAsyncProxyResolver());
675 GURL url("http://www.google.com/");
676 // Get the proxy information.
677 TestCompletionCallback callback;
678 int rv = service.ResolveProxy(url, &info, &callback, NULL);
679 EXPECT_EQ(OK, rv);
680 EXPECT_FALSE(info.is_direct());
681 }
682
683 {
684 ProxyService service(new MockProxyConfigService(config),
685 new MockAsyncProxyResolver());
686 GURL test_url("http://local");
687 TestCompletionCallback callback;
688 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
689 EXPECT_EQ(OK, rv);
690 EXPECT_TRUE(info.is_direct());
691 }
692
693 config.proxy_bypass.clear();
694 config.proxy_bypass.push_back("*.org");
695 config.proxy_bypass_local_names = true;
696 {
697 ProxyService service(new MockProxyConfigService(config),
698 new MockAsyncProxyResolver);
699 GURL test_url("http://www.webkit.org");
700 TestCompletionCallback callback;
701 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
702 EXPECT_EQ(OK, rv);
703 EXPECT_TRUE(info.is_direct());
704 }
705
706 config.proxy_bypass.clear();
707 config.proxy_bypass.push_back("*.org");
708 config.proxy_bypass.push_back("7*");
709 config.proxy_bypass_local_names = true;
710 {
711 ProxyService service(new MockProxyConfigService(config),
712 new MockAsyncProxyResolver);
713 GURL test_url("http://74.125.19.147");
714 TestCompletionCallback callback;
715 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
716 EXPECT_EQ(OK, rv);
717 EXPECT_TRUE(info.is_direct());
718 }
719
720 config.proxy_bypass.clear();
721 config.proxy_bypass.push_back("*.org");
722 config.proxy_bypass_local_names = true;
723 {
724 ProxyService service(new MockProxyConfigService(config),
725 new MockAsyncProxyResolver);
726 GURL test_url("http://www.msn.com");
727 TestCompletionCallback callback;
728 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
729 EXPECT_EQ(OK, rv);
730 EXPECT_FALSE(info.is_direct());
731 }
732
733 config.proxy_bypass.clear();
734 config.proxy_bypass.push_back("*.MSN.COM");
735 config.proxy_bypass_local_names = true;
736 {
737 ProxyService service(new MockProxyConfigService(config),
738 new MockAsyncProxyResolver);
739 GURL test_url("http://www.msnbc.msn.com");
740 TestCompletionCallback callback;
741 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
742 EXPECT_EQ(OK, rv);
743 EXPECT_TRUE(info.is_direct());
744 }
745
746 config.proxy_bypass.clear();
747 config.proxy_bypass.push_back("*.msn.com");
748 config.proxy_bypass_local_names = true;
749 {
750 ProxyService service(new MockProxyConfigService(config),
751 new MockAsyncProxyResolver);
752 GURL test_url("HTTP://WWW.MSNBC.MSN.COM");
753 TestCompletionCallback callback;
754 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
755 EXPECT_EQ(OK, rv);
756 EXPECT_TRUE(info.is_direct());
757 }
758 }
759
760 TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
761 // Test port specification in bypass list entries.
762 ProxyInfo info;
763 ProxyConfig config;
764 config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090");
765 config.auto_detect = false;
766 config.proxy_bypass_local_names = false;
767
768 config.proxy_bypass.clear();
769 config.proxy_bypass.push_back("*.example.com:99");
770 {
771 ProxyService service(new MockProxyConfigService(config),
772 new MockAsyncProxyResolver);
773 {
774 GURL test_url("http://www.example.com:99");
775 TestCompletionCallback callback;
776 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
777 EXPECT_EQ(OK, rv);
778 EXPECT_TRUE(info.is_direct());
779 }
780 {
781 GURL test_url("http://www.example.com:100");
782 TestCompletionCallback callback;
783 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
784 EXPECT_EQ(OK, rv);
785 EXPECT_FALSE(info.is_direct());
786 }
787 {
788 GURL test_url("http://www.example.com");
789 TestCompletionCallback callback;
790 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
791 EXPECT_EQ(OK, rv);
792 EXPECT_FALSE(info.is_direct());
793 }
794 }
795
796 config.proxy_bypass.clear();
797 config.proxy_bypass.push_back("*.example.com:80");
798 {
799 ProxyService service(new MockProxyConfigService(config),
800 new MockAsyncProxyResolver);
801 GURL test_url("http://www.example.com");
802 TestCompletionCallback callback;
803 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
804 EXPECT_EQ(OK, rv);
805 EXPECT_TRUE(info.is_direct());
806 }
807
808 config.proxy_bypass.clear();
809 config.proxy_bypass.push_back("*.example.com");
810 {
811 ProxyService service(new MockProxyConfigService(config),
812 new MockAsyncProxyResolver);
813 GURL test_url("http://www.example.com:99");
814 TestCompletionCallback callback;
815 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
816 EXPECT_EQ(OK, rv);
817 EXPECT_TRUE(info.is_direct());
818 }
819
820 // IPv6 with port.
821 config.proxy_bypass.clear();
822 config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]:99");
823 {
824 ProxyService service(new MockProxyConfigService(config),
825 new MockAsyncProxyResolver);
826 {
827 GURL test_url("http://[3ffe:2a00:100:7031::1]:99/");
828 TestCompletionCallback callback;
829 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
830 EXPECT_EQ(OK, rv);
831 EXPECT_TRUE(info.is_direct());
832 }
833 {
834 GURL test_url("http://[3ffe:2a00:100:7031::1]/");
835 TestCompletionCallback callback;
836 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
837 EXPECT_EQ(OK, rv);
838 EXPECT_FALSE(info.is_direct());
839 }
840 }
841
842 // IPv6 without port. The bypass entry ought to work without the
843 // brackets, but the bypass matching logic in ProxyService is
844 // currently limited.
845 config.proxy_bypass.clear();
846 config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]");
847 {
848 ProxyService service(new MockProxyConfigService(config),
849 new MockAsyncProxyResolver);
850 {
851 GURL test_url("http://[3ffe:2a00:100:7031::1]:99/");
852 TestCompletionCallback callback;
853 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
854 EXPECT_EQ(OK, rv);
855 EXPECT_TRUE(info.is_direct());
856 }
857 {
858 GURL test_url("http://[3ffe:2a00:100:7031::1]/");
859 TestCompletionCallback callback;
860 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
861 EXPECT_EQ(OK, rv);
862 EXPECT_TRUE(info.is_direct());
863 }
864 }
865 }
866
867 TEST(ProxyServiceTest, PerProtocolProxyTests) {
868 ProxyConfig config;
869 config.proxy_rules.ParseFromString("http=foopy1:8080;https=foopy2:8080");
870 config.auto_detect = false;
871 {
872 ProxyService service(new MockProxyConfigService(config),
873 new MockAsyncProxyResolver);
874 GURL test_url("http://www.msn.com");
875 ProxyInfo info;
876 TestCompletionCallback callback;
877 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
878 EXPECT_EQ(OK, rv);
879 EXPECT_FALSE(info.is_direct());
880 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
881 }
882 {
883 ProxyService service(new MockProxyConfigService(config),
884 new MockAsyncProxyResolver);
885 GURL test_url("ftp://ftp.google.com");
886 ProxyInfo info;
887 TestCompletionCallback callback;
888 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
889 EXPECT_EQ(OK, rv);
890 EXPECT_TRUE(info.is_direct());
891 EXPECT_EQ("direct://", info.proxy_server().ToURI());
892 }
893 {
894 ProxyService service(new MockProxyConfigService(config),
895 new MockAsyncProxyResolver);
896 GURL test_url("https://webbranch.techcu.com");
897 ProxyInfo info;
898 TestCompletionCallback callback;
899 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
900 EXPECT_EQ(OK, rv);
901 EXPECT_FALSE(info.is_direct());
902 EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
903 }
904 {
905 config.proxy_rules.ParseFromString("foopy1:8080");
906 ProxyService service(new MockProxyConfigService(config),
907 new MockAsyncProxyResolver);
908 GURL test_url("http://www.microsoft.com");
909 ProxyInfo info;
910 TestCompletionCallback callback;
911 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
912 EXPECT_EQ(OK, rv);
913 EXPECT_FALSE(info.is_direct());
914 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
915 }
916 }
917
918 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
919 // fall back to the SOCKS proxy.
920 TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
921 ProxyConfig config;
922 config.proxy_rules.ParseFromString("http=foopy1:8080;socks=foopy2:1080");
923 config.auto_detect = false;
924 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
925 config.proxy_rules.type);
926
927 {
928 ProxyService service(new MockProxyConfigService(config),
929 new MockAsyncProxyResolver);
930 GURL test_url("http://www.msn.com");
931 ProxyInfo info;
932 TestCompletionCallback callback;
933 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
934 EXPECT_EQ(OK, rv);
935 EXPECT_FALSE(info.is_direct());
936 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
937 }
938 {
939 ProxyService service(new MockProxyConfigService(config),
940 new MockAsyncProxyResolver);
941 GURL test_url("ftp://ftp.google.com");
942 ProxyInfo info;
943 TestCompletionCallback callback;
944 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
945 EXPECT_EQ(OK, rv);
946 EXPECT_FALSE(info.is_direct());
947 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
948 }
949 {
950 ProxyService service(new MockProxyConfigService(config),
951 new MockAsyncProxyResolver);
952 GURL test_url("https://webbranch.techcu.com");
953 ProxyInfo info;
954 TestCompletionCallback callback;
955 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
956 EXPECT_EQ(OK, rv);
957 EXPECT_FALSE(info.is_direct());
958 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
959 }
960 {
961 ProxyService service(new MockProxyConfigService(config),
962 new MockAsyncProxyResolver);
963 GURL test_url("unknown://www.microsoft.com");
964 ProxyInfo info;
965 TestCompletionCallback callback;
966 int rv = service.ResolveProxy(test_url, &info, &callback, NULL);
967 EXPECT_EQ(OK, rv);
968 EXPECT_FALSE(info.is_direct());
969 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
970 }
971 }
972
973 // Test cancellation of an in-progress request.
974 TEST(ProxyServiceTest, CancelInProgressRequest) {
975 MockProxyConfigService* config_service =
976 new MockProxyConfigService("http://foopy/proxy.pac");
977
978 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
979
980 ProxyService service(config_service, resolver);
981
982 // Start 3 requests.
983
984 ProxyInfo info1;
985 TestCompletionCallback callback1;
986 int rv = service.ResolveProxy(
987 GURL("http://request1"), &info1, &callback1, NULL);
988 EXPECT_EQ(ERR_IO_PENDING, rv);
989
990 // Nothing has been sent to the proxy resolver yet, since the proxy
991 // resolver has not been configured yet.
992 ASSERT_EQ(0u, resolver->pending_requests().size());
993
994 // Successfully initialize the PAC script.
995 EXPECT_EQ(GURL("http://foopy/proxy.pac"),
996 resolver->pending_set_pac_script_request()->pac_url());
997 resolver->pending_set_pac_script_request()->CompleteNow(OK);
998
999 ASSERT_EQ(1u, resolver->pending_requests().size());
1000 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1001
1002 ProxyInfo info2;
1003 TestCompletionCallback callback2;
1004 ProxyService::PacRequest* request2;
1005 rv = service.ResolveProxy(
1006 GURL("http://request2"), &info2, &callback2, &request2);
1007 EXPECT_EQ(ERR_IO_PENDING, rv);
1008 ASSERT_EQ(2u, resolver->pending_requests().size());
1009 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1010
1011 ProxyInfo info3;
1012 TestCompletionCallback callback3;
1013 rv = service.ResolveProxy(
1014 GURL("http://request3"), &info3, &callback3, NULL);
1015 EXPECT_EQ(ERR_IO_PENDING, rv);
1016 ASSERT_EQ(3u, resolver->pending_requests().size());
1017 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
1018
1019 // Cancel the second request
1020 service.CancelPacRequest(request2);
1021
1022 ASSERT_EQ(2u, resolver->pending_requests().size());
1023 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1024 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
1025
1026 // Complete the two un-cancelled requests.
1027 // We complete the last one first, just to mix it up a bit.
1028 resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80");
1029 resolver->pending_requests()[1]->CompleteNow(OK);
1030
1031 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1032 resolver->pending_requests()[0]->CompleteNow(OK);
1033
1034 // Complete and verify that requests ran as expected.
1035 EXPECT_EQ(OK, callback1.WaitForResult());
1036 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1037
1038 EXPECT_FALSE(callback2.have_result()); // Cancelled.
1039 ASSERT_EQ(1u, resolver->cancelled_requests().size());
1040 EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url());
1041
1042 EXPECT_EQ(OK, callback3.WaitForResult());
1043 EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1044 }
1045
1046 // Test the initial PAC download for ProxyResolverWithoutFetch.
1047 TEST(ProxyServiceTest, InitialPACScriptDownload) {
1048 MockProxyConfigService* config_service =
1049 new MockProxyConfigService("http://foopy/proxy.pac");
1050
1051 MockAsyncProxyResolverExpectsBytes* resolver =
1052 new MockAsyncProxyResolverExpectsBytes;
1053
1054 ProxyService service(config_service, resolver);
1055
1056 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1057 service.SetProxyScriptFetcher(fetcher);
1058
1059 // Start 3 requests.
1060
1061 ProxyInfo info1;
1062 TestCompletionCallback callback1;
1063 int rv = service.ResolveProxy(
1064 GURL("http://request1"), &info1, &callback1, NULL);
1065 EXPECT_EQ(ERR_IO_PENDING, rv);
1066
1067 // The first request should have triggered download of PAC script.
1068 EXPECT_TRUE(fetcher->has_pending_request());
1069 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1070
1071 ProxyInfo info2;
1072 TestCompletionCallback callback2;
1073 rv = service.ResolveProxy(
1074 GURL("http://request2"), &info2, &callback2, NULL);
1075 EXPECT_EQ(ERR_IO_PENDING, rv);
1076
1077 ProxyInfo info3;
1078 TestCompletionCallback callback3;
1079 rv = service.ResolveProxy(
1080 GURL("http://request3"), &info3, &callback3, NULL);
1081 EXPECT_EQ(ERR_IO_PENDING, rv);
1082
1083 // Nothing has been sent to the resolver yet.
1084 EXPECT_TRUE(resolver->pending_requests().empty());
1085
1086 // At this point the ProxyService should be waiting for the
1087 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1088 // PAC script download completion.
1089 fetcher->NotifyFetchCompletion(OK, "pac-v1");
1090
1091 // Now that the PAC script is downloaded, it will have been sent to the proxy
1092 // resolver.
1093 EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes());
1094 resolver->pending_set_pac_script_request()->CompleteNow(OK);
1095
1096 ASSERT_EQ(3u, resolver->pending_requests().size());
1097 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1098 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1099 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
1100
1101 // Complete all the requests (in some order).
1102 // Note that as we complete requests, they shift up in |pending_requests()|.
1103
1104 resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80");
1105 resolver->pending_requests()[2]->CompleteNow(OK);
1106
1107 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1108 resolver->pending_requests()[0]->CompleteNow(OK);
1109
1110 resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1111 resolver->pending_requests()[0]->CompleteNow(OK);
1112
1113 // Complete and verify that requests ran as expected.
1114 EXPECT_EQ(OK, callback1.WaitForResult());
1115 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1116
1117 EXPECT_EQ(OK, callback2.WaitForResult());
1118 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1119
1120 EXPECT_EQ(OK, callback3.WaitForResult());
1121 EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1122 }
1123
1124 // Test cancellation of a request, while the PAC script is being fetched.
1125 TEST(ProxyServiceTest, CancelWhilePACFetching) {
1126 MockProxyConfigService* config_service =
1127 new MockProxyConfigService("http://foopy/proxy.pac");
1128
1129 MockAsyncProxyResolverExpectsBytes* resolver =
1130 new MockAsyncProxyResolverExpectsBytes;
1131
1132 ProxyService service(config_service, resolver);
1133
1134 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1135 service.SetProxyScriptFetcher(fetcher);
1136
1137 // Start 3 requests.
1138 ProxyInfo info1;
1139 TestCompletionCallback callback1;
1140 ProxyService::PacRequest* request1;
1141 int rv = service.ResolveProxy(
1142 GURL("http://request1"), &info1, &callback1, &request1);
1143 EXPECT_EQ(ERR_IO_PENDING, rv);
1144
1145 // The first request should have triggered download of PAC script.
1146 EXPECT_TRUE(fetcher->has_pending_request());
1147 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1148
1149 ProxyInfo info2;
1150 TestCompletionCallback callback2;
1151 ProxyService::PacRequest* request2;
1152 rv = service.ResolveProxy(
1153 GURL("http://request2"), &info2, &callback2, &request2);
1154 EXPECT_EQ(ERR_IO_PENDING, rv);
1155
1156 ProxyInfo info3;
1157 TestCompletionCallback callback3;
1158 rv = service.ResolveProxy(
1159 GURL("http://request3"), &info3, &callback3, NULL);
1160 EXPECT_EQ(ERR_IO_PENDING, rv);
1161
1162 // Nothing has been sent to the resolver yet.
1163 EXPECT_TRUE(resolver->pending_requests().empty());
1164
1165 // Cancel the first 2 requests.
1166 service.CancelPacRequest(request1);
1167 service.CancelPacRequest(request2);
1168
1169 // At this point the ProxyService should be waiting for the
1170 // ProxyScriptFetcher to invoke its completion callback, notifying it of
1171 // PAC script download completion.
1172 fetcher->NotifyFetchCompletion(OK, "pac-v1");
1173
1174 // Now that the PAC script is downloaded, it will have been sent to the
1175 // proxy resolver.
1176 EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes());
1177 resolver->pending_set_pac_script_request()->CompleteNow(OK);
1178
1179 ASSERT_EQ(1u, resolver->pending_requests().size());
1180 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url());
1181
1182 // Complete all the requests.
1183 resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80");
1184 resolver->pending_requests()[0]->CompleteNow(OK);
1185
1186 EXPECT_EQ(OK, callback3.WaitForResult());
1187 EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1188
1189 EXPECT_TRUE(resolver->cancelled_requests().empty());
1190
1191 EXPECT_FALSE(callback1.have_result()); // Cancelled.
1192 EXPECT_FALSE(callback2.have_result()); // Cancelled.
1193 }
1194
1195 // Test that if auto-detect fails, we fall-back to the custom pac.
1196 TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
1197 ProxyConfig config;
1198 config.auto_detect = true;
1199 config.pac_url = GURL("http://foopy/proxy.pac");
1200 config.proxy_rules.ParseFromString("http=foopy:80"); // Won't be used.
1201
1202 MockProxyConfigService* config_service = new MockProxyConfigService(config);
1203 MockAsyncProxyResolverExpectsBytes* resolver =
1204 new MockAsyncProxyResolverExpectsBytes;
1205 ProxyService service(config_service, resolver);
1206
1207 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1208 service.SetProxyScriptFetcher(fetcher);
1209
1210 // Start 2 requests.
1211
1212 ProxyInfo info1;
1213 TestCompletionCallback callback1;
1214 int rv = service.ResolveProxy(
1215 GURL("http://request1"), &info1, &callback1, NULL);
1216 EXPECT_EQ(ERR_IO_PENDING, rv);
1217
1218 ProxyInfo info2;
1219 TestCompletionCallback callback2;
1220 ProxyService::PacRequest* request2;
1221 rv = service.ResolveProxy(
1222 GURL("http://request2"), &info2, &callback2, &request2);
1223 EXPECT_EQ(ERR_IO_PENDING, rv);
1224
1225 // Check that nothing has been sent to the proxy resolver yet.
1226 ASSERT_EQ(0u, resolver->pending_requests().size());
1227
1228 // It should be trying to auto-detect first -- FAIL the autodetect during
1229 // the script download.
1230 EXPECT_TRUE(fetcher->has_pending_request());
1231 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1232 fetcher->NotifyFetchCompletion(ERR_FAILED, "");
1233
1234 // Next it should be trying the custom PAC url.
1235 EXPECT_TRUE(fetcher->has_pending_request());
1236 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1237 fetcher->NotifyFetchCompletion(OK, "custom-pac-script");
1238
1239 EXPECT_EQ("custom-pac-script",
1240 resolver->pending_set_pac_script_request()->pac_bytes());
1241 resolver->pending_set_pac_script_request()->CompleteNow(OK);
1242
1243 // Now finally, the pending requests should have been sent to the resolver
1244 // (which was initialized with custom PAC script).
1245
1246 ASSERT_EQ(2u, resolver->pending_requests().size());
1247 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1248 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1249
1250 // Complete the pending requests.
1251 resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
1252 resolver->pending_requests()[1]->CompleteNow(OK);
1253 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1254 resolver->pending_requests()[0]->CompleteNow(OK);
1255
1256 // Verify that requests ran as expected.
1257 EXPECT_EQ(OK, callback1.WaitForResult());
1258 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1259
1260 EXPECT_EQ(OK, callback2.WaitForResult());
1261 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1262 }
1263
1264 // This is the same test as FallbackFromAutodetectToCustomPac, except
1265 // the auto-detect script fails parsing rather than downloading.
1266 TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
1267 ProxyConfig config;
1268 config.auto_detect = true;
1269 config.pac_url = GURL("http://foopy/proxy.pac");
1270 config.proxy_rules.ParseFromString("http=foopy:80"); // Won't be used.
1271
1272 MockProxyConfigService* config_service = new MockProxyConfigService(config);
1273 MockAsyncProxyResolverExpectsBytes* resolver =
1274 new MockAsyncProxyResolverExpectsBytes;
1275 ProxyService service(config_service, resolver);
1276
1277 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1278 service.SetProxyScriptFetcher(fetcher);
1279
1280 // Start 2 requests.
1281
1282 ProxyInfo info1;
1283 TestCompletionCallback callback1;
1284 int rv = service.ResolveProxy(
1285 GURL("http://request1"), &info1, &callback1, NULL);
1286 EXPECT_EQ(ERR_IO_PENDING, rv);
1287
1288 ProxyInfo info2;
1289 TestCompletionCallback callback2;
1290 ProxyService::PacRequest* request2;
1291 rv = service.ResolveProxy(
1292 GURL("http://request2"), &info2, &callback2, &request2);
1293 EXPECT_EQ(ERR_IO_PENDING, rv);
1294
1295 // Check that nothing has been sent to the proxy resolver yet.
1296 ASSERT_EQ(0u, resolver->pending_requests().size());
1297
1298 // It should be trying to auto-detect first -- succeed the download.
1299 EXPECT_TRUE(fetcher->has_pending_request());
1300 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1301 fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
1302
1303 // Simulate a parse error.
1304 EXPECT_EQ("invalid-script-contents",
1305 resolver->pending_set_pac_script_request()->pac_bytes());
1306 resolver->pending_set_pac_script_request()->CompleteNow(
1307 ERR_PAC_SCRIPT_FAILED);
1308
1309 // Next it should be trying the custom PAC url.
1310 EXPECT_TRUE(fetcher->has_pending_request());
1311 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1312 fetcher->NotifyFetchCompletion(OK, "custom-pac-script");
1313
1314 EXPECT_EQ("custom-pac-script",
1315 resolver->pending_set_pac_script_request()->pac_bytes());
1316 resolver->pending_set_pac_script_request()->CompleteNow(OK);
1317
1318 // Now finally, the pending requests should have been sent to the resolver
1319 // (which was initialized with custom PAC script).
1320
1321 ASSERT_EQ(2u, resolver->pending_requests().size());
1322 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1323 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1324
1325 // Complete the pending requests.
1326 resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
1327 resolver->pending_requests()[1]->CompleteNow(OK);
1328 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1329 resolver->pending_requests()[0]->CompleteNow(OK);
1330
1331 // Verify that requests ran as expected.
1332 EXPECT_EQ(OK, callback1.WaitForResult());
1333 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1334
1335 EXPECT_EQ(OK, callback2.WaitForResult());
1336 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1337 }
1338
1339 // Test that if all of auto-detect, a custom PAC script, and manual settings
1340 // are given, then we will try them in that order.
1341 TEST(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
1342 ProxyConfig config;
1343 config.auto_detect = true;
1344 config.pac_url = GURL("http://foopy/proxy.pac");
1345 config.proxy_rules.ParseFromString("http=foopy:80");
1346
1347 MockProxyConfigService* config_service = new MockProxyConfigService(config);
1348 MockAsyncProxyResolverExpectsBytes* resolver =
1349 new MockAsyncProxyResolverExpectsBytes;
1350 ProxyService service(config_service, resolver);
1351
1352 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1353 service.SetProxyScriptFetcher(fetcher);
1354
1355 // Start 2 requests.
1356
1357 ProxyInfo info1;
1358 TestCompletionCallback callback1;
1359 int rv = service.ResolveProxy(
1360 GURL("http://request1"), &info1, &callback1, NULL);
1361 EXPECT_EQ(ERR_IO_PENDING, rv);
1362
1363 ProxyInfo info2;
1364 TestCompletionCallback callback2;
1365 ProxyService::PacRequest* request2;
1366 rv = service.ResolveProxy(
1367 GURL("http://request2"), &info2, &callback2, &request2);
1368 EXPECT_EQ(ERR_IO_PENDING, rv);
1369
1370 // Check that nothing has been sent to the proxy resolver yet.
1371 ASSERT_EQ(0u, resolver->pending_requests().size());
1372
1373 // It should be trying to auto-detect first -- fail the download.
1374 EXPECT_TRUE(fetcher->has_pending_request());
1375 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1376 fetcher->NotifyFetchCompletion(ERR_FAILED, "");
1377
1378 // Next it should be trying the custom PAC url -- fail the download.
1379 EXPECT_TRUE(fetcher->has_pending_request());
1380 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1381 fetcher->NotifyFetchCompletion(ERR_FAILED, "");
1382
1383 // Since we never managed to initialize a ProxyResolver, nothing should have
1384 // been sent to it.
1385 ASSERT_EQ(0u, resolver->pending_requests().size());
1386
1387 // Verify that requests ran as expected -- they should have fallen back to
1388 // the manual proxy configuration for HTTP urls.
1389 EXPECT_EQ(OK, callback1.WaitForResult());
1390 EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
1391
1392 EXPECT_EQ(OK, callback2.WaitForResult());
1393 EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
1394 }
1395
1396 // Test that the bypass rules are NOT applied when using autodetect.
1397 TEST(ProxyServiceTest, BypassDoesntApplyToPac) {
1398 ProxyConfig config;
1399 config.auto_detect = true;
1400 config.pac_url = GURL("http://foopy/proxy.pac");
1401 config.proxy_rules.ParseFromString("http=foopy:80"); // Not used.
1402 config.proxy_bypass.push_back("www.google.com");
1403
1404 MockProxyConfigService* config_service = new MockProxyConfigService(config);
1405 MockAsyncProxyResolverExpectsBytes* resolver =
1406 new MockAsyncProxyResolverExpectsBytes;
1407 ProxyService service(config_service, resolver);
1408
1409 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1410 service.SetProxyScriptFetcher(fetcher);
1411
1412 // Start 1 requests.
1413
1414 ProxyInfo info1;
1415 TestCompletionCallback callback1;
1416 int rv = service.ResolveProxy(
1417 GURL("http://www.google.com"), &info1, &callback1, NULL);
1418 EXPECT_EQ(ERR_IO_PENDING, rv);
1419
1420 // Check that nothing has been sent to the proxy resolver yet.
1421 ASSERT_EQ(0u, resolver->pending_requests().size());
1422
1423 // It should be trying to auto-detect first -- succeed the download.
1424 EXPECT_TRUE(fetcher->has_pending_request());
1425 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1426 fetcher->NotifyFetchCompletion(OK, "auto-detect");
1427
1428 EXPECT_EQ("auto-detect",
1429 resolver->pending_set_pac_script_request()->pac_bytes());
1430 resolver->pending_set_pac_script_request()->CompleteNow(OK);
1431
1432 ASSERT_EQ(1u, resolver->pending_requests().size());
1433 EXPECT_EQ(GURL("http://www.google.com"),
1434 resolver->pending_requests()[0]->url());
1435
1436 // Complete the pending request.
1437 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1438 resolver->pending_requests()[0]->CompleteNow(OK);
1439
1440 // Verify that request ran as expected.
1441 EXPECT_EQ(OK, callback1.WaitForResult());
1442 EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1443
1444 // Start another request, it should pickup the bypass item.
1445 ProxyInfo info2;
1446 TestCompletionCallback callback2;
1447 rv = service.ResolveProxy(
1448 GURL("http://www.google.com"), &info2, &callback2, NULL);
1449 EXPECT_EQ(ERR_IO_PENDING, rv);
1450
1451 ASSERT_EQ(1u, resolver->pending_requests().size());
1452 EXPECT_EQ(GURL("http://www.google.com"),
1453 resolver->pending_requests()[0]->url());
1454
1455 // Complete the pending request.
1456 resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1457 resolver->pending_requests()[0]->CompleteNow(OK);
1458
1459 EXPECT_EQ(OK, callback2.WaitForResult());
1460 EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1461 }
1462
1463 TEST(ProxyServiceTest, ResetProxyConfigService) {
1464 ProxyConfig config1;
1465 config1.proxy_rules.ParseFromString("foopy1:8080");
1466 config1.auto_detect = false;
1467 ProxyService service(new MockProxyConfigService(config1),
1468 new MockAsyncProxyResolverExpectsBytes);
1469
1470 ProxyInfo info;
1471 TestCompletionCallback callback1;
1472 int rv = service.ResolveProxy(
1473 GURL("http://request1"), &info, &callback1, NULL);
1474 EXPECT_EQ(OK, rv);
1475 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1476
1477 ProxyConfig config2;
1478 config2.proxy_rules.ParseFromString("foopy2:8080");
1479 config2.auto_detect = false;
1480 service.ResetConfigService(new MockProxyConfigService(config2));
1481 TestCompletionCallback callback2;
1482 rv = service.ResolveProxy(GURL("http://request2"), &info, &callback2, NULL);
1483 EXPECT_EQ(OK, rv);
1484 EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
1485 }
1486
1487 TEST(ProxyServiceTest, IsLocalName) {
1488 const struct {
1489 const char* url;
1490 bool expected_is_local;
1491 } tests[] = {
1492 // Single-component hostnames are considered local.
1493 {"http://localhost/x", true},
1494 {"http://www", true},
1495
1496 // IPv4 loopback interface.
1497 {"http://127.0.0.1/x", true},
1498 {"http://127.0.0.1:80/x", true},
1499
1500 // IPv6 loopback interface.
1501 {"http://[::1]:80/x", true},
1502 {"http://[0:0::1]:6233/x", true},
1503 {"http://[0:0:0:0:0:0:0:1]/x", true},
1504
1505 // Non-local URLs.
1506 {"http://foo.com/", false},
1507 {"http://localhost.i/", false},
1508 {"http://www.google.com/", false},
1509 {"http://192.168.0.1/", false},
1510
1511 // Try with different protocols.
1512 {"ftp://127.0.0.1/x", true},
1513 {"ftp://foobar.com/x", false},
1514
1515 // This is a bit of a gray-area, but GURL does not strip trailing dots
1516 // in host-names, so the following are considered non-local.
1517 {"http://www./x", false},
1518 {"http://localhost./x", false},
1519 };
1520
1521 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
1522 SCOPED_TRACE(StringPrintf("Test[%d]: %s", i, tests[i].url));
1523 bool is_local = ProxyService::IsLocalName(GURL(tests[i].url));
1524 EXPECT_EQ(tests[i].expected_is_local, is_local);
1525 }
1526 }
1527
1528 } // namespace net
OLDNEW
« no previous file with comments | « net/net.gyp ('k') | net/proxy/proxy_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698