Clean up MFYI by adding suppressions for new bugs
[chromium-blink-merge.git] / net / http / http_network_layer_unittest.cc
blob7c3fcb6a715da61356cf502d7d312510afd71ae6
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
3 // found in the LICENSE file.
5 #include "net/http/http_network_layer.h"
7 #include "base/basictypes.h"
8 #include "base/strings/stringprintf.h"
9 #include "net/base/net_log.h"
10 #include "net/cert/mock_cert_verifier.h"
11 #include "net/dns/mock_host_resolver.h"
12 #include "net/http/http_network_session.h"
13 #include "net/http/http_server_properties_impl.h"
14 #include "net/http/http_transaction_unittest.h"
15 #include "net/http/transport_security_state.h"
16 #include "net/proxy/proxy_service.h"
17 #include "net/socket/socket_test_util.h"
18 #include "net/spdy/spdy_session_pool.h"
19 #include "net/ssl/ssl_config_service_defaults.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
23 namespace net {
25 namespace {
27 class HttpNetworkLayerTest : public PlatformTest {
28 protected:
29 HttpNetworkLayerTest() : ssl_config_service_(new SSLConfigServiceDefaults) {}
31 virtual void SetUp() {
32 ConfigureTestDependencies(ProxyService::CreateDirect());
35 void ConfigureTestDependencies(ProxyService* proxy_service) {
36 cert_verifier_.reset(new MockCertVerifier);
37 transport_security_state_.reset(new TransportSecurityState);
38 proxy_service_.reset(proxy_service);
39 HttpNetworkSession::Params session_params;
40 session_params.client_socket_factory = &mock_socket_factory_;
41 session_params.host_resolver = &host_resolver_;
42 session_params.cert_verifier = cert_verifier_.get();
43 session_params.transport_security_state = transport_security_state_.get();
44 session_params.proxy_service = proxy_service_.get();
45 session_params.ssl_config_service = ssl_config_service_.get();
46 session_params.http_server_properties =
47 http_server_properties_.GetWeakPtr();
48 network_session_ = new HttpNetworkSession(session_params);
49 factory_.reset(new HttpNetworkLayer(network_session_.get()));
52 #if defined(SPDY_PROXY_AUTH_ORIGIN)
53 std::string GetChromeProxy() {
54 return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString();
56 #endif
58 #if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(DATA_REDUCTION_FALLBACK_HOST)
59 std::string GetChromeFallbackProxy() {
60 return HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
62 #endif
64 void ExecuteRequestExpectingContentAndHeader(const std::string& method,
65 const std::string& content,
66 const std::string& header,
67 const std::string& value) {
68 TestCompletionCallback callback;
70 HttpRequestInfo request_info;
71 request_info.url = GURL("http://www.google.com/");
72 request_info.method = method;
73 request_info.load_flags = LOAD_NORMAL;
75 scoped_ptr<HttpTransaction> trans;
76 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
77 EXPECT_EQ(OK, rv);
79 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
80 if (rv == ERR_IO_PENDING)
81 rv = callback.WaitForResult();
82 ASSERT_EQ(OK, rv);
84 std::string contents;
85 rv = ReadTransaction(trans.get(), &contents);
86 EXPECT_EQ(OK, rv);
87 EXPECT_EQ(content, contents);
89 if (!header.empty()) {
90 // We also have a server header here that isn't set by the proxy.
91 EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue(
92 header, value));
96 // Check that |proxy_count| proxies are in the retry list.
97 // These will be, in order, |bad_proxy| and |bad_proxy2|".
98 void TestBadProxies(unsigned int proxy_count, const std::string& bad_proxy,
99 const std::string& bad_proxy2) {
100 const ProxyRetryInfoMap& retry_info = proxy_service_->proxy_retry_info();
101 ASSERT_EQ(proxy_count, retry_info.size());
102 if (proxy_count > 0)
103 ASSERT_TRUE(retry_info.find(bad_proxy) != retry_info.end());
104 if (proxy_count > 1)
105 ASSERT_TRUE(retry_info.find(bad_proxy2) != retry_info.end());
108 // Simulates a request through a proxy which returns a bypass, which is then
109 // retried through a second proxy that doesn't bypass.
110 // Checks that the expected requests were issued, the expected content was
111 // recieved, and the first proxy |bad_proxy| was marked as bad.
112 void TestProxyFallback(const std::string& bad_proxy) {
113 MockRead data_reads[] = {
114 MockRead("HTTP/1.1 200 OK\r\n"
115 "Chrome-Proxy: bypass=0\r\n\r\n"),
116 MockRead("Bypass message"),
117 MockRead(SYNCHRONOUS, OK),
119 TestProxyFallbackWithMockReads(bad_proxy, "", data_reads,
120 arraysize(data_reads), 1u);
123 void TestProxyFallbackWithMockReads(const std::string& bad_proxy,
124 const std::string& bad_proxy2,
125 MockRead data_reads[],
126 int data_reads_size,
127 unsigned int expected_retry_info_size) {
128 TestProxyFallbackByMethodWithMockReads(bad_proxy, bad_proxy2, data_reads,
129 data_reads_size, "GET", "content",
130 true, expected_retry_info_size);
133 void TestProxyFallbackByMethodWithMockReads(
134 const std::string& bad_proxy,
135 const std::string& bad_proxy2,
136 MockRead data_reads[],
137 int data_reads_size,
138 std::string method,
139 std::string content,
140 bool retry_expected,
141 unsigned int expected_retry_info_size) {
142 std::string trailer =
143 (method == "HEAD" || method == "PUT" || method == "POST") ?
144 "Content-Length: 0\r\n\r\n" : "\r\n";
145 std::string request =
146 base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n"
147 "Host: www.google.com\r\n"
148 "Proxy-Connection: keep-alive\r\n"
149 "%s", method.c_str(), trailer.c_str());
151 MockWrite data_writes[] = {
152 MockWrite(request.c_str()),
155 StaticSocketDataProvider data1(data_reads, data_reads_size,
156 data_writes, arraysize(data_writes));
157 mock_socket_factory_.AddSocketDataProvider(&data1);
159 // Second data provider returns the expected content.
160 MockRead data_reads2[3];
161 size_t data_reads2_index = 0;
162 data_reads2[data_reads2_index++] = MockRead("HTTP/1.0 200 OK\r\n"
163 "Server: not-proxy\r\n\r\n");
164 if (!content.empty())
165 data_reads2[data_reads2_index++] = MockRead(content.c_str());
166 data_reads2[data_reads2_index++] = MockRead(SYNCHRONOUS, OK);
168 MockWrite data_writes2[] = {
169 MockWrite(request.c_str()),
171 StaticSocketDataProvider data2(data_reads2, data_reads2_index,
172 data_writes2, arraysize(data_writes2));
173 mock_socket_factory_.AddSocketDataProvider(&data2);
175 // Expect that we get "content" and not "Bypass message", and that there's
176 // a "not-proxy" "Server:" header in the final response.
177 if (retry_expected) {
178 ExecuteRequestExpectingContentAndHeader(method, content,
179 "server", "not-proxy");
180 } else {
181 ExecuteRequestExpectingContentAndHeader(method, content, "", "");
184 // We should also observe the bad proxy in the retry list.
185 TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2);
188 // Simulates a request through a proxy which returns a bypass, which is then
189 // retried through a direct connection to the origin site.
190 // Checks that the expected requests were issued, the expected content was
191 // received, and the proxy |bad_proxy| was marked as bad.
192 void TestProxyFallbackToDirect(const std::string& bad_proxy) {
193 MockRead data_reads[] = {
194 MockRead("HTTP/1.1 200 OK\r\n"
195 "Chrome-Proxy: bypass=0\r\n\r\n"),
196 MockRead("Bypass message"),
197 MockRead(SYNCHRONOUS, OK),
199 MockWrite data_writes[] = {
200 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
201 "Host: www.google.com\r\n"
202 "Proxy-Connection: keep-alive\r\n\r\n"),
204 StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
205 data_writes, arraysize(data_writes));
206 mock_socket_factory_.AddSocketDataProvider(&data1);
208 // Second data provider returns the expected content.
209 MockRead data_reads2[] = {
210 MockRead("HTTP/1.0 200 OK\r\n"
211 "Server: not-proxy\r\n\r\n"),
212 MockRead("content"),
213 MockRead(SYNCHRONOUS, OK),
215 MockWrite data_writes2[] = {
216 MockWrite("GET / HTTP/1.1\r\n"
217 "Host: www.google.com\r\n"
218 "Connection: keep-alive\r\n\r\n"),
220 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
221 data_writes2, arraysize(data_writes2));
222 mock_socket_factory_.AddSocketDataProvider(&data2);
224 // Expect that we get "content" and not "Bypass message", and that there's
225 // a "not-proxy" "Server:" header in the final response.
226 ExecuteRequestExpectingContentAndHeader("GET", "content",
227 "server", "not-proxy");
229 // We should also observe the bad proxy in the retry list.
230 TestBadProxies(1u, bad_proxy, "");
233 // Simulates a request through a proxy which returns a bypass, under a
234 // configuration where there is no valid bypass. |proxy_count| proxies
235 // are expected to be configured.
236 // Checks that the expected requests were issued, the bypass message was the
237 // final received content, and all proxies were marked as bad.
238 void TestProxyFallbackFail(unsigned int proxy_count,
239 const std::string& bad_proxy,
240 const std::string& bad_proxy2) {
241 MockRead data_reads[] = {
242 MockRead("HTTP/1.1 200 OK\r\n"
243 "Chrome-Proxy: bypass=0\r\n\r\n"),
244 MockRead("Bypass message"),
245 MockRead(SYNCHRONOUS, OK),
247 MockWrite data_writes[] = {
248 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
249 "Host: www.google.com\r\n"
250 "Proxy-Connection: keep-alive\r\n\r\n"),
252 StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
253 data_writes, arraysize(data_writes));
254 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
255 data_writes, arraysize(data_writes));
257 mock_socket_factory_.AddSocketDataProvider(&data1);
258 if (proxy_count > 1)
259 mock_socket_factory_.AddSocketDataProvider(&data2);
261 // Expect that we get "Bypass message", and not "content"..
262 ExecuteRequestExpectingContentAndHeader("GET", "Bypass message", "", "");
264 // We should also observe the bad proxy or proxies in the retry list.
265 TestBadProxies(proxy_count, bad_proxy, bad_proxy2);
268 MockClientSocketFactory mock_socket_factory_;
269 MockHostResolver host_resolver_;
270 scoped_ptr<CertVerifier> cert_verifier_;
271 scoped_ptr<TransportSecurityState> transport_security_state_;
272 scoped_ptr<ProxyService> proxy_service_;
273 const scoped_refptr<SSLConfigService> ssl_config_service_;
274 scoped_refptr<HttpNetworkSession> network_session_;
275 scoped_ptr<HttpNetworkLayer> factory_;
276 HttpServerPropertiesImpl http_server_properties_;
279 TEST_F(HttpNetworkLayerTest, CreateAndDestroy) {
280 scoped_ptr<HttpTransaction> trans;
281 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
282 EXPECT_EQ(OK, rv);
283 EXPECT_TRUE(trans.get() != NULL);
286 TEST_F(HttpNetworkLayerTest, Suspend) {
287 scoped_ptr<HttpTransaction> trans;
288 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
289 EXPECT_EQ(OK, rv);
291 trans.reset();
293 factory_->OnSuspend();
295 rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
296 EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, rv);
298 ASSERT_TRUE(trans == NULL);
300 factory_->OnResume();
302 rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
303 EXPECT_EQ(OK, rv);
306 TEST_F(HttpNetworkLayerTest, GET) {
307 MockRead data_reads[] = {
308 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
309 MockRead("hello world"),
310 MockRead(SYNCHRONOUS, OK),
312 MockWrite data_writes[] = {
313 MockWrite("GET / HTTP/1.1\r\n"
314 "Host: www.google.com\r\n"
315 "Connection: keep-alive\r\n"
316 "User-Agent: Foo/1.0\r\n\r\n"),
318 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
319 data_writes, arraysize(data_writes));
320 mock_socket_factory_.AddSocketDataProvider(&data);
322 TestCompletionCallback callback;
324 HttpRequestInfo request_info;
325 request_info.url = GURL("http://www.google.com/");
326 request_info.method = "GET";
327 request_info.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
328 "Foo/1.0");
329 request_info.load_flags = LOAD_NORMAL;
331 scoped_ptr<HttpTransaction> trans;
332 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
333 EXPECT_EQ(OK, rv);
335 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
336 rv = callback.GetResult(rv);
337 ASSERT_EQ(OK, rv);
339 std::string contents;
340 rv = ReadTransaction(trans.get(), &contents);
341 EXPECT_EQ(OK, rv);
342 EXPECT_EQ("hello world", contents);
345 // Proxy bypass tests. These tests run through various server-induced
346 // proxy bypass scenarios using both PAC file and fixed proxy params.
347 // The test scenarios are:
348 // - bypass with two proxies configured and the first but not the second
349 // is bypassed.
350 // - bypass with one proxy configured and an explicit fallback to direct
351 // connections
352 // - bypass with two proxies configured and both are bypassed
353 // - bypass with one proxy configured which is bypassed with no defined
354 // fallback
356 #if defined(SPDY_PROXY_AUTH_ORIGIN)
357 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassPac) {
358 std::string bad_proxy = GetChromeProxy();
359 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
360 "PROXY " + bad_proxy + "; PROXY good:8080"));
361 TestProxyFallback(bad_proxy);
364 TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) {
365 std::string bad_proxy = GetChromeProxy();
366 ConfigureTestDependencies(
367 ProxyService::CreateFixed(bad_proxy +", good:8080"));
368 TestProxyFallback(bad_proxy);
371 TEST_F(HttpNetworkLayerTest, BypassAndRetryIdempotentMethods) {
372 std::string bad_proxy = GetChromeProxy();
373 const struct {
374 std::string method;
375 std::string content;
376 bool expected_to_retry;
377 } tests[] = {
379 "GET",
380 "content",
381 true,
384 "OPTIONS",
385 "content",
386 true,
389 "HEAD",
391 true,
394 "PUT",
396 true,
399 "DELETE",
400 "content",
401 true,
404 "TRACE",
405 "content",
406 true,
409 "POST",
410 "Bypass message",
411 false,
415 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
416 ConfigureTestDependencies(
417 ProxyService::CreateFixed(bad_proxy +", good:8080"));
418 MockRead data_reads[] = {
419 MockRead("HTTP/1.1 200 OK\r\n"
420 "Chrome-Proxy: bypass=0\r\n\r\n"),
421 MockRead("Bypass message"),
422 MockRead(SYNCHRONOUS, OK),
424 TestProxyFallbackByMethodWithMockReads(bad_proxy, "", data_reads,
425 arraysize(data_reads),
426 tests[i].method,
427 tests[i].content,
428 tests[i].expected_to_retry, 1u);
432 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) {
433 std::string bad_proxy = GetChromeProxy();
434 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
435 "PROXY " + bad_proxy + "; DIRECT"));
436 TestProxyFallbackToDirect(bad_proxy);
439 TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) {
440 std::string bad_proxy = GetChromeProxy();
441 ConfigureTestDependencies(
442 ProxyService::CreateFixed(bad_proxy + ", direct://"));
443 TestProxyFallbackToDirect(bad_proxy);
446 #if defined(DATA_REDUCTION_FALLBACK_HOST)
447 TEST_F(HttpNetworkLayerTest, ServerTwoProxyDoubleBypassPac) {
448 std::string bad_proxy = GetChromeProxy();
449 std::string bad_proxy2 =
450 HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
451 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
452 "PROXY " + bad_proxy + "; PROXY " + bad_proxy2));
453 TestProxyFallbackFail(2u, bad_proxy, bad_proxy2);
456 TEST_F(HttpNetworkLayerTest, ServerTwoProxyDoubleBypassFixed) {
457 std::string bad_proxy = GetChromeProxy();
458 std::string bad_proxy2 =
459 HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
460 ConfigureTestDependencies(ProxyService::CreateFixed(
461 bad_proxy + ", " + bad_proxy2));
462 TestProxyFallbackFail(2u, bad_proxy, bad_proxy2);
464 #endif
466 TEST_F(HttpNetworkLayerTest, ServerOneProxyNoDirectBypassPac) {
467 std::string bad_proxy = GetChromeProxy();
468 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
469 "PROXY " + bad_proxy));
470 TestProxyFallbackFail(1u, bad_proxy, "");
473 TEST_F(HttpNetworkLayerTest, ServerOneProxyNoDirectBypassFixed) {
474 std::string bad_proxy = GetChromeProxy();
475 ConfigureTestDependencies(ProxyService::CreateFixed(bad_proxy));
476 TestProxyFallbackFail(1u, bad_proxy, "");
479 TEST_F(HttpNetworkLayerTest, ServerFallbackOn5xxError) {
480 // Verify that "500 Internal Server Error", "502 Bad Gateway", and
481 // "503 Service Unavailable" via the data reduction proxy induce proxy
482 // fallback to a second proxy, if configured.
484 // To configure this test, we need to wire up a custom proxy service to use
485 // a pair of proxies. We'll induce fallback via the first and return
486 // the expected data via the second.
487 std::string data_reduction_proxy(
488 HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString());
489 std::string pac_string = base::StringPrintf(
490 "PROXY %s; PROXY good:8080", data_reduction_proxy.data());
492 std::string headers[] = {
493 "HTTP/1.1 500 Internal Server Error\r\n\r\n",
494 "HTTP/1.1 502 Bad Gateway\r\n\r\n",
495 "HTTP/1.1 503 Service Unavailable\r\n\r\n"
498 for (size_t i = 0; i < arraysize(headers); ++i) {
499 ConfigureTestDependencies(
500 ProxyService::CreateFixedFromPacResult(pac_string));
502 MockRead data_reads[] = {
503 MockRead(headers[i].c_str()),
504 MockRead("Bypass message"),
505 MockRead(SYNCHRONOUS, OK),
508 MockWrite data_writes[] = {
509 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
510 "Host: www.google.com\r\n"
511 "Proxy-Connection: keep-alive\r\n\r\n"),
514 StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
515 data_writes, arraysize(data_writes));
516 mock_socket_factory_.AddSocketDataProvider(&data1);
518 // Second data provider returns the expected content.
519 MockRead data_reads2[] = {
520 MockRead("HTTP/1.0 200 OK\r\n"
521 "Server: not-proxy\r\n\r\n"),
522 MockRead("content"),
523 MockRead(SYNCHRONOUS, OK),
525 MockWrite data_writes2[] = {
526 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
527 "Host: www.google.com\r\n"
528 "Proxy-Connection: keep-alive\r\n\r\n"),
531 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
532 data_writes2, arraysize(data_writes2));
533 mock_socket_factory_.AddSocketDataProvider(&data2);
535 TestCompletionCallback callback;
537 HttpRequestInfo request_info;
538 request_info.url = GURL("http://www.google.com/");
539 request_info.method = "GET";
540 request_info.load_flags = LOAD_NORMAL;
542 scoped_ptr<HttpTransaction> trans;
543 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
544 EXPECT_EQ(OK, rv);
546 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
547 if (rv == ERR_IO_PENDING)
548 rv = callback.WaitForResult();
549 ASSERT_EQ(OK, rv);
551 std::string contents;
552 rv = ReadTransaction(trans.get(), &contents);
553 EXPECT_EQ(OK, rv);
555 // We should obtain content from the second socket provider write
556 // corresponding to the fallback proxy.
557 EXPECT_EQ("content", contents);
558 // We also have a server header here that isn't set by the proxy.
559 EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue(
560 "server", "not-proxy"));
561 // We should also observe the data reduction proxy in the retry list.
562 ASSERT_EQ(1u, proxy_service_->proxy_retry_info().size());
563 EXPECT_EQ(data_reduction_proxy,
564 (*proxy_service_->proxy_retry_info().begin()).first);
567 #endif // defined(SPDY_PROXY_AUTH_ORIGIN)
569 TEST_F(HttpNetworkLayerTest, ProxyBypassIgnoredOnDirectConnectionPac) {
570 // Verify that a Chrome-Proxy header is ignored when returned from a directly
571 // connected origin server.
572 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult("DIRECT"));
574 MockRead data_reads[] = {
575 MockRead("HTTP/1.1 200 OK\r\n"
576 "Chrome-Proxy: bypass=0\r\n\r\n"),
577 MockRead("Bypass message"),
578 MockRead(SYNCHRONOUS, OK),
580 MockWrite data_writes[] = {
581 MockWrite("GET / HTTP/1.1\r\n"
582 "Host: www.google.com\r\n"
583 "Connection: keep-alive\r\n\r\n"),
585 StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
586 data_writes, arraysize(data_writes));
587 mock_socket_factory_.AddSocketDataProvider(&data1);
588 TestCompletionCallback callback;
590 HttpRequestInfo request_info;
591 request_info.url = GURL("http://www.google.com/");
592 request_info.method = "GET";
593 request_info.load_flags = LOAD_NORMAL;
595 scoped_ptr<HttpTransaction> trans;
596 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
597 EXPECT_EQ(OK, rv);
599 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
600 if (rv == ERR_IO_PENDING)
601 rv = callback.WaitForResult();
602 ASSERT_EQ(OK, rv);
604 // We should have read the original page data.
605 std::string contents;
606 rv = ReadTransaction(trans.get(), &contents);
607 EXPECT_EQ(OK, rv);
608 EXPECT_EQ("Bypass message", contents);
610 // We should have no entries in our bad proxy list.
611 ASSERT_EQ(0u, proxy_service_->proxy_retry_info().size());
614 #if defined(SPDY_PROXY_AUTH_ORIGIN)
615 TEST_F(HttpNetworkLayerTest, ServerFallbackWithProxyTimedBypass) {
616 // Verify that a Chrome-Proxy: bypass=<seconds> header induces proxy
617 // fallback to a second proxy, if configured.
618 std::string bad_proxy = GetChromeProxy();
619 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
620 "PROXY " + bad_proxy + "; PROXY good:8080"));
622 MockRead data_reads[] = {
623 MockRead("HTTP/1.1 200 OK\r\n"
624 "Connection: keep-alive\r\n"
625 "Chrome-Proxy: bypass=86400\r\n"
626 "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
627 MockRead("Bypass message"),
628 MockRead(SYNCHRONOUS, OK),
631 TestProxyFallbackWithMockReads(bad_proxy, "", data_reads,
632 arraysize(data_reads), 1u);
633 EXPECT_EQ(base::TimeDelta::FromSeconds(86400),
634 (*proxy_service_->proxy_retry_info().begin()).second.current_delay);
637 TEST_F(HttpNetworkLayerTest, ServerFallbackWithWrongViaHeader) {
638 // Verify that a Via header that lacks the Chrome-Proxy induces proxy fallback
639 // to a second proxy, if configured.
640 std::string chrome_proxy = GetChromeProxy();
641 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
642 "PROXY " + chrome_proxy + "; PROXY good:8080"));
644 MockRead data_reads[] = {
645 MockRead("HTTP/1.1 200 OK\r\n"
646 "Connection: keep-alive\r\n"
647 "Via: 1.0 some-other-proxy\r\n\r\n"),
648 MockRead("Bypass message"),
649 MockRead(SYNCHRONOUS, OK),
652 TestProxyFallbackWithMockReads(chrome_proxy, std::string(), data_reads,
653 arraysize(data_reads), 1u);
656 TEST_F(HttpNetworkLayerTest, ServerFallbackWithNoViaHeader) {
657 // Verify that the lack of a Via header induces proxy fallback to a second
658 // proxy, if configured.
659 std::string chrome_proxy = GetChromeProxy();
660 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
661 "PROXY " + chrome_proxy + "; PROXY good:8080"));
663 MockRead data_reads[] = {
664 MockRead("HTTP/1.1 200 OK\r\n"
665 "Connection: keep-alive\r\n\r\n"),
666 MockRead("Bypass message"),
667 MockRead(SYNCHRONOUS, OK),
670 TestProxyFallbackWithMockReads(chrome_proxy, std::string(), data_reads,
671 arraysize(data_reads), 1u);
674 TEST_F(HttpNetworkLayerTest, NoServerFallbackWith304Response) {
675 // Verify that Chrome will not be induced to bypass the Chrome proxy when
676 // the Chrome Proxy via header is absent on a 304.
677 std::string chrome_proxy = GetChromeProxy();
678 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
679 "PROXY " + chrome_proxy + "; PROXY good:8080"));
681 MockRead data_reads[] = {
682 MockRead("HTTP/1.1 304 Not Modified\r\n"
683 "Connection: keep-alive\r\n\r\n"),
684 MockRead(SYNCHRONOUS, OK),
687 TestProxyFallbackByMethodWithMockReads(chrome_proxy, std::string(),
688 data_reads, arraysize(data_reads),
689 "GET", std::string(), false, 0);
692 TEST_F(HttpNetworkLayerTest, NoServerFallbackWithChainedViaHeader) {
693 // Verify that Chrome will not be induced to bypass the Chrome proxy when
694 // the Chrome Proxy via header is present, even if that header is chained.
695 std::string chrome_proxy = GetChromeProxy();
696 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
697 "PROXY " + chrome_proxy + "; PROXY good:8080"));
699 MockRead data_reads[] = {
700 MockRead("HTTP/1.1 200 OK\r\n"
701 "Connection: keep-alive\r\n"
702 "Via: 1.1 Chrome-Compression-Proxy, 1.0 some-other-proxy\r\n\r\n"),
703 MockRead("Bypass message"),
704 MockRead(SYNCHRONOUS, OK),
707 TestProxyFallbackByMethodWithMockReads(chrome_proxy, std::string(),
708 data_reads, arraysize(data_reads),
709 "GET", "Bypass message", false, 0);
712 TEST_F(HttpNetworkLayerTest, NoServerFallbackWithDeprecatedViaHeader) {
713 // Verify that Chrome will not be induced to bypass the Chrome proxy when
714 // the deprecated Chrome Proxy via header is present, even if that header is
715 // chained.
716 std::string chrome_proxy = GetChromeProxy();
717 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
718 "PROXY " + chrome_proxy + "; PROXY good:8080"));
720 MockRead data_reads[] = {
721 MockRead("HTTP/1.1 200 OK\r\n"
722 "Connection: keep-alive\r\n"
723 "Via: 1.1 Chrome Compression Proxy\r\n\r\n"),
724 MockRead("Bypass message"),
725 MockRead(SYNCHRONOUS, OK),
728 TestProxyFallbackByMethodWithMockReads(chrome_proxy, std::string(),
729 data_reads, arraysize(data_reads),
730 "GET", "Bypass message", false, 0);
733 #if defined(DATA_REDUCTION_FALLBACK_HOST)
734 TEST_F(HttpNetworkLayerTest, ServerFallbackWithProxyTimedBypassAll) {
735 // Verify that a Chrome-Proxy: block=<seconds> header bypasses a
736 // a configured Chrome-Proxy and fallback and induces proxy fallback to a
737 // third proxy, if configured.
738 std::string bad_proxy = GetChromeProxy();
739 std::string fallback_proxy = GetChromeFallbackProxy();
740 ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
741 "PROXY " + bad_proxy + "; PROXY " + fallback_proxy +
742 "; PROXY good:8080"));
744 MockRead data_reads[] = {
745 MockRead("HTTP/1.1 200 OK\r\n"
746 "Connection: keep-alive\r\n"
747 "Chrome-Proxy: block=86400\r\n"
748 "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
749 MockRead("Bypass message"),
750 MockRead(SYNCHRONOUS, OK),
753 TestProxyFallbackWithMockReads(bad_proxy, fallback_proxy, data_reads,
754 arraysize(data_reads), 2u);
755 EXPECT_EQ(base::TimeDelta::FromSeconds(86400),
756 (*proxy_service_->proxy_retry_info().begin()).second.current_delay);
758 #endif // defined(DATA_REDUCTION_FALLBACK_HOST)
759 #endif // defined(SPDY_PROXY_AUTH_ORIGIN)
761 TEST_F(HttpNetworkLayerTest, NetworkVerified) {
762 MockRead data_reads[] = {
763 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
764 MockRead("hello world"),
765 MockRead(SYNCHRONOUS, OK),
767 MockWrite data_writes[] = {
768 MockWrite("GET / HTTP/1.1\r\n"
769 "Host: www.google.com\r\n"
770 "Connection: keep-alive\r\n"
771 "User-Agent: Foo/1.0\r\n\r\n"),
773 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
774 data_writes, arraysize(data_writes));
775 mock_socket_factory_.AddSocketDataProvider(&data);
777 TestCompletionCallback callback;
779 HttpRequestInfo request_info;
780 request_info.url = GURL("http://www.google.com/");
781 request_info.method = "GET";
782 request_info.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
783 "Foo/1.0");
784 request_info.load_flags = LOAD_NORMAL;
786 scoped_ptr<HttpTransaction> trans;
787 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
788 EXPECT_EQ(OK, rv);
790 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
791 ASSERT_EQ(OK, callback.GetResult(rv));
793 EXPECT_TRUE(trans->GetResponseInfo()->network_accessed);
796 TEST_F(HttpNetworkLayerTest, NetworkUnVerified) {
797 MockRead data_reads[] = {
798 MockRead(ASYNC, ERR_CONNECTION_RESET),
800 MockWrite data_writes[] = {
801 MockWrite("GET / HTTP/1.1\r\n"
802 "Host: www.google.com\r\n"
803 "Connection: keep-alive\r\n"
804 "User-Agent: Foo/1.0\r\n\r\n"),
806 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
807 data_writes, arraysize(data_writes));
808 mock_socket_factory_.AddSocketDataProvider(&data);
810 TestCompletionCallback callback;
812 HttpRequestInfo request_info;
813 request_info.url = GURL("http://www.google.com/");
814 request_info.method = "GET";
815 request_info.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
816 "Foo/1.0");
817 request_info.load_flags = LOAD_NORMAL;
819 scoped_ptr<HttpTransaction> trans;
820 int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
821 EXPECT_EQ(OK, rv);
823 rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
824 ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv));
826 // If the response info is null, that means that any consumer won't
827 // see the network accessed bit set.
828 EXPECT_EQ(NULL, trans->GetResponseInfo());
831 } // namespace
833 } // namespace net