| Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
|
| diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
|
| index 6800c4b3019885c6f756059fbc60dbcb0d170294..b656f0f1d58caf11a8fc0e7f28d5ef36c8102e7f 100644
|
| --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
|
| +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
|
| @@ -49,8 +49,13 @@
|
| #include "net/proxy/proxy_info.h"
|
| #include "net/proxy/proxy_retry_info.h"
|
| #include "net/proxy/proxy_server.h"
|
| +#include "net/proxy/proxy_service.h"
|
| #include "net/socket/socket_test_util.h"
|
| +#include "net/test/cert_test_util.h"
|
| +#include "net/test/gtest_util.h"
|
| +#include "net/test/test_data_directory.h"
|
| #include "net/url_request/url_request.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"
|
| @@ -172,15 +177,31 @@ class TestLoFiUIService : public LoFiUIService {
|
| class DataReductionProxyNetworkDelegateTest : public testing::Test {
|
| public:
|
| DataReductionProxyNetworkDelegateTest()
|
| - : context_(true),
|
| - context_storage_(&context_),
|
| - test_context_(DataReductionProxyTestContext::Builder()
|
| - .WithClient(kClient)
|
| - .WithMockClientSocketFactory(&mock_socket_factory_)
|
| - .WithURLRequestContext(&context_)
|
| - .Build()) {
|
| + : context_(true), context_storage_(&context_) {}
|
| +
|
| + void Init(bool use_secure_proxy,
|
| + bool enable_brotli_globally,
|
| + bool exclude_chrome_proxy_header_for_testing) {
|
| + net::ProxyServer proxy_server =
|
| + use_secure_proxy
|
| + ? net::ProxyServer::FromURI("https://origin.net:443",
|
| + net::ProxyServer::SCHEME_HTTPS)
|
| + : net::ProxyServer::FromURI("http://origin.net:80",
|
| + net::ProxyServer::SCHEME_HTTP);
|
| +
|
| + proxy_service_ =
|
| + net::ProxyService::CreateFixedFromPacResult(proxy_server.ToPacString());
|
| + context_.set_proxy_service(proxy_service_.get());
|
| + test_context_ = (DataReductionProxyTestContext::Builder()
|
| + .WithClient(kClient)
|
| + .WithMockClientSocketFactory(&mock_socket_factory_)
|
| + .WithURLRequestContext(&context_)
|
| + .WithProxiesForHttp({proxy_server})
|
| + .Build());
|
| +
|
| context_.set_client_socket_factory(&mock_socket_factory_);
|
| - test_context_->AttachToURLRequestContext(&context_storage_);
|
| + test_context_->AttachToURLRequestContext(
|
| + &context_storage_, exclude_chrome_proxy_header_for_testing);
|
|
|
| std::unique_ptr<TestLoFiDecider> lofi_decider(new TestLoFiDecider());
|
| lofi_decider_ = lofi_decider.get();
|
| @@ -190,6 +211,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
|
| lofi_ui_service_ = lofi_ui_service.get();
|
| test_context_->io_data()->set_lofi_ui_service(std::move(lofi_ui_service));
|
|
|
| + context_.set_enable_brotli(enable_brotli_globally);
|
| context_.Init();
|
|
|
| test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
|
| @@ -239,6 +261,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
|
| int64_t response_content_length) {
|
| const std::string response_body(
|
| base::checked_cast<size_t>(response_content_length), ' ');
|
| +
|
| net::MockRead reads[] = {net::MockRead(response_headers.c_str()),
|
| net::MockRead(response_body.c_str()),
|
| net::MockRead(net::SYNCHRONOUS, net::OK)};
|
| @@ -256,6 +279,92 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
|
| return request;
|
| }
|
|
|
| + // Fetches a single URL request, verifies the correctness of Accept-Encoding
|
| + // header, and verifies that the response is cached only if |expect_cached|
|
| + // is set to true. Each line in |response_headers| should end with "\r\n" and
|
| + // not '\0', and the last line should have a second "\r\n". An empty
|
| + // |response_headers| is allowed. It works by making this look like an
|
| + // HTTP/0.9 response, since HTTP/0.9 responses don't have headers.
|
| + void FetchURLRequestAndVerifyBrotli(net::HttpRequestHeaders* request_headers,
|
| + const std::string& response_headers,
|
| + bool expect_cached,
|
| + bool expect_brotli) {
|
| + GURL url("http://www.example.com/a.html");
|
| + net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
|
| +
|
| + int response_body_size = 140;
|
| + const std::string response_body(
|
| + base::checked_cast<size_t>(response_body_size), ' ');
|
| +
|
| + ssl_socket_data_provider.next_proto = net::kProtoHTTP11;
|
| + ssl_socket_data_provider.cert = net::ImportCertFromFile(
|
| + net::GetTestCertsDirectory(), "unittest.selfsigned.der");
|
| + mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
|
| +
|
| + net::MockRead reads[] = {net::MockRead(response_headers.c_str()),
|
| + net::MockRead(response_body.c_str()),
|
| + net::MockRead(net::SYNCHRONOUS, net::OK)};
|
| + net::MockWrite writes[1];
|
| +
|
| + if (expect_brotli) {
|
| + writes[0] = net::MockWrite(
|
| + "GET http://www.example.com/a.html HTTP/1.1\r\n"
|
| + "Host: www.example.com\r\n"
|
| + "Proxy-Connection: keep-alive\r\n"
|
| + "User-Agent:\r\n"
|
| + "Accept-Language: en-us,fr\r\n"
|
| + "Accept-Encoding: gzip, deflate, br\r\n\r\n");
|
| + } else {
|
| + writes[0] = net::MockWrite(
|
| + "GET http://www.example.com/a.html HTTP/1.1\r\n"
|
| + "Host: www.example.com\r\n"
|
| + "Proxy-Connection: keep-alive\r\n"
|
| + "User-Agent:\r\n"
|
| + "Accept-Encoding: gzip, deflate\r\n"
|
| + "Accept-Language: en-us,fr\r\n\r\n");
|
| + }
|
| +
|
| + net::StaticSocketDataProvider socket(reads, arraysize(reads), writes,
|
| + arraysize(writes));
|
| + mock_socket_factory_.AddSocketDataProvider(&socket);
|
| +
|
| + net::TestDelegate delegate;
|
| + std::unique_ptr<net::URLRequest> request =
|
| + context_.CreateRequest(url, net::IDLE, &delegate);
|
| + if (request_headers)
|
| + request->SetExtraRequestHeaders(*request_headers);
|
| +
|
| + request->Start();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + if (!expect_cached) {
|
| + EXPECT_EQ(response_body_size,
|
| + request->received_response_content_length());
|
| + EXPECT_NE(0, request->GetTotalSentBytes());
|
| + EXPECT_NE(0, request->GetTotalReceivedBytes());
|
| + EXPECT_FALSE(request->was_cached());
|
| + VerifyBrotliPresent(request.get(), expect_brotli);
|
| + } else {
|
| + EXPECT_TRUE(request->was_cached());
|
| + }
|
| + }
|
| +
|
| + void VerifyBrotliPresent(net::URLRequest* request, bool expect_brotli) {
|
| + net::HttpRequestHeaders request_headers_sent;
|
| + EXPECT_TRUE(request->GetFullRequestHeaders(&request_headers_sent));
|
| + std::string accept_encoding_value;
|
| + EXPECT_TRUE(request_headers_sent.GetHeader("Accept-Encoding",
|
| + &accept_encoding_value));
|
| + EXPECT_NE(std::string::npos, accept_encoding_value.find("gzip"));
|
| + if (expect_brotli) {
|
| + // Brotli should be the last entry in the Accept-Encoding header.
|
| + EXPECT_EQ(accept_encoding_value.length() - 2,
|
| + accept_encoding_value.find("br"));
|
| + } else {
|
| + EXPECT_EQ(std::string::npos, accept_encoding_value.find("br"));
|
| + }
|
| + }
|
| +
|
| void DelegateStageDone(int result) {}
|
|
|
| void NotifyNetworkDelegate(net::URLRequest* request,
|
| @@ -328,6 +437,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
|
|
|
| base::MessageLoopForIO message_loop_;
|
| net::MockClientSocketFactory mock_socket_factory_;
|
| + std::unique_ptr<net::ProxyService> proxy_service_;
|
| net::TestURLRequestContext context_;
|
| net::URLRequestContextStorage context_storage_;
|
|
|
| @@ -337,6 +447,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
|
| };
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest, AuthenticationTest) {
|
| + Init(false, false, false);
|
| std::unique_ptr<net::URLRequest> fake_request(FetchURLRequest(
|
| GURL("http://www.google.com/"), nullptr, std::string(), 0));
|
|
|
| @@ -359,6 +470,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, AuthenticationTest) {
|
| }
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
|
| + Init(false, false, false);
|
| // Enable Lo-Fi.
|
| const struct {
|
| bool lofi_switch_enabled;
|
| @@ -522,6 +634,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
|
| }
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest, RequestDataConfigurations) {
|
| + Init(false, false, false);
|
| const struct {
|
| bool lofi_on;
|
| bool used_data_reduction_proxy;
|
| @@ -593,6 +706,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, RequestDataConfigurations) {
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest,
|
| RequestDataHoldbackConfigurations) {
|
| + Init(false, false, false);
|
| const struct {
|
| bool data_reduction_proxy_enabled;
|
| bool used_direct;
|
| @@ -639,6 +753,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
|
| }
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest, RedirectRequestDataCleared) {
|
| + Init(false, false, false);
|
| net::ProxyInfo data_reduction_proxy_info;
|
| std::string data_reduction_proxy;
|
| base::TrimString(params()->DefaultOrigin(), "/", &data_reduction_proxy);
|
| @@ -684,6 +799,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, RedirectRequestDataCleared) {
|
| }
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest, NetHistograms) {
|
| + Init(false, false, false);
|
| const std::string kReceivedValidOCLHistogramName =
|
| "Net.HttpContentLengthWithValidOCL";
|
| const std::string kOriginalValidOCLHistogramName =
|
| @@ -833,6 +949,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, NetHistograms) {
|
| }
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedInternalLoFi) {
|
| + Init(false, false, false);
|
| // Enable Lo-Fi.
|
| const struct {
|
| bool lofi_response;
|
| @@ -861,6 +978,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedInternalLoFi) {
|
|
|
| TEST_F(DataReductionProxyNetworkDelegateTest,
|
| TestLoFiTransformationTypeHistogram) {
|
| + Init(false, false, false);
|
| const char kLoFiTransformationTypeHistogram[] =
|
| "DataReductionProxy.LoFi.TransformationType";
|
| base::HistogramTester histogram_tester;
|
| @@ -889,6 +1007,94 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
|
| LITE_PAGE, 1);
|
| }
|
|
|
| +// Test that Brotli is not added to the accept-encoding header when it is
|
| +// disabled globally.
|
| +TEST_F(DataReductionProxyNetworkDelegateTest,
|
| + BrotliAdvertisement_BrotliDisabled) {
|
| + Init(true /* use_secure_proxy */, false /* enable_brotli_globally */,
|
| + true /* exclude_chrome_proxy_header_for_testing */);
|
| + base::FieldTrialList field_trial_list(nullptr);
|
| +
|
| + std::string response_headers =
|
| + "HTTP/1.1 200 OK\r\n"
|
| + "Content-Length: 140\r\n"
|
| + "Via: 1.1 Chrome-Compression-Proxy\r\n"
|
| + "x-original-content-length: 200\r\n"
|
| + "Cache-Control: max-age=1200\r\n";
|
| + response_headers += "\r\n";
|
| +
|
| + // Use secure sockets when fetching the request since Brotli is only enabled
|
| + // for secure connections.
|
| + FetchURLRequestAndVerifyBrotli(nullptr, response_headers, false, false);
|
| +}
|
| +
|
| +// Test that Brotli is not added to the accept-encoding header when the request
|
| +// is fetched from an insecure proxy.
|
| +TEST_F(DataReductionProxyNetworkDelegateTest,
|
| + BrotliAdvertisementInsecureProxy) {
|
| + Init(false /* use_secure_proxy */, true /* enable_brotli_globally */,
|
| + false /* exclude_chrome_proxy_header_for_testing */);
|
| + std::string response_headers =
|
| + "HTTP/1.1 200 OK\r\n"
|
| + "Content-Length: 140\r\n"
|
| + "Via: 1.1 Chrome-Compression-Proxy\r\n"
|
| + "x-original-content-length: 200\r\n"
|
| + "Cache-Control: max-age=1200\r\n";
|
| + response_headers += "\r\n";
|
| +
|
| + // Use secure sockets when fetching the request since Brotli is only enabled
|
| + // for secure connections.
|
| + std::unique_ptr<net::URLRequest> request(FetchURLRequest(
|
| + GURL("http://www.example.com/a.html"), nullptr, response_headers, 140));
|
| + EXPECT_EQ(140, request->received_response_content_length());
|
| + EXPECT_NE(0, request->GetTotalSentBytes());
|
| + EXPECT_NE(0, request->GetTotalReceivedBytes());
|
| + EXPECT_FALSE(request->was_cached());
|
| + // Brotli should be added to Accept Encoding header only if secure proxy is in
|
| + VerifyBrotliPresent(request.get(), false);
|
| +}
|
| +
|
| +// Test that Brotli is not added to the accept-encoding header when it is
|
| +// disabled via data reduction proxy field trial.
|
| +TEST_F(DataReductionProxyNetworkDelegateTest,
|
| + BrotliAdvertisementDisabledViaFieldTrial) {
|
| + Init(true /* use_secure_proxy */, true /* enable_brotli_globally */,
|
| + true /* exclude_chrome_proxy_header_for_testing */);
|
| +
|
| + base::FieldTrialList field_trial_list(nullptr);
|
| + ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
|
| + "DataReductionProxyBrotliAcceptEncoding", "Disabled"));
|
| +
|
| + std::string response_headers =
|
| + "HTTP/1.1 200 OK\r\n"
|
| + "Content-Length: 140\r\n"
|
| + "Via: 1.1 Chrome-Compression-Proxy\r\n"
|
| + "x-original-content-length: 200\r\n"
|
| + "Cache-Control: max-age=1200\r\n";
|
| + response_headers += "\r\n";
|
| +
|
| + FetchURLRequestAndVerifyBrotli(nullptr, response_headers, false, false);
|
| + FetchURLRequestAndVerifyBrotli(nullptr, response_headers, true, false);
|
| +}
|
| +
|
| +// Test that Brotli is correctly added to the accept-encoding header when it is
|
| +// enabled globally.
|
| +TEST_F(DataReductionProxyNetworkDelegateTest, BrotliAdvertisement) {
|
| + Init(true /* use_secure_proxy */, true /* enable_brotli_globally */,
|
| + true /* exclude_chrome_proxy_header_for_testing */);
|
| +
|
| + std::string response_headers =
|
| + "HTTP/1.1 200 OK\r\n"
|
| + "Content-Length: 140\r\n"
|
| + "Via: 1.1 Chrome-Compression-Proxy\r\n"
|
| + "x-original-content-length: 200\r\n"
|
| + "Cache-Control: max-age=1200\r\n";
|
| + response_headers += "\r\n";
|
| +
|
| + FetchURLRequestAndVerifyBrotli(nullptr, response_headers, false, true);
|
| + FetchURLRequestAndVerifyBrotli(nullptr, response_headers, true, true);
|
| +}
|
| +
|
| } // namespace
|
|
|
| } // namespace data_reduction_proxy
|
|
|