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 3672297f81bc418bd5551a09a0be9737827fc2dc..fb4e7feb631c998d617f6375c24c5dfeaa7e0c19 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 |
@@ -134,6 +134,7 @@ class TestLoFiDecider : public LoFiDecider { |
public: |
TestLoFiDecider() |
: should_be_client_lofi_(false), |
+ should_be_client_lofi_auto_reload_(false), |
should_request_lofi_resource_(false), |
ignore_is_using_data_reduction_proxy_check_(false) {} |
~TestLoFiDecider() override {} |
@@ -150,6 +151,10 @@ class TestLoFiDecider : public LoFiDecider { |
should_be_client_lofi_ = should_be_client_lofi; |
} |
+ void SetIsClientLoFiAutoReload(bool should_be_client_lofi_auto_reload) { |
+ should_be_client_lofi_auto_reload_ = should_be_client_lofi_auto_reload; |
+ } |
+ |
void MaybeSetAcceptTransformHeader( |
const net::URLRequest& request, |
bool is_previews_disabled, |
@@ -198,12 +203,18 @@ class TestLoFiDecider : public LoFiDecider { |
return should_be_client_lofi_; |
} |
+ bool IsClientLoFiAutoReloadRequest( |
+ const net::URLRequest& request) const override { |
+ return should_be_client_lofi_auto_reload_; |
+ } |
+ |
void ignore_is_using_data_reduction_proxy_check() { |
ignore_is_using_data_reduction_proxy_check_ = true; |
} |
private: |
bool should_be_client_lofi_; |
+ bool should_be_client_lofi_auto_reload_; |
bool should_request_lofi_resource_; |
bool ignore_is_using_data_reduction_proxy_check_; |
}; |
@@ -232,6 +243,8 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test { |
DataReductionProxyNetworkDelegateTest() |
: context_(true), |
context_storage_(&context_), |
+ lofi_decider_(nullptr), |
+ lofi_ui_service_(nullptr), |
ssl_socket_data_provider_(net::ASYNC, net::OK) { |
ssl_socket_data_provider_.next_proto = net::kProtoHTTP11; |
ssl_socket_data_provider_.cert = net::ImportCertFromFile( |
@@ -1653,6 +1666,186 @@ TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithoutVary) { |
FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true); |
} |
+class DataReductionProxyNetworkDelegateClientLoFiTest : public testing::Test { |
+ public: |
+ DataReductionProxyNetworkDelegateClientLoFiTest() : baseline_savings_(0) {} |
+ ~DataReductionProxyNetworkDelegateClientLoFiTest() override; |
+ |
+ void Reset() { |
+ drp_test_context_.reset(); |
+ mock_socket_factory_.reset(); |
+ context_storage_.reset(); |
+ |
+ context_.reset(new net::TestURLRequestContext(true)); |
+ context_storage_.reset(new net::URLRequestContextStorage(context_.get())); |
+ mock_socket_factory_.reset(new net::MockClientSocketFactory()); |
+ context_->set_client_socket_factory(mock_socket_factory_.get()); |
+ |
+ drp_test_context_ = |
+ DataReductionProxyTestContext::Builder() |
+ .WithURLRequestContext(context_.get()) |
+ .WithMockClientSocketFactory(mock_socket_factory_.get()) |
+ .Build(); |
+ |
+ drp_test_context_->AttachToURLRequestContext(context_storage_.get()); |
+ context_->Init(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ baseline_savings_ = |
+ drp_test_context()->settings()->GetTotalHttpContentLengthSaved(); |
+ } |
+ |
+ void SetUpLoFiDecider(bool is_client_lofi_image, |
+ bool is_client_lofi_auto_reload) const { |
+ std::unique_ptr<TestLoFiDecider> lofi_decider(new TestLoFiDecider()); |
+ lofi_decider->SetIsUsingClientLoFi(is_client_lofi_image); |
+ lofi_decider->SetIsClientLoFiAutoReload(is_client_lofi_auto_reload); |
+ drp_test_context_->io_data()->set_lofi_decider( |
+ std::unique_ptr<LoFiDecider>(std::move(lofi_decider))); |
+ } |
+ |
+ int64_t GetSavings() const { |
+ return drp_test_context()->settings()->GetTotalHttpContentLengthSaved() - |
+ baseline_savings_; |
+ } |
+ |
+ net::TestURLRequestContext* context() const { return context_.get(); } |
+ net::MockClientSocketFactory* mock_socket_factory() const { |
+ return mock_socket_factory_.get(); |
+ } |
+ DataReductionProxyTestContext* drp_test_context() const { |
+ return drp_test_context_.get(); |
+ } |
+ |
+ private: |
+ base::MessageLoopForIO loop; |
+ std::unique_ptr<net::TestURLRequestContext> context_; |
+ std::unique_ptr<net::URLRequestContextStorage> context_storage_; |
+ std::unique_ptr<net::MockClientSocketFactory> mock_socket_factory_; |
+ std::unique_ptr<DataReductionProxyTestContext> drp_test_context_; |
+ int64_t baseline_savings_; |
+}; |
+ |
+DataReductionProxyNetworkDelegateClientLoFiTest:: |
+ ~DataReductionProxyNetworkDelegateClientLoFiTest() {} |
+ |
+TEST_F(DataReductionProxyNetworkDelegateClientLoFiTest, DataSavingsNonDRP) { |
+ const char kSimple200ResponseHeaders[] = |
+ "HTTP/1.1 200 OK\r\n" |
+ "Content-Length: 140\r\n\r\n"; |
+ |
+ const struct { |
+ const char* headers; |
+ size_t response_length; |
+ bool is_client_lofi_image; |
+ bool is_client_lofi_auto_reload; |
+ int64_t expected_savings; |
+ } tests[] = { |
+ // 200 responses shouldn't see any savings. |
+ {kSimple200ResponseHeaders, 140, false, false, 0}, |
+ {kSimple200ResponseHeaders, 140, true, false, 0}, |
+ |
+ // Client Lo-Fi Auto-reload responses should see negative savings. |
+ {kSimple200ResponseHeaders, 140, false, true, |
+ -(static_cast<int64_t>(sizeof(kSimple200ResponseHeaders) - 1) + 140)}, |
+ {kSimple200ResponseHeaders, 140, true, true, |
+ -(static_cast<int64_t>(sizeof(kSimple200ResponseHeaders) - 1) + 140)}, |
+ |
+ // A range response that doesn't use Client Lo-Fi shouldn't see any |
+ // savings. |
+ {"HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Range: bytes 0-2047/10000\r\n" |
+ "Content-Length: 2048\r\n\r\n", |
+ 2048, false, false, 0}, |
+ |
+ // A Client Lo-Fi range response should see savings based on the |
+ // Content-Range header. |
+ {"HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Range: bytes 0-2047/10000\r\n" |
+ "Content-Length: 2048\r\n\r\n", |
+ 2048, true, false, 10000 - 2048}, |
+ |
+ // A Client Lo-Fi range response should see savings based on the |
+ // Content-Range header, which in this case is 0 savings because the range |
+ // response contained the entire resource. |
+ {"HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Range: bytes 0-999/1000\r\n" |
+ "Content-Length: 1000\r\n\r\n", |
+ 1000, true, false, 0}, |
+ |
+ // Client Lo-Fi range responses that don't have a Content-Range with the |
+ // full resource length shouldn't see any savings. |
+ {"HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Length: 2048\r\n\r\n", |
+ 2048, true, false, 0}, |
+ {"HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Range: bytes 0-2047/*\r\n" |
+ "Content-Length: 2048\r\n\r\n", |
+ 2048, true, false, 0}, |
+ {"HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Range: invalid_content_range\r\n" |
+ "Content-Length: 2048\r\n\r\n", |
+ 2048, true, false, 0}, |
+ }; |
+ |
+ for (const auto& test : tests) { |
+ Reset(); |
+ SetUpLoFiDecider(test.is_client_lofi_image, |
+ test.is_client_lofi_auto_reload); |
+ |
+ std::string response_body(test.response_length, 'a'); |
+ net::MockRead reads[] = {net::MockRead(test.headers), |
+ net::MockRead(response_body.c_str()), |
+ net::MockRead(net::ASYNC, net::OK)}; |
+ net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); |
+ mock_socket_factory()->AddSocketDataProvider(&socket); |
+ |
+ net::TestDelegate test_delegate; |
+ std::unique_ptr<net::URLRequest> request = context()->CreateRequest( |
+ GURL("http://example.com"), net::RequestPriority::IDLE, &test_delegate); |
+ |
+ request->Start(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ EXPECT_EQ(test.expected_savings, GetSavings()) << (&test - tests); |
+ } |
+} |
+ |
+TEST_F(DataReductionProxyNetworkDelegateClientLoFiTest, DataSavingsThroughDRP) { |
+ Reset(); |
+ drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
+ SetUpLoFiDecider(true, false); |
+ |
+ const char kHeaders[] = |
+ "HTTP/1.1 206 Partial Content\r\n" |
+ "Content-Range: bytes 0-2047/10000\r\n" |
+ "Content-Length: 2048\r\n" |
+ "Via: 1.1 Chrome-Compression-Proxy\r\n" |
+ "X-Original-Content-Length: 3000\r\n\r\n"; |
+ |
+ std::string response_body(2048, 'a'); |
+ net::MockRead reads[] = {net::MockRead(kHeaders), |
+ net::MockRead(response_body.c_str()), |
+ net::MockRead(net::ASYNC, net::OK)}; |
+ net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); |
+ mock_socket_factory()->AddSocketDataProvider(&socket); |
+ |
+ net::TestDelegate test_delegate; |
+ std::unique_ptr<net::URLRequest> request = context()->CreateRequest( |
+ GURL("http://example.com"), net::RequestPriority::IDLE, &test_delegate); |
+ |
+ request->Start(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Since the Data Reduction Proxy is enabled, the length of the raw headers |
+ // should be used in the estimated original size. The X-OCL should be ignored. |
+ EXPECT_EQ(static_cast<int64_t>(net::HttpUtil::AssembleRawHeaders( |
+ kHeaders, sizeof(kHeaders) - 1) |
+ .size() + |
+ 10000 - request->GetTotalReceivedBytes()), |
+ GetSavings()); |
+} |
+ |
} // namespace |
} // namespace data_reduction_proxy |