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

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

Issue 836583002: Add support for field trial group to relax missing via header bypass logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed unused include from aw_url_request_context_getter.cc Created 5 years, 11 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_protocol_unittest.cc
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
deleted file mode 100644
index 72ee6b913ac989366c34006a729f50b169f27314..0000000000000000000000000000000000000000
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
+++ /dev/null
@@ -1,967 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.h"
-
-#include <utility>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/metrics/field_trial.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
-#include "net/base/completion_callback.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/load_flags.h"
-#include "net/base/network_delegate.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_transaction_test_util.h"
-#include "net/proxy/proxy_service.h"
-#include "net/socket/socket_test_util.h"
-#include "net/url_request/static_http_user_agent_settings.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_http_job.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_factory.h"
-#include "net/url_request/url_request_job_factory_impl.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-using net::HttpResponseHeaders;
-using net::HostPortPair;
-using net::MockRead;
-using net::MockWrite;
-using net::ProxyRetryInfoMap;
-using net::ProxyService;
-using net::StaticSocketDataProvider;
-using net::TestDelegate;
-using net::URLRequest;
-using net::TestURLRequestContext;
-
-
-namespace data_reduction_proxy {
-
-class SimpleURLRequestInterceptor : public net::URLRequestInterceptor {
- public:
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override {
- return net::URLRequestHttpJob::Factory(request, network_delegate, "http");
- }
-};
-
-// Constructs a |TestURLRequestContext| that uses a |MockSocketFactory| to
-// simulate requests and responses.
-class DataReductionProxyProtocolTest : public testing::Test {
- public:
- DataReductionProxyProtocolTest() : http_user_agent_settings_("", "") {
- proxy_params_.reset(
- new TestDataReductionProxyParams(
- DataReductionProxyParams::kAllowed |
- DataReductionProxyParams::kFallbackAllowed |
- DataReductionProxyParams::kPromoAllowed,
- TestDataReductionProxyParams::HAS_EVERYTHING &
- ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
- ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN));
- simple_interceptor_.reset(new SimpleURLRequestInterceptor());
- net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
- "http", "www.google.com", simple_interceptor_.Pass());
- }
- ~DataReductionProxyProtocolTest() override {
- // URLRequestJobs may post clean-up tasks on destruction.
- net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(
- "http", "www.google.com");
- base::RunLoop().RunUntilIdle();
- }
-
- // Sets up the |TestURLRequestContext| with the provided |ProxyService| and
- // |bypass_type| to store bypass reasons.
- void ConfigureTestDependencies(ProxyService* proxy_service,
- DataReductionProxyBypassType* bypass_type) {
- // Create a context with delayed initialization.
- context_.reset(new TestURLRequestContext(true));
-
- proxy_service_.reset(proxy_service);
- context_->set_client_socket_factory(&mock_socket_factory_);
- context_->set_proxy_service(proxy_service_.get());
- network_delegate_.reset(new net::TestNetworkDelegate());
- context_->set_network_delegate(network_delegate_.get());
- // This is needed to prevent the test context from adding language headers
- // to requests.
- context_->set_http_user_agent_settings(&http_user_agent_settings_);
- usage_stats_.reset(new DataReductionProxyUsageStats(
- proxy_params_.get(), base::MessageLoopProxy::current()));
- event_store_.reset(new DataReductionProxyEventStore(
- base::MessageLoopProxy::current()));
- DataReductionProxyInterceptor* interceptor =
- new DataReductionProxyInterceptor(proxy_params_.get(),
- usage_stats_.get(),
- event_store_.get());
-
- scoped_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
- new net::URLRequestJobFactoryImpl());
- job_factory_.reset(
- new net::URLRequestInterceptingJobFactory(
- job_factory_impl.Pass(),
- make_scoped_ptr(interceptor)));
- context_->set_job_factory(job_factory_.get());
- context_->Init();
- }
-
- // Simulates a request to a data reduction proxy that may result in bypassing
- // the proxy and retrying the the request.
- // Runs a test with the given request |method| that expects the first response
- // from the server to be |first_response|. If |expected_retry|, the test
- // will expect a retry of the request. A response body will be expected
- // if |expect_response_body|.
- void TestProxyFallback(const char* method,
- const char* first_response,
- bool expected_retry,
- bool generate_response_error,
- size_t expected_bad_proxy_count,
- bool expect_response_body) {
- std::string m(method);
- std::string trailer =
- (m == "HEAD" || m == "PUT" || m == "POST") ?
- "Content-Length: 0\r\n" : "";
-
- std::string request1 =
- base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n%s"
- "User-Agent:\r\n"
- "Accept-Encoding: gzip, deflate\r\n\r\n",
- method, trailer.c_str());
-
- std::string payload1 =
- (expected_retry ? "Bypass message" : "content");
-
- MockWrite data_writes[] = {
- MockWrite(request1.c_str()),
- };
-
- MockRead data_reads[] = {
- MockRead(first_response),
- MockRead(payload1.c_str()),
- MockRead(net::SYNCHRONOUS, net::OK),
- };
- MockRead data_reads_error[] = {
- MockRead(net::SYNCHRONOUS, net::ERR_INVALID_RESPONSE),
- };
-
- StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
- data_writes, arraysize(data_writes));
- StaticSocketDataProvider data1_error(data_reads_error,
- arraysize(data_reads_error),
- data_writes, arraysize(data_writes));
- if (!generate_response_error)
- mock_socket_factory_.AddSocketDataProvider(&data1);
- else
- mock_socket_factory_.AddSocketDataProvider(&data1_error);
-
- std::string response2;
- std::string request2;
- std::string response2_via_header = "";
- std::string request2_connection_type = "";
- std::string request2_path = "/";
- bool idempotent_block_once =
- m != "POST" && expected_retry && expected_bad_proxy_count == 0u;
-
- if (expected_bad_proxy_count < 2u && !idempotent_block_once) {
- request2_path = "http://www.google.com/";
- request2_connection_type = "Proxy-";
- response2_via_header = "Via: 1.1 Chrome-Compression-Proxy\r\n";
- }
-
- request2 = base::StringPrintf(
- "%s %s HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "%sConnection: keep-alive\r\n%s"
- "User-Agent:\r\n"
- "Accept-Encoding: gzip, deflate\r\n\r\n",
- method, request2_path.c_str(), request2_connection_type.c_str(),
- trailer.c_str());
-
- response2 = base::StringPrintf(
- "HTTP/1.0 200 OK\r\n"
- "Server: foo\r\n%s\r\n", response2_via_header.c_str());
-
- MockWrite data_writes2[] = {
- MockWrite(request2.c_str()),
- };
-
- MockRead data_reads2[] = {
- MockRead(response2.c_str()),
- MockRead("content"),
- MockRead(net::SYNCHRONOUS, net::OK),
- };
-
- StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
- data_writes2, arraysize(data_writes2));
- if (expected_retry) {
- mock_socket_factory_.AddSocketDataProvider(&data2);
- }
-
- // Expect that we get "content" and not "Bypass message", and that there's
- // a "not-proxy" "Server:" header in the final response.
- ExecuteRequestExpectingContentAndHeader(
- method,
- (expect_response_body ? "content" : ""),
- expected_retry,
- generate_response_error);
- }
-
- // Starts a request with the given |method| and checks that the response
- // contains |content|.
- void ExecuteRequestExpectingContentAndHeader(const std::string& method,
- const std::string& content,
- bool expected_retry,
- bool expected_error) {
- TestDelegate d;
- scoped_ptr<URLRequest> r(context_->CreateRequest(
- GURL("http://www.google.com/"),
- net::DEFAULT_PRIORITY,
- &d,
- NULL));
- r->set_method(method);
- r->SetLoadFlags(net::LOAD_NORMAL);
-
- r->Start();
- base::RunLoop().Run();
-
- if (!expected_error) {
- EXPECT_EQ(net::URLRequestStatus::SUCCESS, r->status().status());
- EXPECT_EQ(net::OK, r->status().error());
- if (expected_retry)
- EXPECT_EQ(2, network_delegate_->headers_received_count());
- else
- EXPECT_EQ(1, network_delegate_->headers_received_count());
- EXPECT_EQ(content, d.data_received());
- return;
- }
- EXPECT_EQ(net::URLRequestStatus::FAILED, r->status().status());
- EXPECT_EQ(net::ERR_INVALID_RESPONSE, r->status().error());
- EXPECT_EQ(0, network_delegate_->headers_received_count());
- }
-
- // Returns the key to the |ProxyRetryInfoMap|.
- std::string GetProxyKey(std::string proxy) {
- GURL gurl(proxy);
- std::string host_port = HostPortPair::FromURL(GURL(proxy)).ToString();
- if (gurl.SchemeIs("https"))
- return "https://" + host_port;
- return host_port;
- }
-
- // Checks that |expected_num_bad_proxies| proxies are on the proxy retry list.
- // If the list has one proxy, it should match |bad_proxy|. If it has two
- // proxies, it should match |bad_proxy| and |bad_proxy2|. Checks also that
- // the current delay associated with each bad proxy is |duration_seconds|.
- void TestBadProxies(unsigned int expected_num_bad_proxies,
- int duration_seconds,
- const std::string& bad_proxy,
- const std::string& bad_proxy2) {
- const ProxyRetryInfoMap& retry_info = proxy_service_->proxy_retry_info();
- ASSERT_EQ(expected_num_bad_proxies, retry_info.size());
-
- base::TimeDelta expected_min_duration;
- base::TimeDelta expected_max_duration;
- if (duration_seconds == 0) {
- expected_min_duration = base::TimeDelta::FromMinutes(1);
- expected_max_duration = base::TimeDelta::FromMinutes(5);
- } else {
- expected_min_duration = base::TimeDelta::FromSeconds(duration_seconds);
- expected_max_duration = base::TimeDelta::FromSeconds(duration_seconds);
- }
-
- if (expected_num_bad_proxies >= 1u) {
- ProxyRetryInfoMap::const_iterator i =
- retry_info.find(GetProxyKey(bad_proxy));
- ASSERT_TRUE(i != retry_info.end());
- EXPECT_TRUE(expected_min_duration <= (*i).second.current_delay);
- EXPECT_TRUE((*i).second.current_delay <= expected_max_duration);
- }
- if (expected_num_bad_proxies == 2u) {
- ProxyRetryInfoMap::const_iterator i =
- retry_info.find(GetProxyKey(bad_proxy2));
- ASSERT_TRUE(i != retry_info.end());
- EXPECT_TRUE(expected_min_duration <= (*i).second.current_delay);
- EXPECT_TRUE((*i).second.current_delay <= expected_max_duration);
- }
- }
-
- protected:
- base::MessageLoopForIO loop_;
-
- scoped_ptr<net::URLRequestInterceptor> simple_interceptor_;
- net::MockClientSocketFactory mock_socket_factory_;
- scoped_ptr<net::TestNetworkDelegate> network_delegate_;
- scoped_ptr<ProxyService> proxy_service_;
- scoped_ptr<TestDataReductionProxyParams> proxy_params_;
- scoped_ptr<DataReductionProxyUsageStats> usage_stats_;
- scoped_ptr<DataReductionProxyEventStore> event_store_;
- net::StaticHttpUserAgentSettings http_user_agent_settings_;
-
- scoped_ptr<net::URLRequestInterceptingJobFactory> job_factory_;
- scoped_ptr<TestURLRequestContext> context_;
-};
-
-// Tests that request are deemed idempotent or not according to the method used.
-TEST_F(DataReductionProxyProtocolTest, TestIdempotency) {
- net::TestURLRequestContext context;
- const struct {
- const char* method;
- bool expected_result;
- } tests[] = {
- { "GET", true },
- { "OPTIONS", true },
- { "HEAD", true },
- { "PUT", true },
- { "DELETE", true },
- { "TRACE", true },
- { "POST", false },
- { "CONNECT", false },
- };
- for (size_t i = 0; i < arraysize(tests); ++i) {
- scoped_ptr<net::URLRequest> request(
- context.CreateRequest(GURL("http://www.google.com/"),
- net::DEFAULT_PRIORITY,
- NULL,
- NULL));
- request->set_method(tests[i].method);
- EXPECT_EQ(tests[i].expected_result, IsRequestIdempotent(request.get()));
- }
-}
-
-// After each test, the proxy retry info will contain zero, one, or two of the
-// data reduction proxies depending on whether no bypass was indicated by the
-// initial response, a single proxy bypass was indicated, or a double bypass
-// was indicated. In both the single and double bypass cases, if the request
-// was idempotent, it will be retried over a direct connection.
-TEST_F(DataReductionProxyProtocolTest, BypassLogic) {
- const struct {
- const char* method;
- const char* first_response;
- bool expected_retry;
- bool generate_response_error;
- size_t expected_bad_proxy_count;
- bool expect_response_body;
- int expected_duration;
- DataReductionProxyBypassType expected_bypass_type;
- } tests[] = {
- // Valid data reduction proxy response with no bypass message.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
- false,
- 0u,
- true,
- -1,
- BYPASS_EVENT_TYPE_MAX,
- },
- // Response error does not result in bypass.
- { "GET",
- "Not an HTTP response",
- false,
- true,
- 0u,
- true,
- -1,
- BYPASS_EVENT_TYPE_MAX,
- },
- // Valid data reduction proxy response with older, but still valid via
- // header.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Via: 1.1 Chrome Compression Proxy\r\n\r\n",
- false,
- false,
- 0u,
- true,
- -1,
- BYPASS_EVENT_TYPE_MAX
- },
- // Valid data reduction proxy response with chained via header,
- // no bypass message.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Via: 1.1 Chrome-Compression-Proxy, 1.0 some-other-proxy\r\n\r\n",
- false,
- false,
- 0u,
- true,
- -1,
- BYPASS_EVENT_TYPE_MAX
- },
- // Valid data reduction proxy response with a bypass message.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // Valid data reduction proxy response with a bypass message.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=1\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 1,
- BYPASS_EVENT_TYPE_SHORT
- },
- // Same as above with the OPTIONS method, which is idempotent.
- { "OPTIONS",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // Same as above with the HEAD method, which is idempotent.
- { "HEAD",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- false,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // Same as above with the PUT method, which is idempotent.
- { "PUT",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // Same as above with the DELETE method, which is idempotent.
- { "DELETE",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // Same as above with the TRACE method, which is idempotent.
- { "TRACE",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // 500 responses should be bypassed.
- { "GET",
- "HTTP/1.1 500 Internal Server Error\r\n"
- "Server: proxy\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR
- },
- // 502 responses should be bypassed.
- { "GET",
- "HTTP/1.1 502 Internal Server Error\r\n"
- "Server: proxy\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY
- },
- // 503 responses should be bypassed.
- { "GET",
- "HTTP/1.1 503 Internal Server Error\r\n"
- "Server: proxy\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE
- },
- // Invalid data reduction proxy 4xx response. Missing Via header.
- { "GET",
- "HTTP/1.1 404 Not Found\r\n"
- "Server: proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 1,
- BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_4XX
- },
- // Invalid data reduction proxy response. Missing Via header.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER
- },
- // Invalid data reduction proxy response. Wrong Via header.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Via: 1.0 some-other-proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER
- },
- // Valid data reduction proxy response. 304 missing Via header.
- { "GET",
- "HTTP/1.1 304 Not Modified\r\n"
- "Server: proxy\r\n\r\n",
- false,
- false,
- 0u,
- false,
- 0,
- BYPASS_EVENT_TYPE_MAX
- },
- // Valid data reduction proxy response with a bypass message. It will
- // not be retried because the request is non-idempotent.
- { "POST",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=0\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
- false,
- 1u,
- true,
- 0,
- BYPASS_EVENT_TYPE_MEDIUM
- },
- // Valid data reduction proxy response with block message. Both proxies
- // should be on the retry list when it completes.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block=1\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 2u,
- true,
- 1,
- BYPASS_EVENT_TYPE_SHORT
- },
- // Valid data reduction proxy response with a block-once message. It will be
- // retried, and there will be no proxies on the retry list since block-once
- // only affects the current request.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 0u,
- true,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Same as above with the OPTIONS method, which is idempotent.
- { "OPTIONS",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 0u,
- true,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Same as above with the HEAD method, which is idempotent.
- { "HEAD",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 0u,
- false,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Same as above with the PUT method, which is idempotent.
- { "PUT",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 0u,
- true,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Same as above with the DELETE method, which is idempotent.
- { "DELETE",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 0u,
- true,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Same as above with the TRACE method, which is idempotent.
- { "TRACE",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 0u,
- true,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Valid data reduction proxy response with a block-once message. It will
- // not be retried because the request is non-idempotent, and there will be
- // no proxies on the retry list since block-once only affects the current
- // request.
- { "POST",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
- false,
- 0u,
- true,
- 0,
- BYPASS_EVENT_TYPE_CURRENT
- },
- // Valid data reduction proxy response with block and block-once messages.
- // The block message will override the block-once message, so both proxies
- // should be on the retry list when it completes.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: block=1, block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 2u,
- true,
- 1,
- BYPASS_EVENT_TYPE_SHORT
- },
- // Valid data reduction proxy response with bypass and block-once messages.
- // The bypass message will override the block-once message, so one proxy
- // should be on the retry list when it completes.
- { "GET",
- "HTTP/1.1 200 OK\r\n"
- "Server: proxy\r\n"
- "Chrome-Proxy: bypass=1, block-once\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- true,
- false,
- 1u,
- true,
- 1,
- BYPASS_EVENT_TYPE_SHORT
- },
- };
- std::string primary = proxy_params_->DefaultOrigin();
- std::string fallback = proxy_params_->DefaultFallbackOrigin();
- for (size_t i = 0; i < arraysize(tests); ++i) {
- DataReductionProxyBypassType bypass_type;
- ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
- "PROXY " +
- HostPortPair::FromURL(GURL(primary)).ToString() + "; PROXY " +
- HostPortPair::FromURL(GURL(fallback)).ToString() + "; DIRECT"),
- &bypass_type);
- TestProxyFallback(tests[i].method,
- tests[i].first_response,
- tests[i].expected_retry,
- tests[i].generate_response_error,
- tests[i].expected_bad_proxy_count,
- tests[i].expect_response_body);
- EXPECT_EQ(tests[i].expected_bypass_type, usage_stats_->GetBypassType());
- // We should also observe the bad proxy in the retry list.
- TestBadProxies(tests[i].expected_bad_proxy_count,
- tests[i].expected_duration,
- primary, fallback);
- }
-}
-
-TEST_F(DataReductionProxyProtocolTest,
- ProxyBypassIgnoredOnDirectConnection) {
- // Verify that a Chrome-Proxy header is ignored when returned from a directly
- // connected origin server.
- ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult("DIRECT"),
- NULL);
-
- MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"
- "Chrome-Proxy: bypass=0\r\n\r\n"),
- MockRead("Bypass message"),
- MockRead(net::SYNCHRONOUS, net::OK),
- };
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Connection: keep-alive\r\n"
- "User-Agent:\r\n"
- "Accept-Encoding: gzip, deflate\r\n\r\n"),
- };
- StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
- data_writes, arraysize(data_writes));
- mock_socket_factory_.AddSocketDataProvider(&data1);
-
- TestDelegate d;
- scoped_ptr<URLRequest> r(context_->CreateRequest(
- GURL("http://www.google.com/"),
- net::DEFAULT_PRIORITY,
- &d,
- NULL));
- r->set_method("GET");
- r->SetLoadFlags(net::LOAD_NORMAL);
-
- r->Start();
- base::RunLoop().Run();
-
- EXPECT_EQ(net::URLRequestStatus::SUCCESS, r->status().status());
- EXPECT_EQ(net::OK, r->status().error());
-
- EXPECT_EQ("Bypass message", d.data_received());
-
- // We should have no entries in our bad proxy list.
- TestBadProxies(0, -1, "", "");
-}
-
-class BadEntropyProvider : public base::FieldTrial::EntropyProvider {
- public:
- ~BadEntropyProvider() override {}
-
- double GetEntropyForTrial(const std::string& trial_name,
- uint32 randomization_seed) const override {
- return 0.5;
- }
-};
-
-TEST_F(DataReductionProxyProtocolTest, OnResolveProxyHandler) {
- int load_flags = net::LOAD_NORMAL;
- GURL url("http://www.google.com/");
-
- TestDataReductionProxyParams test_params(
- DataReductionProxyParams::kAllowed |
- DataReductionProxyParams::kFallbackAllowed |
- DataReductionProxyParams::kPromoAllowed,
- TestDataReductionProxyParams::HAS_EVERYTHING &
- ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
- ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN);
-
- // Data reduction proxy info
- net::ProxyInfo data_reduction_proxy_info;
- std::string data_reduction_proxy;
- base::TrimString(test_params.DefaultOrigin(), "/", &data_reduction_proxy);
- data_reduction_proxy_info.UsePacString(
- "PROXY " +
- HostPortPair::FromURL(GURL(test_params.DefaultOrigin())).ToString() +
- "; DIRECT");
- EXPECT_FALSE(data_reduction_proxy_info.is_empty());
-
- // Data reduction proxy config
- net::ProxyConfig data_reduction_proxy_config;
- data_reduction_proxy_config.proxy_rules().ParseFromString(
- "http=" + data_reduction_proxy + ",direct://;");
- data_reduction_proxy_config.set_id(1);
-
- // Other proxy info
- net::ProxyInfo other_proxy_info;
- other_proxy_info.UseNamedProxy("proxy.com");
- EXPECT_FALSE(other_proxy_info.is_empty());
-
- // Direct
- net::ProxyInfo direct_proxy_info;
- direct_proxy_info.UseDirect();
- EXPECT_TRUE(direct_proxy_info.is_direct());
-
- // Empty retry info map
- net::ProxyRetryInfoMap empty_proxy_retry_info;
-
- // Retry info map with the data reduction proxy;
- net::ProxyRetryInfoMap data_reduction_proxy_retry_info;
- net::ProxyRetryInfo retry_info;
- retry_info.current_delay = base::TimeDelta::FromSeconds(1000);
- retry_info.bad_until = base::TimeTicks().Now() + retry_info.current_delay;
- retry_info.try_while_bad = false;
- data_reduction_proxy_retry_info[
- data_reduction_proxy_info.proxy_server().ToURI()] = retry_info;
-
- net::ProxyInfo result;
- // Another proxy is used. It should be used afterwards.
- result.Use(other_proxy_info);
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params, &result);
- EXPECT_EQ(other_proxy_info.proxy_server(), result.proxy_server());
-
- // A direct connection is used. The data reduction proxy should be used
- // afterwards.
- // Another proxy is used. It should be used afterwards.
- result.Use(direct_proxy_info);
- net::ProxyConfig::ID prev_id = result.config_id();
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params, &result);
- EXPECT_EQ(data_reduction_proxy_info.proxy_server(), result.proxy_server());
- // Only the proxy list should be updated, not he proxy info.
- EXPECT_EQ(result.config_id(), prev_id);
-
- // A direct connection is used, but the data reduction proxy is on the retry
- // list. A direct connection should be used afterwards.
- result.Use(direct_proxy_info);
- prev_id = result.config_id();
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- data_reduction_proxy_retry_info, &test_params, &result);
- EXPECT_TRUE(result.proxy_server().is_direct());
- EXPECT_EQ(result.config_id(), prev_id);
-
- // Test that ws:// and wss:// URLs bypass the data reduction proxy.
- result.UseDirect();
- OnResolveProxyHandler(GURL("ws://echo.websocket.org/"),
- load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params, &result);
- EXPECT_TRUE(result.is_direct());
-
- OnResolveProxyHandler(GURL("wss://echo.websocket.org/"),
- load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params, &result);
- EXPECT_TRUE(result.is_direct());
-
- // Without DataCompressionProxyCriticalBypass Finch trial set, the
- // BYPASS_DATA_REDUCTION_PROXY load flag should be ignored.
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params,
- &result);
- EXPECT_FALSE(result.is_direct());
-
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info,
- &test_params, &other_proxy_info);
- EXPECT_FALSE(other_proxy_info.is_direct());
-
- load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
-
- result.UseDirect();
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params,
- &result);
- EXPECT_FALSE(result.is_direct());
-
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info,
- &test_params, &other_proxy_info);
- EXPECT_FALSE(other_proxy_info.is_direct());
-
- // With Finch trial set, should only bypass if LOAD flag is set and the
- // effective proxy is the data compression proxy.
- base::FieldTrialList field_trial_list(new BadEntropyProvider());
- base::FieldTrialList::CreateFieldTrial("DataCompressionProxyCriticalBypass",
- "Enabled");
- EXPECT_TRUE(
- DataReductionProxyParams::IsIncludedInCriticalPathBypassFieldTrial());
-
- load_flags = net::LOAD_NORMAL;
-
- result.UseDirect();
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params,
- &result);
- EXPECT_FALSE(result.is_direct());
-
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params,
- &other_proxy_info);
- EXPECT_FALSE(other_proxy_info.is_direct());
-
- load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
-
- result.UseDirect();
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params,
- &result);
- EXPECT_TRUE(result.is_direct());
-
- OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
- empty_proxy_retry_info, &test_params,
- &other_proxy_info);
- EXPECT_FALSE(other_proxy_info.is_direct());
-}
-
-} // namespace data_reduction_proxy

Powered by Google App Engine
This is Rietveld 408576698