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 "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "net/base/net_log.h" | 8 #include "net/base/net_log.h" |
| 9 #include "net/cert/mock_cert_verifier.h" | 9 #include "net/cert/mock_cert_verifier.h" |
| 10 #include "net/dns/mock_host_resolver.h" | 10 #include "net/dns/mock_host_resolver.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 network_session_ = new HttpNetworkSession(session_params); | 47 network_session_ = new HttpNetworkSession(session_params); |
| 48 factory_.reset(new HttpNetworkLayer(network_session_.get())); | 48 factory_.reset(new HttpNetworkLayer(network_session_.get())); |
| 49 } | 49 } |
| 50 | 50 |
| 51 #if defined (SPDY_PROXY_AUTH_ORIGIN) | 51 #if defined (SPDY_PROXY_AUTH_ORIGIN) |
| 52 std::string GetChromeProxy() { | 52 std::string GetChromeProxy() { |
| 53 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString(); | 53 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString(); |
| 54 } | 54 } |
| 55 #endif | 55 #endif |
| 56 | 56 |
| 57 void ExecuteRequestExpectingContentAndHeader(const std::string& content, | 57 void ExecuteRequestExpectingContentAndHeader(const std::string& method, |
| 58 const std::string& content, | |
| 58 const std::string& header, | 59 const std::string& header, |
| 59 const std::string& value) { | 60 const std::string& value) { |
| 60 TestCompletionCallback callback; | 61 TestCompletionCallback callback; |
| 61 | 62 |
| 62 HttpRequestInfo request_info; | 63 HttpRequestInfo request_info; |
| 63 request_info.url = GURL("http://www.google.com/"); | 64 request_info.url = GURL("http://www.google.com/"); |
| 64 request_info.method = "GET"; | 65 request_info.method = method; |
| 65 request_info.load_flags = LOAD_NORMAL; | 66 request_info.load_flags = LOAD_NORMAL; |
| 66 | 67 |
| 67 scoped_ptr<HttpTransaction> trans; | 68 scoped_ptr<HttpTransaction> trans; |
| 68 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL); | 69 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL); |
| 69 EXPECT_EQ(OK, rv); | 70 EXPECT_EQ(OK, rv); |
| 70 | 71 |
| 71 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); | 72 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); |
| 72 if (rv == ERR_IO_PENDING) | 73 if (rv == ERR_IO_PENDING) |
| 73 rv = callback.WaitForResult(); | 74 rv = callback.WaitForResult(); |
| 74 ASSERT_EQ(OK, rv); | 75 ASSERT_EQ(OK, rv); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 MockRead("Bypass message"), | 108 MockRead("Bypass message"), |
| 108 MockRead(SYNCHRONOUS, OK), | 109 MockRead(SYNCHRONOUS, OK), |
| 109 }; | 110 }; |
| 110 TestProxyFallbackWithMockReads(bad_proxy, data_reads, | 111 TestProxyFallbackWithMockReads(bad_proxy, data_reads, |
| 111 arraysize(data_reads)); | 112 arraysize(data_reads)); |
| 112 } | 113 } |
| 113 | 114 |
| 114 void TestProxyFallbackWithMockReads(const std::string& bad_proxy, | 115 void TestProxyFallbackWithMockReads(const std::string& bad_proxy, |
| 115 MockRead data_reads[], | 116 MockRead data_reads[], |
| 116 int data_reads_size) { | 117 int data_reads_size) { |
| 118 TestProxyFallbackByMethodWithMockReads(bad_proxy, data_reads, | |
| 119 data_reads_size, | |
| 120 "GET", "content", true); | |
| 121 | |
| 122 } | |
| 123 | |
| 124 void TestProxyFallbackByMethodWithMockReads(const std::string& bad_proxy, | |
| 125 MockRead data_reads[], | |
| 126 int data_reads_size, | |
| 127 std::string method, | |
| 128 std::string content, | |
| 129 bool retry_expected) { | |
| 130 | |
| 131 std::string trailer = | |
| 132 (method == "HEAD" || method == "PUT" || method == "POST") ? | |
| 133 "Content-Length: 0\r\n\r\n" : "\r\n"; | |
| 134 std::string request = | |
| 135 base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n" | |
| 136 "Host: www.google.com\r\n" | |
| 137 "Proxy-Connection: keep-alive\r\n" | |
| 138 "%s", method.c_str(), trailer.c_str()); | |
| 139 | |
| 117 MockWrite data_writes[] = { | 140 MockWrite data_writes[] = { |
| 118 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | 141 MockWrite(request.c_str()), |
| 119 "Host: www.google.com\r\n" | |
| 120 "Proxy-Connection: keep-alive\r\n\r\n"), | |
| 121 }; | 142 }; |
| 122 | 143 |
| 123 StaticSocketDataProvider data1(data_reads, data_reads_size, | 144 StaticSocketDataProvider data1(data_reads, data_reads_size, |
| 124 data_writes, arraysize(data_writes)); | 145 data_writes, arraysize(data_writes)); |
| 125 mock_socket_factory_.AddSocketDataProvider(&data1); | 146 mock_socket_factory_.AddSocketDataProvider(&data1); |
| 126 | 147 |
| 127 // Second data provider returns the expected content. | 148 // Second data provider returns the expected content. |
| 128 MockRead data_reads2[] = { | 149 MockRead data_reads2[3]; |
| 129 MockRead("HTTP/1.0 200 OK\r\n" | 150 size_t data_reads2_index = 0; |
| 130 "Server: not-proxy\r\n\r\n"), | 151 data_reads2[data_reads2_index++] = MockRead("HTTP/1.0 200 OK\r\n" |
| 131 MockRead("content"), | 152 "Server: not-proxy\r\n\r\n"); |
| 132 MockRead(SYNCHRONOUS, OK), | 153 if (!content.empty()) |
| 154 data_reads2[data_reads2_index++] = MockRead(content.c_str()); | |
| 155 data_reads2[data_reads2_index++] = MockRead(SYNCHRONOUS, OK); | |
| 156 | |
| 157 | |
| 158 MockWrite data_writes2[] = { | |
| 159 MockWrite(request.c_str()), | |
| 133 }; | 160 }; |
| 134 MockWrite data_writes2[] = { | 161 StaticSocketDataProvider data2(data_reads2, data_reads2_index, |
| 135 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | |
| 136 "Host: www.google.com\r\n" | |
| 137 "Proxy-Connection: keep-alive\r\n\r\n"), | |
| 138 }; | |
| 139 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | |
| 140 data_writes2, arraysize(data_writes2)); | 162 data_writes2, arraysize(data_writes2)); |
| 141 mock_socket_factory_.AddSocketDataProvider(&data2); | 163 mock_socket_factory_.AddSocketDataProvider(&data2); |
| 142 | 164 |
| 143 // Expect that we get "content" and not "Bypass message", and that there's | 165 // Expect that we get "content" and not "Bypass message", and that there's |
| 144 // a "not-proxy" "Server:" header in the final response. | 166 // a "not-proxy" "Server:" header in the final response. |
| 145 ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy"); | 167 if (retry_expected) { |
| 168 ExecuteRequestExpectingContentAndHeader(method, content, | |
| 169 "server", "not-proxy"); | |
| 170 } else { | |
| 171 ExecuteRequestExpectingContentAndHeader(method, "Bypass message", "", ""); | |
| 172 } | |
| 146 | 173 |
| 147 // We should also observe the bad proxy in the retry list. | 174 // We should also observe the bad proxy in the retry list. |
| 148 TestBadProxies(1u, bad_proxy, ""); | 175 TestBadProxies(1u, bad_proxy, ""); |
| 149 } | 176 } |
| 150 | 177 |
| 151 // Simulates a request through a proxy which returns a bypass, which is then | 178 // Simulates a request through a proxy which returns a bypass, which is then |
| 152 // retried through a direct connection to the origin site. | 179 // retried through a direct connection to the origin site. |
| 153 // Checks that the expected requests were issued, the expected content was | 180 // Checks that the expected requests were issued, the expected content was |
| 154 // received, and the proxy |bad_proxy| was marked as bad. | 181 // received, and the proxy |bad_proxy| was marked as bad. |
| 155 void TestProxyFallbackToDirect(const std::string& bad_proxy) { | 182 void TestProxyFallbackToDirect(const std::string& bad_proxy) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 179 MockWrite("GET / HTTP/1.1\r\n" | 206 MockWrite("GET / HTTP/1.1\r\n" |
| 180 "Host: www.google.com\r\n" | 207 "Host: www.google.com\r\n" |
| 181 "Connection: keep-alive\r\n\r\n"), | 208 "Connection: keep-alive\r\n\r\n"), |
| 182 }; | 209 }; |
| 183 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | 210 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
| 184 data_writes2, arraysize(data_writes2)); | 211 data_writes2, arraysize(data_writes2)); |
| 185 mock_socket_factory_.AddSocketDataProvider(&data2); | 212 mock_socket_factory_.AddSocketDataProvider(&data2); |
| 186 | 213 |
| 187 // Expect that we get "content" and not "Bypass message", and that there's | 214 // Expect that we get "content" and not "Bypass message", and that there's |
| 188 // a "not-proxy" "Server:" header in the final response. | 215 // a "not-proxy" "Server:" header in the final response. |
| 189 ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy"); | 216 ExecuteRequestExpectingContentAndHeader("GET", "content", |
| 217 "server", "not-proxy"); | |
| 190 | 218 |
| 191 // We should also observe the bad proxy in the retry list. | 219 // We should also observe the bad proxy in the retry list. |
| 192 TestBadProxies(1u, bad_proxy, ""); | 220 TestBadProxies(1u, bad_proxy, ""); |
| 193 } | 221 } |
| 194 | 222 |
| 195 // Simulates a request through a proxy which returns a bypass, under a | 223 // Simulates a request through a proxy which returns a bypass, under a |
| 196 // configuration where there is no valid bypass. |proxy_count| proxies | 224 // configuration where there is no valid bypass. |proxy_count| proxies |
| 197 // are expected to be configured. | 225 // are expected to be configured. |
| 198 // Checks that the expected requests were issued, the bypass message was the | 226 // Checks that the expected requests were issued, the bypass message was the |
| 199 // final received content, and all proxies were marked as bad. | 227 // final received content, and all proxies were marked as bad. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 214 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), | 242 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), |
| 215 data_writes, arraysize(data_writes)); | 243 data_writes, arraysize(data_writes)); |
| 216 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), | 244 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), |
| 217 data_writes, arraysize(data_writes)); | 245 data_writes, arraysize(data_writes)); |
| 218 | 246 |
| 219 mock_socket_factory_.AddSocketDataProvider(&data1); | 247 mock_socket_factory_.AddSocketDataProvider(&data1); |
| 220 if (proxy_count > 1) | 248 if (proxy_count > 1) |
| 221 mock_socket_factory_.AddSocketDataProvider(&data2); | 249 mock_socket_factory_.AddSocketDataProvider(&data2); |
| 222 | 250 |
| 223 // Expect that we get "Bypass message", and not "content".. | 251 // Expect that we get "Bypass message", and not "content".. |
| 224 ExecuteRequestExpectingContentAndHeader("Bypass message", "", ""); | 252 ExecuteRequestExpectingContentAndHeader("GET", "Bypass message", "", ""); |
| 225 | 253 |
| 226 // We should also observe the bad proxy or proxies in the retry list. | 254 // We should also observe the bad proxy or proxies in the retry list. |
| 227 TestBadProxies(proxy_count, bad_proxy, bad_proxy2); | 255 TestBadProxies(proxy_count, bad_proxy, bad_proxy2); |
| 228 } | 256 } |
| 229 | 257 |
| 230 MockClientSocketFactory mock_socket_factory_; | 258 MockClientSocketFactory mock_socket_factory_; |
| 231 MockHostResolver host_resolver_; | 259 MockHostResolver host_resolver_; |
| 232 scoped_ptr<CertVerifier> cert_verifier_; | 260 scoped_ptr<CertVerifier> cert_verifier_; |
| 233 scoped_ptr<TransportSecurityState> transport_security_state_; | 261 scoped_ptr<TransportSecurityState> transport_security_state_; |
| 234 scoped_ptr<ProxyService> proxy_service_; | 262 scoped_ptr<ProxyService> proxy_service_; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 TestProxyFallback(bad_proxy); | 351 TestProxyFallback(bad_proxy); |
| 324 } | 352 } |
| 325 | 353 |
| 326 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) { | 354 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) { |
| 327 std::string bad_proxy = GetChromeProxy(); | 355 std::string bad_proxy = GetChromeProxy(); |
| 328 ConfigureTestDependencies( | 356 ConfigureTestDependencies( |
| 329 ProxyService::CreateFixed(bad_proxy +", good:8080")); | 357 ProxyService::CreateFixed(bad_proxy +", good:8080")); |
| 330 TestProxyFallback(bad_proxy); | 358 TestProxyFallback(bad_proxy); |
| 331 } | 359 } |
| 332 | 360 |
| 361 TEST_F(HttpNetworkLayerTest, BypassAndRetryIdempotentMethods) { | |
| 362 std::string bad_proxy = GetChromeProxy(); | |
| 363 const struct { | |
| 364 const char* method; | |
|
mef
2013/12/18 16:34:41
why is method const char* but content std::string?
bengr
2013/12/18 19:39:47
No good reason. Changed so both are std::string.
| |
| 365 std::string content; | |
| 366 bool expected_to_retry; | |
| 367 } tests[] = { | |
| 368 { | |
| 369 "GET", | |
| 370 "content", | |
| 371 true, | |
| 372 }, | |
| 373 { | |
| 374 "OPTIONS", | |
| 375 "content", | |
| 376 true, | |
| 377 }, | |
| 378 { | |
| 379 "HEAD", | |
| 380 "", | |
| 381 true, | |
| 382 }, | |
| 383 { | |
| 384 "PUT", | |
| 385 "", | |
| 386 true, | |
| 387 }, | |
| 388 { | |
| 389 "DELETE", | |
| 390 "content", | |
| 391 true, | |
| 392 }, | |
| 393 { | |
| 394 "TRACE", | |
| 395 "content", | |
| 396 true, | |
| 397 }, | |
| 398 { | |
| 399 "POST", | |
| 400 "Bypass message", | |
| 401 false, | |
| 402 }, | |
| 403 }; | |
| 404 | |
| 405 for (size_t i = 0; i < arraysize(tests); ++i) { | |
| 406 ConfigureTestDependencies( | |
| 407 ProxyService::CreateFixed(bad_proxy +", good:8080")); | |
| 408 MockRead data_reads[] = { | |
| 409 MockRead("HTTP/1.1 200 OK\r\n" | |
| 410 "Connection: proxy-bypass\r\n\r\n"), | |
| 411 MockRead("Bypass message"), | |
| 412 MockRead(SYNCHRONOUS, OK), | |
| 413 }; | |
| 414 TestProxyFallbackByMethodWithMockReads(bad_proxy, data_reads, | |
| 415 arraysize(data_reads), | |
| 416 tests[i].method, | |
| 417 tests[i].content, | |
| 418 tests[i].expected_to_retry); | |
| 419 } | |
| 420 } | |
| 421 | |
| 333 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) { | 422 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) { |
| 334 std::string bad_proxy = GetChromeProxy(); | 423 std::string bad_proxy = GetChromeProxy(); |
| 335 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( | 424 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( |
| 336 "PROXY " + bad_proxy + "; DIRECT")); | 425 "PROXY " + bad_proxy + "; DIRECT")); |
| 337 TestProxyFallbackToDirect(bad_proxy); | 426 TestProxyFallbackToDirect(bad_proxy); |
| 338 } | 427 } |
| 339 | 428 |
| 340 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) { | 429 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) { |
| 341 std::string bad_proxy = GetChromeProxy(); | 430 std::string bad_proxy = GetChromeProxy(); |
| 342 ConfigureTestDependencies( | 431 ConfigureTestDependencies( |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv)); | 689 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv)); |
| 601 | 690 |
| 602 // If the response info is null, that means that any consumer won't | 691 // If the response info is null, that means that any consumer won't |
| 603 // see the network accessed bit set. | 692 // see the network accessed bit set. |
| 604 EXPECT_EQ(NULL, trans->GetResponseInfo()); | 693 EXPECT_EQ(NULL, trans->GetResponseInfo()); |
| 605 } | 694 } |
| 606 | 695 |
| 607 } // namespace | 696 } // namespace |
| 608 | 697 |
| 609 } // namespace net | 698 } // namespace net |
| OLD | NEW |