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

Unified Diff: components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc

Issue 958163004: Make Data Saver proxy bypass logic apply to redirects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Suppress size_t to int warnings in gyp/gn files (crbug 167187) Created 5 years, 10 months 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698