OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <math.h> // ceil | 5 #include <math.h> // ceil |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 MockClientSocketFactory socket_factory; | 58 MockClientSocketFactory socket_factory; |
59 scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; | 59 scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; |
60 }; | 60 }; |
61 | 61 |
62 ProxyService* CreateFixedProxyService(const std::string& proxy) { | 62 ProxyService* CreateFixedProxyService(const std::string& proxy) { |
63 net::ProxyConfig proxy_config; | 63 net::ProxyConfig proxy_config; |
64 proxy_config.proxy_rules().ParseFromString(proxy); | 64 proxy_config.proxy_rules().ParseFromString(proxy); |
65 return ProxyService::CreateFixed(proxy_config); | 65 return ProxyService::CreateFixed(proxy_config); |
66 } | 66 } |
67 | 67 |
68 | |
69 HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { | 68 HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { |
70 return new HttpNetworkSession(NULL, | 69 return new HttpNetworkSession(NULL, |
71 session_deps->host_resolver, | 70 session_deps->host_resolver, |
72 session_deps->proxy_service, | 71 session_deps->proxy_service, |
73 &session_deps->socket_factory, | 72 &session_deps->socket_factory, |
74 session_deps->ssl_config_service, | 73 session_deps->ssl_config_service, |
75 session_deps->http_auth_handler_factory.get()); | 74 session_deps->http_auth_handler_factory.get()); |
76 } | 75 } |
77 | 76 |
78 class HttpNetworkTransactionTest : public PlatformTest { | 77 class HttpNetworkTransactionTest : public PlatformTest { |
(...skipping 4593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4672 const HttpResponseInfo* response = trans->GetResponseInfo(); | 4671 const HttpResponseInfo* response = trans->GetResponseInfo(); |
4673 ASSERT_TRUE(response != NULL); | 4672 ASSERT_TRUE(response != NULL); |
4674 ASSERT_TRUE(response->headers != NULL); | 4673 ASSERT_TRUE(response->headers != NULL); |
4675 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); | 4674 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
4676 | 4675 |
4677 std::string response_data; | 4676 std::string response_data; |
4678 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); | 4677 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); |
4679 EXPECT_EQ("hello world", response_data); | 4678 EXPECT_EQ("hello world", response_data); |
4680 } | 4679 } |
4681 | 4680 |
| 4681 // MockAuthHandlerCanonical is used by the ResolveCanonicalName |
| 4682 // HttpNetworkTransaction unit test below. Callers set up expectations for |
| 4683 // whether the canonical name needs to be resolved. |
| 4684 class MockAuthHandlerCanonical : public HttpAuthHandler { |
| 4685 public: |
| 4686 enum Resolve { |
| 4687 RESOLVE_INIT, |
| 4688 RESOLVE_SKIP, |
| 4689 RESOLVE_SYNC, |
| 4690 RESOLVE_ASYNC, |
| 4691 RESOLVE_TESTED, |
| 4692 }; |
| 4693 |
| 4694 MockAuthHandlerCanonical() : resolve_(RESOLVE_INIT), user_callback_(NULL) {} |
| 4695 virtual ~MockAuthHandlerCanonical() {} |
| 4696 |
| 4697 void SetResolveExpectation(Resolve resolve) { |
| 4698 EXPECT_EQ(RESOLVE_INIT, resolve_); |
| 4699 resolve_ = resolve; |
| 4700 } |
| 4701 |
| 4702 void ResetResolveExpectation() { |
| 4703 EXPECT_EQ(RESOLVE_TESTED, resolve_); |
| 4704 resolve_ = RESOLVE_INIT; |
| 4705 } |
| 4706 |
| 4707 virtual bool NeedsCanonicalName() { |
| 4708 switch (resolve_) { |
| 4709 case RESOLVE_SYNC: |
| 4710 case RESOLVE_ASYNC: |
| 4711 return true; |
| 4712 case RESOLVE_SKIP: |
| 4713 resolve_ = RESOLVE_TESTED; |
| 4714 return false; |
| 4715 default: |
| 4716 NOTREACHED(); |
| 4717 return false; |
| 4718 } |
| 4719 } |
| 4720 |
| 4721 virtual int ResolveCanonicalName(HostResolver* host_resolver, |
| 4722 CompletionCallback* callback, |
| 4723 const BoundNetLog& net_log) { |
| 4724 EXPECT_NE(RESOLVE_TESTED, resolve_); |
| 4725 int rv = OK; |
| 4726 switch (resolve_) { |
| 4727 case RESOLVE_SYNC: |
| 4728 resolve_ = RESOLVE_TESTED; |
| 4729 break; |
| 4730 case RESOLVE_ASYNC: |
| 4731 EXPECT_TRUE(user_callback_ == NULL); |
| 4732 rv = ERR_IO_PENDING; |
| 4733 user_callback_ = callback; |
| 4734 MessageLoop::current()->PostTask( |
| 4735 FROM_HERE, |
| 4736 NewRunnableMethod( |
| 4737 this, &MockAuthHandlerCanonical::OnResolveCanonicalName)); |
| 4738 break; |
| 4739 default: |
| 4740 NOTREACHED(); |
| 4741 break; |
| 4742 } |
| 4743 return rv; |
| 4744 } |
| 4745 |
| 4746 void OnResolveCanonicalName() { |
| 4747 EXPECT_EQ(RESOLVE_ASYNC, resolve_); |
| 4748 EXPECT_TRUE(user_callback_ != NULL); |
| 4749 resolve_ = RESOLVE_TESTED; |
| 4750 CompletionCallback* callback = user_callback_; |
| 4751 user_callback_ = NULL; |
| 4752 callback->Run(OK); |
| 4753 } |
| 4754 |
| 4755 virtual bool Init(HttpAuth::ChallengeTokenizer* challenge) { |
| 4756 scheme_ = "mock"; |
| 4757 score_ = 1; |
| 4758 properties_ = 0; |
| 4759 return true; |
| 4760 } |
| 4761 |
| 4762 virtual int GenerateAuthToken(const std::wstring& username, |
| 4763 const std::wstring& password, |
| 4764 const HttpRequestInfo* request, |
| 4765 const ProxyInfo* proxy, |
| 4766 std::string* auth_token) { |
| 4767 auth_token->assign("Mock AUTH myserver.example.com"); |
| 4768 return OK; |
| 4769 } |
| 4770 |
| 4771 virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request, |
| 4772 const ProxyInfo* proxy, |
| 4773 std::string* auth_token) { |
| 4774 auth_token->assign("Mock DEFAULT_AUTH myserver.example.com"); |
| 4775 return OK; |
| 4776 } |
| 4777 |
| 4778 // The Factory class simply returns the same handler each time |
| 4779 // CreateAuthHandler is called. |
| 4780 class Factory : public HttpAuthHandlerFactory { |
| 4781 public: |
| 4782 Factory() {} |
| 4783 virtual ~Factory() {} |
| 4784 |
| 4785 void set_mock_handler(MockAuthHandlerCanonical* mock_handler) { |
| 4786 mock_handler_ = mock_handler; |
| 4787 } |
| 4788 MockAuthHandlerCanonical* mock_handler() const { |
| 4789 return mock_handler_.get(); |
| 4790 } |
| 4791 |
| 4792 virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge, |
| 4793 HttpAuth::Target target, |
| 4794 const GURL& origin, |
| 4795 scoped_refptr<HttpAuthHandler>* handler) { |
| 4796 *handler = mock_handler_; |
| 4797 return OK; |
| 4798 } |
| 4799 |
| 4800 private: |
| 4801 scoped_refptr<MockAuthHandlerCanonical> mock_handler_; |
| 4802 }; |
| 4803 |
| 4804 private: |
| 4805 Resolve resolve_; |
| 4806 CompletionCallback* user_callback_; |
| 4807 }; |
| 4808 |
| 4809 // Tests that ResolveCanonicalName is handled correctly by the |
| 4810 // HttpNetworkTransaction. |
| 4811 TEST_F(HttpNetworkTransactionTest, ResolveCanonicalName) { |
| 4812 SessionDependencies session_deps; |
| 4813 scoped_refptr<MockAuthHandlerCanonical> auth_handler( |
| 4814 new MockAuthHandlerCanonical()); |
| 4815 auth_handler->Init(NULL); |
| 4816 MockAuthHandlerCanonical::Factory* auth_factory( |
| 4817 new MockAuthHandlerCanonical::Factory()); |
| 4818 auth_factory->set_mock_handler(auth_handler); |
| 4819 session_deps.http_auth_handler_factory.reset(auth_factory); |
| 4820 |
| 4821 for (int i = 0; i < 2; ++i) { |
| 4822 scoped_ptr<HttpTransaction> trans( |
| 4823 new HttpNetworkTransaction(CreateSession(&session_deps))); |
| 4824 |
| 4825 // Set up expectations for this pass of the test. Many of the EXPECT calls |
| 4826 // are contained inside the MockAuthHandlerCanonical codebase in response to |
| 4827 // the expectations. |
| 4828 MockAuthHandlerCanonical::Resolve resolve = (i == 0) ? |
| 4829 MockAuthHandlerCanonical::RESOLVE_SYNC : |
| 4830 MockAuthHandlerCanonical::RESOLVE_ASYNC; |
| 4831 auth_handler->SetResolveExpectation(resolve); |
| 4832 HttpRequestInfo request; |
| 4833 request.method = "GET"; |
| 4834 request.url = GURL("http://myserver/"); |
| 4835 request.load_flags = 0; |
| 4836 |
| 4837 MockWrite data_writes1[] = { |
| 4838 MockWrite("GET / HTTP/1.1\r\n" |
| 4839 "Host: myserver\r\n" |
| 4840 "Connection: keep-alive\r\n\r\n"), |
| 4841 }; |
| 4842 |
| 4843 MockRead data_reads1[] = { |
| 4844 MockRead("HTTP/1.1 401 Unauthorized\r\n"), |
| 4845 MockRead("WWW-Authenticate: Mock myserver.example.com\r\n"), |
| 4846 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 4847 MockRead("Content-Length: 14\r\n\r\n"), |
| 4848 MockRead("Unauthorized\r\n"), |
| 4849 }; |
| 4850 |
| 4851 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 4852 data_writes1, arraysize(data_writes1)); |
| 4853 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 4854 |
| 4855 TestCompletionCallback callback1; |
| 4856 |
| 4857 int rv = trans->Start(&request, &callback1, NULL); |
| 4858 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 4859 |
| 4860 rv = callback1.WaitForResult(); |
| 4861 EXPECT_EQ(OK, rv); |
| 4862 |
| 4863 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 4864 EXPECT_FALSE(response == NULL); |
| 4865 |
| 4866 // The password prompt is set after the canonical name is resolved. |
| 4867 // If it isn't present or is incorrect, it indicates that the scheme |
| 4868 // did not complete correctly. |
| 4869 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 4870 |
| 4871 EXPECT_EQ(L"myserver:80", response->auth_challenge->host_and_port); |
| 4872 EXPECT_EQ(L"", response->auth_challenge->realm); |
| 4873 EXPECT_EQ(L"mock", response->auth_challenge->scheme); |
| 4874 auth_handler->ResetResolveExpectation(); |
| 4875 } |
| 4876 } |
| 4877 |
4682 } // namespace net | 4878 } // namespace net |
OLD | NEW |