OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <cstdarg> | 7 #include <cstdarg> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 3462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3473 bool synchronous_success = service.TryResolveProxySynchronously( | 3473 bool synchronous_success = service.TryResolveProxySynchronously( |
3474 url, std::string(), LOAD_NORMAL, &info, nullptr, log.bound()); | 3474 url, std::string(), LOAD_NORMAL, &info, nullptr, log.bound()); |
3475 EXPECT_TRUE(synchronous_success); | 3475 EXPECT_TRUE(synchronous_success); |
3476 EXPECT_FALSE(info.is_direct()); | 3476 EXPECT_FALSE(info.is_direct()); |
3477 EXPECT_EQ("foopy1", info.proxy_server().host_port_pair().host()); | 3477 EXPECT_EQ("foopy1", info.proxy_server().host_port_pair().host()); |
3478 | 3478 |
3479 // No request should have been queued. | 3479 // No request should have been queued. |
3480 EXPECT_EQ(0u, factory->pending_requests().size()); | 3480 EXPECT_EQ(0u, factory->pending_requests().size()); |
3481 } | 3481 } |
3482 | 3482 |
| 3483 // Helper class to exercise URL sanitization using the different policies. This |
| 3484 // works by submitted URLs to the ProxyService. In turn the ProxyService |
| 3485 // sanitizes the URL and then passes it along to the ProxyResolver. This helper |
| 3486 // returns the URL seen by the ProxyResolver. |
| 3487 class SanitizeUrlHelper { |
| 3488 public: |
| 3489 SanitizeUrlHelper() { |
| 3490 std::unique_ptr<MockProxyConfigService> config_service( |
| 3491 new MockProxyConfigService("http://foopy/proxy.pac")); |
| 3492 |
| 3493 factory = new MockAsyncProxyResolverFactory(false); |
| 3494 |
| 3495 service_.reset(new ProxyService(std::move(config_service), |
| 3496 base::WrapUnique(factory), nullptr)); |
| 3497 |
| 3498 // Do an initial request to initialize the service (configure the PAC |
| 3499 // script). |
| 3500 GURL url("http://example.com"); |
| 3501 |
| 3502 ProxyInfo info; |
| 3503 TestCompletionCallback callback; |
| 3504 int rv = service_->ResolveProxy(url, std::string(), LOAD_NORMAL, &info, |
| 3505 callback.callback(), nullptr, nullptr, |
| 3506 BoundNetLog()); |
| 3507 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3508 |
| 3509 // First step is to download the PAC script. |
| 3510 EXPECT_EQ(GURL("http://foopy/proxy.pac"), |
| 3511 factory->pending_requests()[0]->script_data()->url()); |
| 3512 factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver); |
| 3513 |
| 3514 EXPECT_EQ(1u, resolver.pending_requests().size()); |
| 3515 EXPECT_EQ(url, resolver.pending_requests()[0]->url()); |
| 3516 |
| 3517 // Complete the request. |
| 3518 resolver.pending_requests()[0]->results()->UsePacString("DIRECT"); |
| 3519 resolver.pending_requests()[0]->CompleteNow(OK); |
| 3520 EXPECT_EQ(OK, callback.WaitForResult()); |
| 3521 EXPECT_TRUE(info.is_direct()); |
| 3522 } |
| 3523 |
| 3524 // Changes the URL sanitization policy for the underlying ProxyService. This |
| 3525 // will affect subsequent calls to SanitizeUrl. |
| 3526 void SetSanitizeUrlPolicy(ProxyService::SanitizeUrlPolicy policy) { |
| 3527 service_->set_sanitize_url_policy(policy); |
| 3528 } |
| 3529 |
| 3530 // Makes a proxy resolution request through the ProxyService, and returns the |
| 3531 // URL that was submitted to the Proxy Resolver. |
| 3532 GURL SanitizeUrl(const GURL& raw_url) { |
| 3533 // Issue a request and see what URL is sent to the proxy resolver. |
| 3534 ProxyInfo info; |
| 3535 TestCompletionCallback callback; |
| 3536 int rv = service_->ResolveProxy(raw_url, std::string(), LOAD_NORMAL, &info, |
| 3537 callback.callback(), nullptr, nullptr, |
| 3538 BoundNetLog()); |
| 3539 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3540 |
| 3541 EXPECT_EQ(1u, resolver.pending_requests().size()); |
| 3542 |
| 3543 GURL sanitized_url = resolver.pending_requests()[0]->url(); |
| 3544 |
| 3545 // Complete the request. |
| 3546 resolver.pending_requests()[0]->results()->UsePacString("DIRECT"); |
| 3547 resolver.pending_requests()[0]->CompleteNow(OK); |
| 3548 EXPECT_EQ(OK, callback.WaitForResult()); |
| 3549 EXPECT_TRUE(info.is_direct()); |
| 3550 |
| 3551 return sanitized_url; |
| 3552 } |
| 3553 |
| 3554 // Changes the ProxyService's URL sanitization policy and then sanitizes |
| 3555 // |raw_url|. |
| 3556 GURL SanitizeUrl(const GURL& raw_url, |
| 3557 ProxyService::SanitizeUrlPolicy policy) { |
| 3558 service_->set_sanitize_url_policy(policy); |
| 3559 return SanitizeUrl(raw_url); |
| 3560 } |
| 3561 |
| 3562 private: |
| 3563 MockAsyncProxyResolver resolver; |
| 3564 MockAsyncProxyResolverFactory* factory; |
| 3565 std::unique_ptr<ProxyService> service_; |
| 3566 }; |
| 3567 |
| 3568 TEST_F(ProxyServiceTest, SanitizeUrlDefaultsToSafe) { |
| 3569 SanitizeUrlHelper helper; |
| 3570 |
| 3571 // Without changing the URL sanitization policy, the default should be to |
| 3572 // strip https:// URLs. |
| 3573 EXPECT_EQ(GURL("https://example.com/"), |
| 3574 helper.SanitizeUrl( |
| 3575 GURL("https://foo:bar@example.com/foo/bar/baz?hello#sigh"))); |
| 3576 } |
| 3577 |
| 3578 // Tests URL sanitization with input URLs that have a // non-cryptographic |
| 3579 // scheme (i.e. http://). The sanitized result is consistent regardless of the |
| 3580 // stripping mode selected. |
| 3581 TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptNonCryptographic) { |
| 3582 const struct { |
| 3583 const char* raw_url; |
| 3584 const char* sanitized_url; |
| 3585 } kTests[] = { |
| 3586 // Embedded identity is stripped. |
| 3587 { |
| 3588 "http://foo:bar@example.com/", "http://example.com/", |
| 3589 }, |
| 3590 { |
| 3591 "ftp://foo:bar@example.com/", "ftp://example.com/", |
| 3592 }, |
| 3593 { |
| 3594 "ftp://example.com/some/path/here", |
| 3595 "ftp://example.com/some/path/here", |
| 3596 }, |
| 3597 // Reference fragment is stripped. |
| 3598 { |
| 3599 "http://example.com/blah#hello", "http://example.com/blah", |
| 3600 }, |
| 3601 // Query parameters are NOT stripped. |
| 3602 { |
| 3603 "http://example.com/foo/bar/baz?hello", |
| 3604 "http://example.com/foo/bar/baz?hello", |
| 3605 }, |
| 3606 // Fragment is stripped, but path and query are left intact. |
| 3607 { |
| 3608 "http://foo:bar@example.com/foo/bar/baz?hello#sigh", |
| 3609 "http://example.com/foo/bar/baz?hello", |
| 3610 }, |
| 3611 // Port numbers are not affected. |
| 3612 { |
| 3613 "http://example.com:88/hi", "http://example.com:88/hi", |
| 3614 }, |
| 3615 }; |
| 3616 |
| 3617 SanitizeUrlHelper helper; |
| 3618 |
| 3619 for (const auto& test : kTests) { |
| 3620 // The result of SanitizeUrlForPacScript() is the same regardless of the |
| 3621 // second parameter (sanitization mode), since the input URLs do not use a |
| 3622 // cryptographic scheme. |
| 3623 GURL raw_url(test.raw_url); |
| 3624 ASSERT_TRUE(raw_url.is_valid()); |
| 3625 EXPECT_FALSE(raw_url.SchemeIsCryptographic()); |
| 3626 |
| 3627 EXPECT_EQ( |
| 3628 GURL(test.sanitized_url), |
| 3629 helper.SanitizeUrl(raw_url, ProxyService::SanitizeUrlPolicy::UNSAFE)); |
| 3630 |
| 3631 EXPECT_EQ( |
| 3632 GURL(test.sanitized_url), |
| 3633 helper.SanitizeUrl(raw_url, ProxyService::SanitizeUrlPolicy::SAFE)); |
| 3634 } |
| 3635 } |
| 3636 |
| 3637 // Tests URL sanitization using input URLs that have a cryptographic schemes |
| 3638 // (i.e. https://). The sanitized result differs depending on the sanitization |
| 3639 // mode chosen. |
| 3640 TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptCryptographic) { |
| 3641 const struct { |
| 3642 // Input URL. |
| 3643 const char* raw_url; |
| 3644 |
| 3645 // Output URL when stripping of cryptographic URLs is disabled. |
| 3646 const char* sanitized_url_unstripped; |
| 3647 |
| 3648 // Output URL when stripping of cryptographic URLs is enabled. |
| 3649 const char* sanitized_url; |
| 3650 } kTests[] = { |
| 3651 // Embedded identity is always stripped. |
| 3652 { |
| 3653 "https://foo:bar@example.com/", "https://example.com/", |
| 3654 "https://example.com/", |
| 3655 }, |
| 3656 // Fragments are always stripped, but stripping path is conditional on the |
| 3657 // mode. |
| 3658 { |
| 3659 "https://example.com/blah#hello", "https://example.com/blah", |
| 3660 "https://example.com/", |
| 3661 }, |
| 3662 // Stripping the query is conditional on the mode. |
| 3663 { |
| 3664 "https://example.com/?hello", "https://example.com/?hello", |
| 3665 "https://example.com/", |
| 3666 }, |
| 3667 // The embedded identity and fragment is always stripped, however path and |
| 3668 // query are conditional on the stripping mode. |
| 3669 { |
| 3670 "https://foo:bar@example.com/foo/bar/baz?hello#sigh", |
| 3671 "https://example.com/foo/bar/baz?hello", "https://example.com/", |
| 3672 }, |
| 3673 // The URL's port should not be stripped. |
| 3674 { |
| 3675 "https://example.com:88/hi", "https://example.com:88/hi", |
| 3676 "https://example.com:88/", |
| 3677 }, |
| 3678 // Try a wss:// URL, to make sure it also strips (is is also a |
| 3679 // cryptographic URL). |
| 3680 { |
| 3681 "wss://example.com:88/hi", "wss://example.com:88/hi", |
| 3682 "wss://example.com:88/", |
| 3683 }, |
| 3684 }; |
| 3685 |
| 3686 SanitizeUrlHelper helper; |
| 3687 |
| 3688 for (const auto& test : kTests) { |
| 3689 GURL raw_url(test.raw_url); |
| 3690 ASSERT_TRUE(raw_url.is_valid()); |
| 3691 EXPECT_TRUE(raw_url.SchemeIsCryptographic()); |
| 3692 |
| 3693 EXPECT_EQ( |
| 3694 GURL(test.sanitized_url_unstripped), |
| 3695 helper.SanitizeUrl(raw_url, ProxyService::SanitizeUrlPolicy::UNSAFE)); |
| 3696 |
| 3697 EXPECT_EQ( |
| 3698 GURL(test.sanitized_url), |
| 3699 helper.SanitizeUrl(raw_url, ProxyService::SanitizeUrlPolicy::SAFE)); |
| 3700 } |
| 3701 } |
| 3702 |
3483 } // namespace net | 3703 } // namespace net |
OLD | NEW |