Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: net/http/http_network_layer_unittest.cc

Issue 99283006: Retry idempotent methods on Chrome-Proxy: bypass (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Using ARRAYSIZE_UNSAFE in test Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/http/http_network_transaction.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
7 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
8 #include "net/base/net_log.h" 9 #include "net/base/net_log.h"
9 #include "net/cert/mock_cert_verifier.h" 10 #include "net/cert/mock_cert_verifier.h"
10 #include "net/dns/mock_host_resolver.h" 11 #include "net/dns/mock_host_resolver.h"
11 #include "net/http/http_network_session.h" 12 #include "net/http/http_network_session.h"
12 #include "net/http/http_server_properties_impl.h" 13 #include "net/http/http_server_properties_impl.h"
13 #include "net/http/http_transaction_unittest.h" 14 #include "net/http/http_transaction_unittest.h"
14 #include "net/http/transport_security_state.h" 15 #include "net/http/transport_security_state.h"
15 #include "net/proxy/proxy_service.h" 16 #include "net/proxy/proxy_service.h"
16 #include "net/socket/socket_test_util.h" 17 #include "net/socket/socket_test_util.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString(); 54 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString();
54 } 55 }
55 #endif 56 #endif
56 57
57 #if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(DATA_REDUCTION_FALLBACK_HOST) 58 #if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(DATA_REDUCTION_FALLBACK_HOST)
58 std::string GetChromeFallbackProxy() { 59 std::string GetChromeFallbackProxy() {
59 return HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString(); 60 return HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
60 } 61 }
61 #endif 62 #endif
62 63
63 void ExecuteRequestExpectingContentAndHeader(const std::string& content, 64 void ExecuteRequestExpectingContentAndHeader(const std::string& method,
65 const std::string& content,
64 const std::string& header, 66 const std::string& header,
65 const std::string& value) { 67 const std::string& value) {
66 TestCompletionCallback callback; 68 TestCompletionCallback callback;
67 69
68 HttpRequestInfo request_info; 70 HttpRequestInfo request_info;
69 request_info.url = GURL("http://www.google.com/"); 71 request_info.url = GURL("http://www.google.com/");
70 request_info.method = "GET"; 72 request_info.method = method;
71 request_info.load_flags = LOAD_NORMAL; 73 request_info.load_flags = LOAD_NORMAL;
72 74
73 scoped_ptr<HttpTransaction> trans; 75 scoped_ptr<HttpTransaction> trans;
74 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL); 76 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL);
75 EXPECT_EQ(OK, rv); 77 EXPECT_EQ(OK, rv);
76 78
77 rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); 79 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
78 if (rv == ERR_IO_PENDING) 80 if (rv == ERR_IO_PENDING)
79 rv = callback.WaitForResult(); 81 rv = callback.WaitForResult();
80 ASSERT_EQ(OK, rv); 82 ASSERT_EQ(OK, rv);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 }; 117 };
116 TestProxyFallbackWithMockReads(bad_proxy, "", data_reads, 118 TestProxyFallbackWithMockReads(bad_proxy, "", data_reads,
117 arraysize(data_reads), 1u); 119 arraysize(data_reads), 1u);
118 } 120 }
119 121
120 void TestProxyFallbackWithMockReads(const std::string& bad_proxy, 122 void TestProxyFallbackWithMockReads(const std::string& bad_proxy,
121 const std::string& bad_proxy2, 123 const std::string& bad_proxy2,
122 MockRead data_reads[], 124 MockRead data_reads[],
123 int data_reads_size, 125 int data_reads_size,
124 unsigned int expected_retry_info_size) { 126 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
125 MockWrite data_writes[] = { 150 MockWrite data_writes[] = {
126 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 151 MockWrite(request.c_str()),
127 "Host: www.google.com\r\n"
128 "Proxy-Connection: keep-alive\r\n\r\n"),
129 }; 152 };
130 153
131 StaticSocketDataProvider data1(data_reads, data_reads_size, 154 StaticSocketDataProvider data1(data_reads, data_reads_size,
132 data_writes, arraysize(data_writes)); 155 data_writes, arraysize(data_writes));
133 mock_socket_factory_.AddSocketDataProvider(&data1); 156 mock_socket_factory_.AddSocketDataProvider(&data1);
134 157
135 // Second data provider returns the expected content. 158 // Second data provider returns the expected content.
136 MockRead data_reads2[] = { 159 MockRead data_reads2[3];
137 MockRead("HTTP/1.0 200 OK\r\n" 160 size_t data_reads2_index = 0;
138 "Server: not-proxy\r\n\r\n"), 161 data_reads2[data_reads2_index++] = MockRead("HTTP/1.0 200 OK\r\n"
139 MockRead("content"), 162 "Server: not-proxy\r\n\r\n");
140 MockRead(SYNCHRONOUS, OK), 163 if (!content.empty())
164 data_reads2[data_reads2_index++] = MockRead(content.c_str());
165 data_reads2[data_reads2_index++] = MockRead(SYNCHRONOUS, OK);
166
167 MockWrite data_writes2[] = {
168 MockWrite(request.c_str()),
141 }; 169 };
142 MockWrite data_writes2[] = { 170 StaticSocketDataProvider data2(data_reads2, data_reads2_index,
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"),
146 };
147 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
148 data_writes2, arraysize(data_writes2)); 171 data_writes2, arraysize(data_writes2));
149 mock_socket_factory_.AddSocketDataProvider(&data2); 172 mock_socket_factory_.AddSocketDataProvider(&data2);
150 173
151 // Expect that we get "content" and not "Bypass message", and that there's 174 // Expect that we get "content" and not "Bypass message", and that there's
152 // a "not-proxy" "Server:" header in the final response. 175 // a "not-proxy" "Server:" header in the final response.
153 ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy"); 176 if (retry_expected) {
177 ExecuteRequestExpectingContentAndHeader(method, content,
178 "server", "not-proxy");
179 } else {
180 ExecuteRequestExpectingContentAndHeader(method, "Bypass message", "", "");
181 }
154 182
155 // We should also observe the bad proxy in the retry list. 183 // We should also observe the bad proxy in the retry list.
156 TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2); 184 TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2);
157 } 185 }
158 186
159 // Simulates a request through a proxy which returns a bypass, which is then 187 // Simulates a request through a proxy which returns a bypass, which is then
160 // retried through a direct connection to the origin site. 188 // retried through a direct connection to the origin site.
161 // Checks that the expected requests were issued, the expected content was 189 // Checks that the expected requests were issued, the expected content was
162 // received, and the proxy |bad_proxy| was marked as bad. 190 // received, and the proxy |bad_proxy| was marked as bad.
163 void TestProxyFallbackToDirect(const std::string& bad_proxy) { 191 void TestProxyFallbackToDirect(const std::string& bad_proxy) {
(...skipping 23 matching lines...) Expand all
187 MockWrite("GET / HTTP/1.1\r\n" 215 MockWrite("GET / HTTP/1.1\r\n"
188 "Host: www.google.com\r\n" 216 "Host: www.google.com\r\n"
189 "Connection: keep-alive\r\n\r\n"), 217 "Connection: keep-alive\r\n\r\n"),
190 }; 218 };
191 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 219 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
192 data_writes2, arraysize(data_writes2)); 220 data_writes2, arraysize(data_writes2));
193 mock_socket_factory_.AddSocketDataProvider(&data2); 221 mock_socket_factory_.AddSocketDataProvider(&data2);
194 222
195 // Expect that we get "content" and not "Bypass message", and that there's 223 // Expect that we get "content" and not "Bypass message", and that there's
196 // a "not-proxy" "Server:" header in the final response. 224 // a "not-proxy" "Server:" header in the final response.
197 ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy"); 225 ExecuteRequestExpectingContentAndHeader("GET", "content",
226 "server", "not-proxy");
198 227
199 // We should also observe the bad proxy in the retry list. 228 // We should also observe the bad proxy in the retry list.
200 TestBadProxies(1u, bad_proxy, ""); 229 TestBadProxies(1u, bad_proxy, "");
201 } 230 }
202 231
203 // Simulates a request through a proxy which returns a bypass, under a 232 // Simulates a request through a proxy which returns a bypass, under a
204 // configuration where there is no valid bypass. |proxy_count| proxies 233 // configuration where there is no valid bypass. |proxy_count| proxies
205 // are expected to be configured. 234 // are expected to be configured.
206 // Checks that the expected requests were issued, the bypass message was the 235 // Checks that the expected requests were issued, the bypass message was the
207 // final received content, and all proxies were marked as bad. 236 // final received content, and all proxies were marked as bad.
(...skipping 14 matching lines...) Expand all
222 StaticSocketDataProvider data1(data_reads, arraysize(data_reads), 251 StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
223 data_writes, arraysize(data_writes)); 252 data_writes, arraysize(data_writes));
224 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), 253 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
225 data_writes, arraysize(data_writes)); 254 data_writes, arraysize(data_writes));
226 255
227 mock_socket_factory_.AddSocketDataProvider(&data1); 256 mock_socket_factory_.AddSocketDataProvider(&data1);
228 if (proxy_count > 1) 257 if (proxy_count > 1)
229 mock_socket_factory_.AddSocketDataProvider(&data2); 258 mock_socket_factory_.AddSocketDataProvider(&data2);
230 259
231 // Expect that we get "Bypass message", and not "content".. 260 // Expect that we get "Bypass message", and not "content"..
232 ExecuteRequestExpectingContentAndHeader("Bypass message", "", ""); 261 ExecuteRequestExpectingContentAndHeader("GET", "Bypass message", "", "");
233 262
234 // We should also observe the bad proxy or proxies in the retry list. 263 // We should also observe the bad proxy or proxies in the retry list.
235 TestBadProxies(proxy_count, bad_proxy, bad_proxy2); 264 TestBadProxies(proxy_count, bad_proxy, bad_proxy2);
236 } 265 }
237 266
238 MockClientSocketFactory mock_socket_factory_; 267 MockClientSocketFactory mock_socket_factory_;
239 MockHostResolver host_resolver_; 268 MockHostResolver host_resolver_;
240 scoped_ptr<CertVerifier> cert_verifier_; 269 scoped_ptr<CertVerifier> cert_verifier_;
241 scoped_ptr<TransportSecurityState> transport_security_state_; 270 scoped_ptr<TransportSecurityState> transport_security_state_;
242 scoped_ptr<ProxyService> proxy_service_; 271 scoped_ptr<ProxyService> proxy_service_;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 TestProxyFallback(bad_proxy); 360 TestProxyFallback(bad_proxy);
332 } 361 }
333 362
334 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) { 363 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) {
335 std::string bad_proxy = GetChromeProxy(); 364 std::string bad_proxy = GetChromeProxy();
336 ConfigureTestDependencies( 365 ConfigureTestDependencies(
337 ProxyService::CreateFixed(bad_proxy +", good:8080")); 366 ProxyService::CreateFixed(bad_proxy +", good:8080"));
338 TestProxyFallback(bad_proxy); 367 TestProxyFallback(bad_proxy);
339 } 368 }
340 369
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_UNSAFE(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
341 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) { 431 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) {
342 std::string bad_proxy = GetChromeProxy(); 432 std::string bad_proxy = GetChromeProxy();
343 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( 433 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
344 "PROXY " + bad_proxy + "; DIRECT")); 434 "PROXY " + bad_proxy + "; DIRECT"));
345 TestProxyFallbackToDirect(bad_proxy); 435 TestProxyFallbackToDirect(bad_proxy);
346 } 436 }
347 437
348 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) { 438 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) {
349 std::string bad_proxy = GetChromeProxy(); 439 std::string bad_proxy = GetChromeProxy();
350 ConfigureTestDependencies( 440 ConfigureTestDependencies(
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv)); 725 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv));
636 726
637 // If the response info is null, that means that any consumer won't 727 // If the response info is null, that means that any consumer won't
638 // see the network accessed bit set. 728 // see the network accessed bit set.
639 EXPECT_EQ(NULL, trans->GetResponseInfo()); 729 EXPECT_EQ(NULL, trans->GetResponseInfo());
640 } 730 }
641 731
642 } // namespace 732 } // namespace
643 733
644 } // namespace net 734 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/http_network_transaction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698