| Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
|
| diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
|
| index 29c4f9e785e0951b997e7ef15e64d0a176764cd7..2edcff89c21e1919ee2f48703d154906c3f9aeb0 100644
|
| --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
|
| +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
|
| @@ -5,23 +5,31 @@
|
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h"
|
|
|
| #include <string>
|
| +#include <vector>
|
|
|
| #include "base/files/file_path.h"
|
| #include "base/memory/ref_counted.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/scoped_vector.h"
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/prefs/pref_service.h"
|
| #include "base/run_loop.h"
|
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
|
| +#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
|
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
|
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
|
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
|
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
|
| +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
|
| #include "net/base/capturing_net_log.h"
|
| +#include "net/base/net_errors.h"
|
| #include "net/base/request_priority.h"
|
| #include "net/http/http_response_headers.h"
|
| #include "net/proxy/proxy_server.h"
|
| +#include "net/socket/socket_test_util.h"
|
| #include "net/test/embedded_test_server/embedded_test_server.h"
|
| #include "net/url_request/url_request.h"
|
| +#include "net/url_request/url_request_context_storage.h"
|
| #include "net/url_request/url_request_intercepting_job_factory.h"
|
| #include "net/url_request/url_request_interceptor.h"
|
| #include "net/url_request/url_request_job.h"
|
| @@ -30,8 +38,12 @@
|
| #include "net/url_request/url_request_test_util.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +using net::MockRead;
|
| +
|
| namespace data_reduction_proxy {
|
|
|
| +namespace {
|
| +
|
| class CountingURLRequestInterceptor : public net::URLRequestInterceptor {
|
| public:
|
| CountingURLRequestInterceptor()
|
| @@ -264,4 +276,206 @@ TEST_F(DataReductionProxyInterceptorWithServerTest, TestNoBypass) {
|
| EXPECT_EQ("hello", delegate.data_received());
|
| }
|
|
|
| +class DataReductionProxyInterceptorEndToEndTest : public testing::Test {
|
| + public:
|
| + DataReductionProxyInterceptorEndToEndTest()
|
| + : context_(true), context_storage_(&context_) {}
|
| +
|
| + ~DataReductionProxyInterceptorEndToEndTest() override {}
|
| +
|
| + void SetUp() override {
|
| + drp_test_context_ =
|
| + DataReductionProxyTestContext::Builder()
|
| + .WithParamsFlags(DataReductionProxyParams::kAllowed |
|
| + DataReductionProxyParams::kFallbackAllowed)
|
| + .WithParamsDefinitions(
|
| + TestDataReductionProxyParams::HAS_EVERYTHING &
|
| + ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
|
| + ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)
|
| + .WithURLRequestContext(&context_)
|
| + .WithMockClientSocketFactory(&mock_socket_factory_)
|
| + .Build();
|
| + drp_test_context_->AttachToURLRequestContext(&context_storage_);
|
| + context_.set_client_socket_factory(&mock_socket_factory_);
|
| + context_.Init();
|
| + drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
|
| +
|
| + // Three proxies should be available for use: primary, fallback, and direct.
|
| + const net::ProxyConfig& proxy_config =
|
| + drp_test_context_->configurator()->GetProxyConfigOnIOThread();
|
| + EXPECT_EQ(3U, proxy_config.proxy_rules().proxies_for_http.size());
|
| + }
|
| +
|
| + // Creates a URLRequest using the test's TestURLRequestContext and executes
|
| + // it. Returns the created URLRequest.
|
| + scoped_ptr<net::URLRequest> CreateAndExecuteRequest(const GURL& url) {
|
| + scoped_ptr<net::URLRequest> request(
|
| + context_.CreateRequest(url, net::IDLE, &delegate_, NULL));
|
| + request->Start();
|
| + drp_test_context_->RunUntilIdle();
|
| + return request.Pass();
|
| + }
|
| +
|
| + const net::TestDelegate& delegate() const {
|
| + return delegate_;
|
| + }
|
| +
|
| + net::MockClientSocketFactory* mock_socket_factory() {
|
| + return &mock_socket_factory_;
|
| + }
|
| +
|
| + DataReductionProxyConfig* config() const {
|
| + return drp_test_context_->config();
|
| + }
|
| +
|
| + private:
|
| + net::TestDelegate delegate_;
|
| + net::MockClientSocketFactory mock_socket_factory_;
|
| + net::TestURLRequestContext context_;
|
| + net::URLRequestContextStorage context_storage_;
|
| + scoped_ptr<DataReductionProxyTestContext> drp_test_context_;
|
| +};
|
| +
|
| +const std::string kBody = "response body";
|
| +
|
| +TEST_F(DataReductionProxyInterceptorEndToEndTest, ResponseWithoutRetry) {
|
| + // The response comes through the proxy and should not be retried.
|
| + MockRead mock_reads[] = {
|
| + MockRead("HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
|
| + MockRead(kBody.c_str()),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + };
|
| + net::StaticSocketDataProvider socket_data_provider(
|
| + mock_reads, arraysize(mock_reads), nullptr, 0);
|
| + mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);
|
| +
|
| + scoped_ptr<net::URLRequest> request =
|
| + CreateAndExecuteRequest(GURL("http://foo.com"));
|
| +
|
| + EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
|
| + EXPECT_EQ(200, request->GetResponseCode());
|
| + EXPECT_EQ(kBody, delegate().data_received());
|
| + EXPECT_EQ(config()->Origin().host_port_pair().ToString(),
|
| + request->proxy_server().ToString());
|
| +}
|
| +
|
| +TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithoutRetry) {
|
| + // The redirect comes through the proxy and should not be retried.
|
| + MockRead redirect_mock_reads[] = {
|
| + MockRead("HTTP/1.1 302 Found\r\n"
|
| + "Via: 1.1 Chrome-Compression-Proxy\r\n"
|
| + "Location: http://bar.com/\r\n\r\n"),
|
| + MockRead(""),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + };
|
| + net::StaticSocketDataProvider redirect_socket_data_provider(
|
| + redirect_mock_reads, arraysize(redirect_mock_reads), nullptr, 0);
|
| + mock_socket_factory()->AddSocketDataProvider(&redirect_socket_data_provider);
|
| +
|
| + // The response after the redirect comes through proxy and should not be
|
| + // retried.
|
| + MockRead response_mock_reads[] = {
|
| + MockRead("HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
|
| + MockRead(kBody.c_str()),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + };
|
| + net::StaticSocketDataProvider response_socket_data_provider(
|
| + response_mock_reads, arraysize(response_mock_reads), nullptr, 0);
|
| + mock_socket_factory()->AddSocketDataProvider(&response_socket_data_provider);
|
| +
|
| + scoped_ptr<net::URLRequest> request =
|
| + CreateAndExecuteRequest(GURL("http://foo.com"));
|
| +
|
| + EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
|
| + EXPECT_EQ(200, request->GetResponseCode());
|
| + EXPECT_EQ(kBody, delegate().data_received());
|
| + EXPECT_EQ(config()->Origin().host_port_pair().ToString(),
|
| + request->proxy_server().ToString());
|
| + // The redirect should have been processed and followed normally.
|
| + EXPECT_EQ(1, delegate().received_redirect_count());
|
| +}
|
| +
|
| +TEST_F(DataReductionProxyInterceptorEndToEndTest, ResponseWithBypassAndRetry) {
|
| + // The first try gives a bypass.
|
| + MockRead initial_mock_reads[] = {
|
| + MockRead("HTTP/1.1 502 Bad Gateway\r\n"
|
| + "Via: 1.1 Chrome-Compression-Proxy\r\n"
|
| + "Chrome-Proxy: block-once\r\n\r\n"),
|
| + MockRead(""),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + };
|
| + net::StaticSocketDataProvider initial_socket_data_provider(
|
| + initial_mock_reads, arraysize(initial_mock_reads), nullptr, 0);
|
| + mock_socket_factory()->AddSocketDataProvider(&initial_socket_data_provider);
|
| +
|
| + // The retry after the bypass is successful.
|
| + MockRead retry_mock_reads[] = {
|
| + MockRead("HTTP/1.1 200 OK\r\n\r\n"),
|
| + MockRead(kBody.c_str()),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + };
|
| + net::StaticSocketDataProvider retry_socket_data_provider(
|
| + retry_mock_reads, arraysize(retry_mock_reads), nullptr, 0);
|
| + mock_socket_factory()->AddSocketDataProvider(&retry_socket_data_provider);
|
| +
|
| + scoped_ptr<net::URLRequest> request = CreateAndExecuteRequest(
|
| + GURL("http://foo.com"));
|
| +
|
| + EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
|
| + EXPECT_EQ(200, request->GetResponseCode());
|
| + EXPECT_EQ(kBody, delegate().data_received());
|
| + EXPECT_FALSE(request->was_fetched_via_proxy());
|
| + // The bypassed response should have been intercepted before the response was
|
| + // processed, so only the final response after the retry should have been
|
| + // processed.
|
| + EXPECT_EQ(1, delegate().response_started_count());
|
| +}
|
| +
|
| +TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithBypassAndRetry) {
|
| + MockRead mock_reads_array[][3] = {
|
| + // First, get a redirect without a via header, which should be retried
|
| + // using the fallback proxy.
|
| + {
|
| + MockRead("HTTP/1.1 302 Found\r\n"
|
| + "Location: http://bar.com/\r\n\r\n"),
|
| + MockRead(""),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + },
|
| + // Same as before, but through the fallback proxy. Now both proxies are
|
| + // bypassed, and the request should be retried over direct.
|
| + {
|
| + MockRead("HTTP/1.1 302 Found\r\n"
|
| + "Location: http://baz.com/\r\n\r\n"),
|
| + MockRead(""),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + },
|
| + // Finally, a successful response is received.
|
| + {
|
| + MockRead("HTTP/1.1 200 OK\r\n\r\n"),
|
| + MockRead(kBody.c_str()),
|
| + MockRead(net::SYNCHRONOUS, net::OK),
|
| + },
|
| + };
|
| + ScopedVector<net::SocketDataProvider> socket_data_providers;
|
| + for (MockRead* mock_reads : mock_reads_array) {
|
| + socket_data_providers.push_back(
|
| + new net::StaticSocketDataProvider(mock_reads, 3, nullptr, 0));
|
| + mock_socket_factory()->AddSocketDataProvider(socket_data_providers.back());
|
| + }
|
| +
|
| + scoped_ptr<net::URLRequest> request =
|
| + CreateAndExecuteRequest(GURL("http://foo.com"));
|
| +
|
| + EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
|
| + EXPECT_EQ(200, request->GetResponseCode());
|
| + EXPECT_EQ(kBody, delegate().data_received());
|
| + EXPECT_FALSE(request->was_fetched_via_proxy());
|
| +
|
| + // Each of the redirects should have been intercepted before being followed.
|
| + EXPECT_EQ(0, delegate().received_redirect_count());
|
| + EXPECT_EQ(std::vector<GURL>(1, GURL("http://foo.com")), request->url_chain());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| } // namespace data_reduction_proxy
|
|
|