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_TRUE(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)); |
| 214 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), |
| 215 data_writes, arraysize(data_writes)); |
| 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 ASSERT_TRUE(retry_info.find("bad:8080") != retry_info.end()); |
| 245 ASSERT_TRUE(retry_info.find("alsobad:8080") != retry_info.end()); |
| 246 } |
| 247 |
| 248 TEST_F(HttpNetworkLayerTest, ProxyBypassIgnoredOnDirectConnection) { |
| 249 // Verify that a Connection: proxy-bypass header is ignored when returned |
| 250 // from a directly connected origin server. |
| 251 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult("DIRECT")); |
| 252 |
| 253 MockRead data_reads[] = { |
| 254 MockRead("HTTP/1.1 200 OK\r\n" |
| 255 "Connection: proxy-bypass\r\n\r\n"), |
| 256 MockRead("Bypass message"), |
| 257 MockRead(SYNCHRONOUS, OK), |
| 258 }; |
| 259 MockWrite data_writes[] = { |
| 260 MockWrite("GET / HTTP/1.1\r\n" |
| 261 "Host: www.google.com\r\n" |
| 262 "Connection: keep-alive\r\n\r\n"), |
| 263 }; |
| 264 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), |
| 265 data_writes, arraysize(data_writes)); |
| 266 mock_socket_factory_.AddSocketDataProvider(&data1); |
| 267 TestCompletionCallback callback; |
| 268 |
| 269 HttpRequestInfo request_info; |
| 270 request_info.url = GURL("http://www.google.com/"); |
| 271 request_info.method = "GET"; |
| 272 request_info.load_flags = LOAD_NORMAL; |
| 273 |
| 274 scoped_ptr<HttpTransaction> trans; |
| 275 int rv = factory_->CreateTransaction(&trans, NULL); |
| 276 EXPECT_EQ(OK, rv); |
| 277 |
| 278 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); |
| 279 if (rv == ERR_IO_PENDING) |
| 280 rv = callback.WaitForResult(); |
| 281 ASSERT_EQ(OK, rv); |
| 282 |
| 283 // We should have read the original page data. |
| 284 std::string contents; |
| 285 rv = ReadTransaction(trans.get(), &contents); |
| 286 EXPECT_EQ(OK, rv); |
| 287 EXPECT_EQ("Bypass message", contents); |
| 288 |
| 289 // We should have no entries in our bad proxy list. |
| 290 ASSERT_EQ(0u, proxy_service_->proxy_retry_info().size()); |
| 291 } |
| 292 |
118 } // namespace | 293 } // namespace |
119 | 294 |
120 } // namespace net | 295 } // namespace net |
OLD | NEW |