Chromium Code Reviews| 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/http/http_network_layer.h" | 5 #include "net/http/http_network_layer.h" |
| 6 | 6 |
| 7 #include "net/base/mock_cert_verifier.h" | 7 #include "net/base/mock_cert_verifier.h" |
| 8 #include "net/base/mock_host_resolver.h" | 8 #include "net/base/mock_host_resolver.h" |
| 9 #include "net/base/net_log.h" | 9 #include "net/base/net_log.h" |
| 10 #include "net/base/ssl_config_service_defaults.h" | 10 #include "net/base/ssl_config_service_defaults.h" |
| 11 #include "net/http/http_network_session.h" | 11 #include "net/http/http_network_session.h" |
| 12 #include "net/http/http_server_properties_impl.h" | 12 #include "net/http/http_server_properties_impl.h" |
| 13 #include "net/http/http_transaction_unittest.h" | 13 #include "net/http/http_transaction_unittest.h" |
| 14 #include "net/proxy/proxy_service.h" | 14 #include "net/proxy/proxy_service.h" |
| 15 #include "net/socket/socket_test_util.h" | 15 #include "net/socket/socket_test_util.h" |
| 16 #include "net/spdy/spdy_session_pool.h" | 16 #include "net/spdy/spdy_session_pool.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
| 19 | 19 |
| 20 namespace net { | 20 namespace net { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 class HttpNetworkLayerTest : public PlatformTest { | 24 class HttpNetworkLayerTest : public PlatformTest { |
| 25 protected: | 25 protected: |
| 26 HttpNetworkLayerTest() | 26 HttpNetworkLayerTest() : ssl_config_service_(new SSLConfigServiceDefaults) {} |
| 27 : cert_verifier_(new MockCertVerifier), | 27 |
| 28 proxy_service_(ProxyService::CreateDirect()), | 28 virtual void SetUp() { |
| 29 ssl_config_service_(new SSLConfigServiceDefaults) { | 29 ConfigureTestDependencies(ProxyService::CreateDirect()); |
| 30 } | |
| 31 | |
| 32 void ConfigureTestDependencies(ProxyService* proxy_service) { | |
| 33 cert_verifier_.reset(new MockCertVerifier); | |
| 34 proxy_service_.reset(proxy_service); | |
| 30 HttpNetworkSession::Params session_params; | 35 HttpNetworkSession::Params session_params; |
| 31 session_params.client_socket_factory = &mock_socket_factory_; | 36 session_params.client_socket_factory = &mock_socket_factory_; |
| 32 session_params.host_resolver = &host_resolver_; | 37 session_params.host_resolver = &host_resolver_; |
| 33 session_params.cert_verifier = cert_verifier_.get(); | 38 session_params.cert_verifier = cert_verifier_.get(); |
| 34 session_params.proxy_service = proxy_service_.get(); | 39 session_params.proxy_service = proxy_service_.get(); |
| 35 session_params.ssl_config_service = ssl_config_service_; | 40 session_params.ssl_config_service = ssl_config_service_; |
| 36 session_params.http_server_properties = &http_server_properties_; | 41 session_params.http_server_properties = &http_server_properties_; |
| 37 network_session_ = new HttpNetworkSession(session_params); | 42 network_session_ = new HttpNetworkSession(session_params); |
| 38 factory_.reset(new HttpNetworkLayer(network_session_)); | 43 factory_.reset(new HttpNetworkLayer(network_session_)); |
| 39 } | 44 } |
| 40 | 45 |
| 41 MockClientSocketFactory mock_socket_factory_; | 46 MockClientSocketFactory mock_socket_factory_; |
| 42 MockHostResolver host_resolver_; | 47 MockHostResolver host_resolver_; |
| 43 scoped_ptr<CertVerifier> cert_verifier_; | 48 scoped_ptr<CertVerifier> cert_verifier_; |
| 44 const scoped_ptr<ProxyService> proxy_service_; | 49 scoped_ptr<ProxyService> proxy_service_; |
| 45 const scoped_refptr<SSLConfigService> ssl_config_service_; | 50 const scoped_refptr<SSLConfigService> ssl_config_service_; |
| 46 scoped_refptr<HttpNetworkSession> network_session_; | 51 scoped_refptr<HttpNetworkSession> network_session_; |
| 47 scoped_ptr<HttpNetworkLayer> factory_; | 52 scoped_ptr<HttpNetworkLayer> factory_; |
| 48 HttpServerPropertiesImpl http_server_properties_; | 53 HttpServerPropertiesImpl http_server_properties_; |
| 49 }; | 54 }; |
| 50 | 55 |
| 51 TEST_F(HttpNetworkLayerTest, CreateAndDestroy) { | 56 TEST_F(HttpNetworkLayerTest, CreateAndDestroy) { |
| 52 scoped_ptr<HttpTransaction> trans; | 57 scoped_ptr<HttpTransaction> trans; |
| 53 int rv = factory_->CreateTransaction(&trans, NULL); | 58 int rv = factory_->CreateTransaction(&trans, NULL); |
| 54 EXPECT_EQ(OK, rv); | 59 EXPECT_EQ(OK, rv); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 if (rv == ERR_IO_PENDING) | 113 if (rv == ERR_IO_PENDING) |
| 109 rv = callback.WaitForResult(); | 114 rv = callback.WaitForResult(); |
| 110 ASSERT_EQ(OK, rv); | 115 ASSERT_EQ(OK, rv); |
| 111 | 116 |
| 112 std::string contents; | 117 std::string contents; |
| 113 rv = ReadTransaction(trans.get(), &contents); | 118 rv = ReadTransaction(trans.get(), &contents); |
| 114 EXPECT_EQ(OK, rv); | 119 EXPECT_EQ(OK, rv); |
| 115 EXPECT_EQ("hello world", contents); | 120 EXPECT_EQ("hello world", contents); |
| 116 } | 121 } |
| 117 | 122 |
| 123 TEST_F(HttpNetworkLayerTest, ServerFallback) { | |
| 124 // Verify that a Connection: Proxy-Bypass header induces proxy fallback to | |
| 125 // a second proxy, if configured. | |
| 126 | |
| 127 // To configure this test, we need to wire up a custom proxy service to use | |
| 128 // a pair of proxies. We'll induce fallback via the first and return | |
| 129 // the expected data via the second. | |
| 130 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( | |
| 131 "PROXY bad:8080; PROXY good:8080")); | |
| 132 | |
| 133 MockRead data_reads[] = { | |
| 134 MockRead("HTTP/1.1 200 OK\r\n" | |
| 135 "Connection: proxy-bypass\r\n\r\n"), | |
| 136 MockRead("Bypass message"), | |
| 137 MockRead(SYNCHRONOUS, OK), | |
| 138 }; | |
| 139 MockWrite data_writes[] = { | |
| 140 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | |
| 141 "Host: www.google.com\r\n" | |
| 142 "Proxy-Connection: keep-alive\r\n\r\n"), | |
| 143 }; | |
| 144 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), | |
| 145 data_writes, arraysize(data_writes)); | |
| 146 mock_socket_factory_.AddSocketDataProvider(&data1); | |
| 147 | |
| 148 // Second data provider returns the expected content. | |
| 149 MockRead data_reads2[] = { | |
| 150 MockRead("HTTP/1.0 200 OK\r\n" | |
| 151 "Server: not-proxy\r\n\r\n"), | |
| 152 MockRead("content"), | |
| 153 MockRead(SYNCHRONOUS, OK), | |
| 154 }; | |
| 155 MockWrite data_writes2[] = { | |
| 156 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | |
| 157 "Host: www.google.com\r\n" | |
| 158 "Proxy-Connection: keep-alive\r\n\r\n"), | |
| 159 }; | |
| 160 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | |
| 161 data_writes2, arraysize(data_writes2)); | |
| 162 mock_socket_factory_.AddSocketDataProvider(&data2); | |
| 163 | |
| 164 TestCompletionCallback callback; | |
| 165 | |
| 166 HttpRequestInfo request_info; | |
| 167 request_info.url = GURL("http://www.google.com/"); | |
| 168 request_info.method = "GET"; | |
| 169 request_info.load_flags = LOAD_NORMAL; | |
| 170 | |
| 171 scoped_ptr<HttpTransaction> trans; | |
| 172 int rv = factory_->CreateTransaction(&trans, NULL); | |
| 173 EXPECT_EQ(OK, rv); | |
| 174 | |
| 175 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); | |
| 176 if (rv == ERR_IO_PENDING) | |
| 177 rv = callback.WaitForResult(); | |
| 178 ASSERT_EQ(OK, rv); | |
| 179 | |
| 180 std::string contents; | |
| 181 rv = ReadTransaction(trans.get(), &contents); | |
| 182 EXPECT_EQ(OK, rv); | |
| 183 | |
| 184 // We should obtain content from the second socket provider write | |
| 185 // corresponding to the fallback proxy. | |
| 186 EXPECT_EQ("content", contents); | |
| 187 // We also have a server header here that isn't set by the proxy. | |
| 188 EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue( | |
| 189 "server", "not-proxy")); | |
| 190 // We should also observe the bad proxy in the retry list. | |
| 191 ASSERT_EQ(1u, proxy_service_->proxy_retry_info().size()); | |
| 192 EXPECT_EQ("bad:8080", (*proxy_service_->proxy_retry_info().begin()).first); | |
| 193 } | |
| 194 | |
| 195 TEST_F(HttpNetworkLayerTest, ServerFallbackDoesntLoop) { | |
| 196 // Verify that a Connection: Proxy-Bypass header will display the original | |
| 197 // proxy's error page content if a fallback option is not configured. | |
| 198 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( | |
| 199 "PROXY bad:8080; PROXY alsobad:8080")); | |
| 200 | |
| 201 MockRead data_reads[] = { | |
| 202 MockRead("HTTP/1.1 200 OK\r\n" | |
| 203 "Connection: proxy-bypass\r\n\r\n"), | |
| 204 MockRead("Bypass message"), | |
| 205 MockRead(SYNCHRONOUS, OK), | |
| 206 }; | |
| 207 MockWrite data_writes[] = { | |
| 208 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | |
| 209 "Host: www.google.com\r\n" | |
| 210 "Proxy-Connection: keep-alive\r\n\r\n"), | |
| 211 }; | |
| 212 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), | |
| 213 data_writes, arraysize(data_writes)); | |
|
eroman
2012/10/12 18:30:58
nit: indent by 1 more
Michael Piatek
2012/10/15 17:10:16
Done.
| |
| 214 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), | |
| 215 data_writes, arraysize(data_writes)); | |
|
eroman
2012/10/12 18:30:58
same
Michael Piatek
2012/10/15 17:10:16
Done.
| |
| 216 mock_socket_factory_.AddSocketDataProvider(&data1); | |
| 217 mock_socket_factory_.AddSocketDataProvider(&data2); | |
| 218 | |
| 219 TestCompletionCallback callback; | |
| 220 | |
| 221 HttpRequestInfo request_info; | |
| 222 request_info.url = GURL("http://www.google.com/"); | |
| 223 request_info.method = "GET"; | |
| 224 request_info.load_flags = LOAD_NORMAL; | |
| 225 | |
| 226 scoped_ptr<HttpTransaction> trans; | |
| 227 int rv = factory_->CreateTransaction(&trans, NULL); | |
| 228 EXPECT_EQ(OK, rv); | |
| 229 | |
| 230 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); | |
| 231 if (rv == ERR_IO_PENDING) | |
| 232 rv = callback.WaitForResult(); | |
| 233 ASSERT_EQ(OK, rv); | |
| 234 | |
| 235 std::string contents; | |
| 236 rv = ReadTransaction(trans.get(), &contents); | |
| 237 EXPECT_EQ(OK, rv); | |
| 238 EXPECT_EQ("Bypass message", contents); | |
| 239 | |
| 240 // Despite not falling back to anything, we should still observe the proxies | |
| 241 // in the bad proxies list. | |
| 242 const ProxyRetryInfoMap& retry_info = proxy_service_->proxy_retry_info(); | |
| 243 ASSERT_EQ(2u, retry_info.size()); | |
| 244 EXPECT_NE(retry_info.find("bad:8080"), retry_info.end()); | |
| 245 EXPECT_NE(retry_info.find("alsobad:8080"), retry_info.end()); | |
| 246 } | |
| 247 | |
| 118 } // namespace | 248 } // namespace |
| 119 | 249 |
| 120 } // namespace net | 250 } // namespace net |
| OLD | NEW |