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

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: 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
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/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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | net/http/http_network_transaction.cc » ('j') | net/http/http_network_transaction.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698