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/basictypes.h" | |
8 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
9 #include "net/base/net_log.h" | 8 #include "net/base/net_log.h" |
10 #include "net/cert/mock_cert_verifier.h" | 9 #include "net/cert/mock_cert_verifier.h" |
11 #include "net/dns/mock_host_resolver.h" | 10 #include "net/dns/mock_host_resolver.h" |
12 #include "net/http/http_network_session.h" | 11 #include "net/http/http_network_session.h" |
13 #include "net/http/http_server_properties_impl.h" | 12 #include "net/http/http_server_properties_impl.h" |
14 #include "net/http/http_transaction_unittest.h" | 13 #include "net/http/http_transaction_unittest.h" |
15 #include "net/http/transport_security_state.h" | 14 #include "net/http/transport_security_state.h" |
16 #include "net/proxy/proxy_service.h" | 15 #include "net/proxy/proxy_service.h" |
17 #include "net/socket/socket_test_util.h" | 16 #include "net/socket/socket_test_util.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString(); | 53 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString(); |
55 } | 54 } |
56 #endif | 55 #endif |
57 | 56 |
58 #if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(DATA_REDUCTION_FALLBACK_HOST) | 57 #if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(DATA_REDUCTION_FALLBACK_HOST) |
59 std::string GetChromeFallbackProxy() { | 58 std::string GetChromeFallbackProxy() { |
60 return HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString(); | 59 return HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString(); |
61 } | 60 } |
62 #endif | 61 #endif |
63 | 62 |
64 void ExecuteRequestExpectingContentAndHeader(const std::string& method, | 63 void ExecuteRequestExpectingContentAndHeader(const std::string& content, |
65 const std::string& content, | |
66 const std::string& header, | 64 const std::string& header, |
67 const std::string& value) { | 65 const std::string& value) { |
68 TestCompletionCallback callback; | 66 TestCompletionCallback callback; |
69 | 67 |
70 HttpRequestInfo request_info; | 68 HttpRequestInfo request_info; |
71 request_info.url = GURL("http://www.google.com/"); | 69 request_info.url = GURL("http://www.google.com/"); |
72 request_info.method = method; | 70 request_info.method = "GET"; |
73 request_info.load_flags = LOAD_NORMAL; | 71 request_info.load_flags = LOAD_NORMAL; |
74 | 72 |
75 scoped_ptr<HttpTransaction> trans; | 73 scoped_ptr<HttpTransaction> trans; |
76 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL); | 74 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL); |
77 EXPECT_EQ(OK, rv); | 75 EXPECT_EQ(OK, rv); |
78 | 76 |
79 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); | 77 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); |
80 if (rv == ERR_IO_PENDING) | 78 if (rv == ERR_IO_PENDING) |
81 rv = callback.WaitForResult(); | 79 rv = callback.WaitForResult(); |
82 ASSERT_EQ(OK, rv); | 80 ASSERT_EQ(OK, rv); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 }; | 115 }; |
118 TestProxyFallbackWithMockReads(bad_proxy, "", data_reads, | 116 TestProxyFallbackWithMockReads(bad_proxy, "", data_reads, |
119 arraysize(data_reads), 1u); | 117 arraysize(data_reads), 1u); |
120 } | 118 } |
121 | 119 |
122 void TestProxyFallbackWithMockReads(const std::string& bad_proxy, | 120 void TestProxyFallbackWithMockReads(const std::string& bad_proxy, |
123 const std::string& bad_proxy2, | 121 const std::string& bad_proxy2, |
124 MockRead data_reads[], | 122 MockRead data_reads[], |
125 int data_reads_size, | 123 int data_reads_size, |
126 unsigned int expected_retry_info_size) { | 124 unsigned int expected_retry_info_size) { |
127 TestProxyFallbackByMethodWithMockReads(bad_proxy, bad_proxy2, data_reads, | |
128 data_reads_size, "GET", "content", | |
129 true, expected_retry_info_size); | |
130 } | |
131 | |
132 void TestProxyFallbackByMethodWithMockReads( | |
133 const std::string& bad_proxy, | |
134 const std::string& bad_proxy2, | |
135 MockRead data_reads[], | |
136 int data_reads_size, | |
137 std::string method, | |
138 std::string content, | |
139 bool retry_expected, | |
140 unsigned int expected_retry_info_size) { | |
141 std::string trailer = | |
142 (method == "HEAD" || method == "PUT" || method == "POST") ? | |
143 "Content-Length: 0\r\n\r\n" : "\r\n"; | |
144 std::string request = | |
145 base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n" | |
146 "Host: www.google.com\r\n" | |
147 "Proxy-Connection: keep-alive\r\n" | |
148 "%s", method.c_str(), trailer.c_str()); | |
149 | |
150 MockWrite data_writes[] = { | 125 MockWrite data_writes[] = { |
151 MockWrite(request.c_str()), | 126 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 127 "Host: www.google.com\r\n" |
| 128 "Proxy-Connection: keep-alive\r\n\r\n"), |
152 }; | 129 }; |
153 | 130 |
154 StaticSocketDataProvider data1(data_reads, data_reads_size, | 131 StaticSocketDataProvider data1(data_reads, data_reads_size, |
155 data_writes, arraysize(data_writes)); | 132 data_writes, arraysize(data_writes)); |
156 mock_socket_factory_.AddSocketDataProvider(&data1); | 133 mock_socket_factory_.AddSocketDataProvider(&data1); |
157 | 134 |
158 // Second data provider returns the expected content. | 135 // Second data provider returns the expected content. |
159 MockRead data_reads2[3]; | 136 MockRead data_reads2[] = { |
160 size_t data_reads2_index = 0; | 137 MockRead("HTTP/1.0 200 OK\r\n" |
161 data_reads2[data_reads2_index++] = MockRead("HTTP/1.0 200 OK\r\n" | 138 "Server: not-proxy\r\n\r\n"), |
162 "Server: not-proxy\r\n\r\n"); | 139 MockRead("content"), |
163 if (!content.empty()) | 140 MockRead(SYNCHRONOUS, OK), |
164 data_reads2[data_reads2_index++] = MockRead(content.c_str()); | 141 }; |
165 data_reads2[data_reads2_index++] = MockRead(SYNCHRONOUS, OK); | |
166 | |
167 MockWrite data_writes2[] = { | 142 MockWrite data_writes2[] = { |
168 MockWrite(request.c_str()), | 143 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 144 "Host: www.google.com\r\n" |
| 145 "Proxy-Connection: keep-alive\r\n\r\n"), |
169 }; | 146 }; |
170 StaticSocketDataProvider data2(data_reads2, data_reads2_index, | 147 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
171 data_writes2, arraysize(data_writes2)); | 148 data_writes2, arraysize(data_writes2)); |
172 mock_socket_factory_.AddSocketDataProvider(&data2); | 149 mock_socket_factory_.AddSocketDataProvider(&data2); |
173 | 150 |
174 // Expect that we get "content" and not "Bypass message", and that there's | 151 // Expect that we get "content" and not "Bypass message", and that there's |
175 // a "not-proxy" "Server:" header in the final response. | 152 // a "not-proxy" "Server:" header in the final response. |
176 if (retry_expected) { | 153 ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy"); |
177 ExecuteRequestExpectingContentAndHeader(method, content, | |
178 "server", "not-proxy"); | |
179 } else { | |
180 ExecuteRequestExpectingContentAndHeader(method, "Bypass message", "", ""); | |
181 } | |
182 | 154 |
183 // We should also observe the bad proxy in the retry list. | 155 // We should also observe the bad proxy in the retry list. |
184 TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2); | 156 TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2); |
185 } | 157 } |
186 | 158 |
187 // Simulates a request through a proxy which returns a bypass, which is then | 159 // Simulates a request through a proxy which returns a bypass, which is then |
188 // retried through a direct connection to the origin site. | 160 // retried through a direct connection to the origin site. |
189 // Checks that the expected requests were issued, the expected content was | 161 // Checks that the expected requests were issued, the expected content was |
190 // received, and the proxy |bad_proxy| was marked as bad. | 162 // received, and the proxy |bad_proxy| was marked as bad. |
191 void TestProxyFallbackToDirect(const std::string& bad_proxy) { | 163 void TestProxyFallbackToDirect(const std::string& bad_proxy) { |
(...skipping 23 matching lines...) Expand all Loading... |
215 MockWrite("GET / HTTP/1.1\r\n" | 187 MockWrite("GET / HTTP/1.1\r\n" |
216 "Host: www.google.com\r\n" | 188 "Host: www.google.com\r\n" |
217 "Connection: keep-alive\r\n\r\n"), | 189 "Connection: keep-alive\r\n\r\n"), |
218 }; | 190 }; |
219 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | 191 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
220 data_writes2, arraysize(data_writes2)); | 192 data_writes2, arraysize(data_writes2)); |
221 mock_socket_factory_.AddSocketDataProvider(&data2); | 193 mock_socket_factory_.AddSocketDataProvider(&data2); |
222 | 194 |
223 // Expect that we get "content" and not "Bypass message", and that there's | 195 // Expect that we get "content" and not "Bypass message", and that there's |
224 // a "not-proxy" "Server:" header in the final response. | 196 // a "not-proxy" "Server:" header in the final response. |
225 ExecuteRequestExpectingContentAndHeader("GET", "content", | 197 ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy"); |
226 "server", "not-proxy"); | |
227 | 198 |
228 // We should also observe the bad proxy in the retry list. | 199 // We should also observe the bad proxy in the retry list. |
229 TestBadProxies(1u, bad_proxy, ""); | 200 TestBadProxies(1u, bad_proxy, ""); |
230 } | 201 } |
231 | 202 |
232 // Simulates a request through a proxy which returns a bypass, under a | 203 // Simulates a request through a proxy which returns a bypass, under a |
233 // configuration where there is no valid bypass. |proxy_count| proxies | 204 // configuration where there is no valid bypass. |proxy_count| proxies |
234 // are expected to be configured. | 205 // are expected to be configured. |
235 // Checks that the expected requests were issued, the bypass message was the | 206 // Checks that the expected requests were issued, the bypass message was the |
236 // final received content, and all proxies were marked as bad. | 207 // final received content, and all proxies were marked as bad. |
(...skipping 14 matching lines...) Expand all Loading... |
251 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), | 222 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), |
252 data_writes, arraysize(data_writes)); | 223 data_writes, arraysize(data_writes)); |
253 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), | 224 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), |
254 data_writes, arraysize(data_writes)); | 225 data_writes, arraysize(data_writes)); |
255 | 226 |
256 mock_socket_factory_.AddSocketDataProvider(&data1); | 227 mock_socket_factory_.AddSocketDataProvider(&data1); |
257 if (proxy_count > 1) | 228 if (proxy_count > 1) |
258 mock_socket_factory_.AddSocketDataProvider(&data2); | 229 mock_socket_factory_.AddSocketDataProvider(&data2); |
259 | 230 |
260 // Expect that we get "Bypass message", and not "content".. | 231 // Expect that we get "Bypass message", and not "content".. |
261 ExecuteRequestExpectingContentAndHeader("GET", "Bypass message", "", ""); | 232 ExecuteRequestExpectingContentAndHeader("Bypass message", "", ""); |
262 | 233 |
263 // We should also observe the bad proxy or proxies in the retry list. | 234 // We should also observe the bad proxy or proxies in the retry list. |
264 TestBadProxies(proxy_count, bad_proxy, bad_proxy2); | 235 TestBadProxies(proxy_count, bad_proxy, bad_proxy2); |
265 } | 236 } |
266 | 237 |
267 MockClientSocketFactory mock_socket_factory_; | 238 MockClientSocketFactory mock_socket_factory_; |
268 MockHostResolver host_resolver_; | 239 MockHostResolver host_resolver_; |
269 scoped_ptr<CertVerifier> cert_verifier_; | 240 scoped_ptr<CertVerifier> cert_verifier_; |
270 scoped_ptr<TransportSecurityState> transport_security_state_; | 241 scoped_ptr<TransportSecurityState> transport_security_state_; |
271 scoped_ptr<ProxyService> proxy_service_; | 242 scoped_ptr<ProxyService> proxy_service_; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 TestProxyFallback(bad_proxy); | 331 TestProxyFallback(bad_proxy); |
361 } | 332 } |
362 | 333 |
363 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) { | 334 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) { |
364 std::string bad_proxy = GetChromeProxy(); | 335 std::string bad_proxy = GetChromeProxy(); |
365 ConfigureTestDependencies( | 336 ConfigureTestDependencies( |
366 ProxyService::CreateFixed(bad_proxy +", good:8080")); | 337 ProxyService::CreateFixed(bad_proxy +", good:8080")); |
367 TestProxyFallback(bad_proxy); | 338 TestProxyFallback(bad_proxy); |
368 } | 339 } |
369 | 340 |
370 TEST_F(HttpNetworkLayerTest, BypassAndRetryIdempotentMethods) { | |
371 std::string bad_proxy = GetChromeProxy(); | |
372 const struct { | |
373 std::string method; | |
374 std::string content; | |
375 bool expected_to_retry; | |
376 } tests[] = { | |
377 { | |
378 "GET", | |
379 "content", | |
380 true, | |
381 }, | |
382 { | |
383 "OPTIONS", | |
384 "content", | |
385 true, | |
386 }, | |
387 { | |
388 "HEAD", | |
389 "", | |
390 true, | |
391 }, | |
392 { | |
393 "PUT", | |
394 "", | |
395 true, | |
396 }, | |
397 { | |
398 "DELETE", | |
399 "content", | |
400 true, | |
401 }, | |
402 { | |
403 "TRACE", | |
404 "content", | |
405 true, | |
406 }, | |
407 { | |
408 "POST", | |
409 "Bypass message", | |
410 false, | |
411 }, | |
412 }; | |
413 | |
414 for (size_t i = 0; i < arraysize(tests); ++i) { | |
415 ConfigureTestDependencies( | |
416 ProxyService::CreateFixed(bad_proxy +", good:8080")); | |
417 MockRead data_reads[] = { | |
418 MockRead("HTTP/1.1 200 OK\r\n" | |
419 "Chrome-Proxy: bypass=0\r\n\r\n"), | |
420 MockRead("Bypass message"), | |
421 MockRead(SYNCHRONOUS, OK), | |
422 }; | |
423 TestProxyFallbackByMethodWithMockReads(bad_proxy, "", data_reads, | |
424 arraysize(data_reads), | |
425 tests[i].method, | |
426 tests[i].content, | |
427 tests[i].expected_to_retry, 1u); | |
428 } | |
429 } | |
430 | |
431 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) { | 341 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) { |
432 std::string bad_proxy = GetChromeProxy(); | 342 std::string bad_proxy = GetChromeProxy(); |
433 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( | 343 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( |
434 "PROXY " + bad_proxy + "; DIRECT")); | 344 "PROXY " + bad_proxy + "; DIRECT")); |
435 TestProxyFallbackToDirect(bad_proxy); | 345 TestProxyFallbackToDirect(bad_proxy); |
436 } | 346 } |
437 | 347 |
438 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) { | 348 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) { |
439 std::string bad_proxy = GetChromeProxy(); | 349 std::string bad_proxy = GetChromeProxy(); |
440 ConfigureTestDependencies( | 350 ConfigureTestDependencies( |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv)); | 635 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv)); |
726 | 636 |
727 // If the response info is null, that means that any consumer won't | 637 // If the response info is null, that means that any consumer won't |
728 // see the network accessed bit set. | 638 // see the network accessed bit set. |
729 EXPECT_EQ(NULL, trans->GetResponseInfo()); | 639 EXPECT_EQ(NULL, trans->GetResponseInfo()); |
730 } | 640 } |
731 | 641 |
732 } // namespace | 642 } // namespace |
733 | 643 |
734 } // namespace net | 644 } // namespace net |
OLD | NEW |