Index: net/http/http_network_layer_unittest.cc |
diff --git a/net/http/http_network_layer_unittest.cc b/net/http/http_network_layer_unittest.cc |
index a82dd007810c17e29bd55d4f55069aad5a74bca3..f5ecb59ed53e316e9c0c3d09c0e6140834449a97 100644 |
--- a/net/http/http_network_layer_unittest.cc |
+++ b/net/http/http_network_layer_unittest.cc |
@@ -23,10 +23,15 @@ namespace { |
class HttpNetworkLayerTest : public PlatformTest { |
protected: |
- HttpNetworkLayerTest() |
- : cert_verifier_(new MockCertVerifier), |
- proxy_service_(ProxyService::CreateDirect()), |
- ssl_config_service_(new SSLConfigServiceDefaults) { |
+ HttpNetworkLayerTest() : ssl_config_service_(new SSLConfigServiceDefaults) {} |
+ |
+ virtual void SetUp() { |
+ ConfigureTestDependencies(ProxyService::CreateDirect()); |
+ } |
+ |
+ void ConfigureTestDependencies(ProxyService* proxy_service) { |
+ cert_verifier_.reset(new MockCertVerifier); |
+ proxy_service_.reset(proxy_service); |
HttpNetworkSession::Params session_params; |
session_params.client_socket_factory = &mock_socket_factory_; |
session_params.host_resolver = &host_resolver_; |
@@ -41,7 +46,7 @@ class HttpNetworkLayerTest : public PlatformTest { |
MockClientSocketFactory mock_socket_factory_; |
MockHostResolver host_resolver_; |
scoped_ptr<CertVerifier> cert_verifier_; |
- const scoped_ptr<ProxyService> proxy_service_; |
+ scoped_ptr<ProxyService> proxy_service_; |
const scoped_refptr<SSLConfigService> ssl_config_service_; |
scoped_refptr<HttpNetworkSession> network_session_; |
scoped_ptr<HttpNetworkLayer> factory_; |
@@ -115,6 +120,131 @@ TEST_F(HttpNetworkLayerTest, GET) { |
EXPECT_EQ("hello world", contents); |
} |
+TEST_F(HttpNetworkLayerTest, ServerFallback) { |
+ // Verify that a Connection: Proxy-Bypass header induces proxy fallback to |
+ // a second proxy, if configured. |
+ |
+ // To configure this test, we need to wire up a custom proxy service to use |
+ // a pair of proxies. We'll induce fallback via the first and return |
+ // the expected data via the second. |
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( |
+ "PROXY bad:8080; PROXY good:8080")); |
+ |
+ MockRead data_reads[] = { |
+ MockRead("HTTP/1.1 200 OK\r\n" |
+ "Connection: proxy-bypass\r\n\r\n"), |
+ MockRead("Bypass message"), |
+ MockRead(SYNCHRONOUS, OK), |
+ }; |
+ MockWrite data_writes[] = { |
+ MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
+ "Host: www.google.com\r\n" |
+ "Proxy-Connection: keep-alive\r\n\r\n"), |
+ }; |
+ StaticSocketDataProvider data1(data_reads, arraysize(data_reads), |
+ data_writes, arraysize(data_writes)); |
+ mock_socket_factory_.AddSocketDataProvider(&data1); |
+ |
+ // Second data provider returns the expected content. |
+ MockRead data_reads2[] = { |
+ MockRead("HTTP/1.0 200 OK\r\n" |
+ "Server: not-proxy\r\n\r\n"), |
+ MockRead("content"), |
+ MockRead(SYNCHRONOUS, OK), |
+ }; |
+ MockWrite data_writes2[] = { |
+ MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
+ "Host: www.google.com\r\n" |
+ "Proxy-Connection: keep-alive\r\n\r\n"), |
+ }; |
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), |
+ data_writes2, arraysize(data_writes2)); |
+ mock_socket_factory_.AddSocketDataProvider(&data2); |
+ |
+ TestCompletionCallback callback; |
+ |
+ HttpRequestInfo request_info; |
+ request_info.url = GURL("http://www.google.com/"); |
+ request_info.method = "GET"; |
+ request_info.load_flags = LOAD_NORMAL; |
+ |
+ scoped_ptr<HttpTransaction> trans; |
+ int rv = factory_->CreateTransaction(&trans, NULL); |
+ EXPECT_EQ(OK, rv); |
+ |
+ rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); |
+ if (rv == ERR_IO_PENDING) |
+ rv = callback.WaitForResult(); |
+ ASSERT_EQ(OK, rv); |
+ |
+ std::string contents; |
+ rv = ReadTransaction(trans.get(), &contents); |
+ EXPECT_EQ(OK, rv); |
+ |
+ // We should obtain content from the second socket provider write |
+ // corresponding to the fallback proxy. |
+ EXPECT_EQ("content", contents); |
+ // We also have a server header here that isn't set by the proxy. |
+ EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue( |
+ "server", "not-proxy")); |
+ // We should also observe the bad proxy in the retry list. |
+ ASSERT_EQ(1u, proxy_service_->proxy_retry_info().size()); |
+ EXPECT_EQ("bad:8080", (*proxy_service_->proxy_retry_info().begin()).first); |
+} |
+ |
+TEST_F(HttpNetworkLayerTest, ServerFallbackDoesntLoop) { |
+ // Verify that a Connection: Proxy-Bypass header will display the original |
+ // proxy's error page content if a fallback option is not configured. |
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult( |
+ "PROXY bad:8080; PROXY alsobad:8080")); |
+ |
+ MockRead data_reads[] = { |
+ MockRead("HTTP/1.1 200 OK\r\n" |
+ "Connection: proxy-bypass\r\n\r\n"), |
+ MockRead("Bypass message"), |
+ MockRead(SYNCHRONOUS, OK), |
+ }; |
+ MockWrite data_writes[] = { |
+ MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
+ "Host: www.google.com\r\n" |
+ "Proxy-Connection: keep-alive\r\n\r\n"), |
+ }; |
+ StaticSocketDataProvider data1(data_reads, arraysize(data_reads), |
+ data_writes, arraysize(data_writes)); |
eroman
2012/10/12 18:30:58
nit: indent by 1 more
Michael Piatek
2012/10/15 17:10:16
Done.
|
+ StaticSocketDataProvider data2(data_reads, arraysize(data_reads), |
+ data_writes, arraysize(data_writes)); |
eroman
2012/10/12 18:30:58
same
Michael Piatek
2012/10/15 17:10:16
Done.
|
+ mock_socket_factory_.AddSocketDataProvider(&data1); |
+ mock_socket_factory_.AddSocketDataProvider(&data2); |
+ |
+ TestCompletionCallback callback; |
+ |
+ HttpRequestInfo request_info; |
+ request_info.url = GURL("http://www.google.com/"); |
+ request_info.method = "GET"; |
+ request_info.load_flags = LOAD_NORMAL; |
+ |
+ scoped_ptr<HttpTransaction> trans; |
+ int rv = factory_->CreateTransaction(&trans, NULL); |
+ EXPECT_EQ(OK, rv); |
+ |
+ rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); |
+ if (rv == ERR_IO_PENDING) |
+ rv = callback.WaitForResult(); |
+ ASSERT_EQ(OK, rv); |
+ |
+ std::string contents; |
+ rv = ReadTransaction(trans.get(), &contents); |
+ EXPECT_EQ(OK, rv); |
+ EXPECT_EQ("Bypass message", contents); |
+ |
+ // Despite not falling back to anything, we should still observe the proxies |
+ // in the bad proxies list. |
+ const ProxyRetryInfoMap& retry_info = proxy_service_->proxy_retry_info(); |
+ ASSERT_EQ(2u, retry_info.size()); |
+ EXPECT_NE(retry_info.find("bad:8080"), retry_info.end()); |
+ EXPECT_NE(retry_info.find("alsobad:8080"), retry_info.end()); |
+} |
+ |
} // namespace |
} // namespace net |