OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_netw
ork_delegate.h" | 5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_netw
ork_delegate.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 #elif defined(OS_QNX) | 127 #elif defined(OS_QNX) |
128 const Client kClient = Client::CHROME_QNX; | 128 const Client kClient = Client::CHROME_QNX; |
129 #else | 129 #else |
130 const Client kClient = Client::UNKNOWN; | 130 const Client kClient = Client::UNKNOWN; |
131 #endif | 131 #endif |
132 | 132 |
133 class TestLoFiDecider : public LoFiDecider { | 133 class TestLoFiDecider : public LoFiDecider { |
134 public: | 134 public: |
135 TestLoFiDecider() | 135 TestLoFiDecider() |
136 : should_be_client_lofi_(false), | 136 : should_be_client_lofi_(false), |
| 137 should_be_client_lofi_auto_reload_(false), |
137 should_request_lofi_resource_(false), | 138 should_request_lofi_resource_(false), |
138 ignore_is_using_data_reduction_proxy_check_(false) {} | 139 ignore_is_using_data_reduction_proxy_check_(false) {} |
139 ~TestLoFiDecider() override {} | 140 ~TestLoFiDecider() override {} |
140 | 141 |
141 bool IsUsingLoFi(const net::URLRequest& request) const override { | 142 bool IsUsingLoFi(const net::URLRequest& request) const override { |
142 return should_request_lofi_resource_; | 143 return should_request_lofi_resource_; |
143 } | 144 } |
144 | 145 |
145 void SetIsUsingLoFi(bool should_request_lofi_resource) { | 146 void SetIsUsingLoFi(bool should_request_lofi_resource) { |
146 should_request_lofi_resource_ = should_request_lofi_resource; | 147 should_request_lofi_resource_ = should_request_lofi_resource; |
147 } | 148 } |
148 | 149 |
149 void SetIsUsingClientLoFi(bool should_be_client_lofi) { | 150 void SetIsUsingClientLoFi(bool should_be_client_lofi) { |
150 should_be_client_lofi_ = should_be_client_lofi; | 151 should_be_client_lofi_ = should_be_client_lofi; |
151 } | 152 } |
152 | 153 |
| 154 void SetIsClientLoFiAutoReload(bool should_be_client_lofi_auto_reload) { |
| 155 should_be_client_lofi_auto_reload_ = should_be_client_lofi_auto_reload; |
| 156 } |
| 157 |
153 void MaybeSetAcceptTransformHeader( | 158 void MaybeSetAcceptTransformHeader( |
154 const net::URLRequest& request, | 159 const net::URLRequest& request, |
155 bool is_previews_disabled, | 160 bool is_previews_disabled, |
156 net::HttpRequestHeaders* headers) const override { | 161 net::HttpRequestHeaders* headers) const override { |
157 if (should_request_lofi_resource_) { | 162 if (should_request_lofi_resource_) { |
158 headers->SetHeader(chrome_proxy_accept_transform_header(), | 163 headers->SetHeader(chrome_proxy_accept_transform_header(), |
159 empty_image_directive()); | 164 empty_image_directive()); |
160 } | 165 } |
161 } | 166 } |
162 | 167 |
(...skipping 28 matching lines...) Expand all Loading... |
191 net::HttpRequestHeaders* headers) const override {} | 196 net::HttpRequestHeaders* headers) const override {} |
192 | 197 |
193 bool ShouldRecordLoFiUMA(const net::URLRequest& request) const override { | 198 bool ShouldRecordLoFiUMA(const net::URLRequest& request) const override { |
194 return should_request_lofi_resource_; | 199 return should_request_lofi_resource_; |
195 } | 200 } |
196 | 201 |
197 bool IsClientLoFiImageRequest(const net::URLRequest& request) const override { | 202 bool IsClientLoFiImageRequest(const net::URLRequest& request) const override { |
198 return should_be_client_lofi_; | 203 return should_be_client_lofi_; |
199 } | 204 } |
200 | 205 |
| 206 bool IsClientLoFiAutoReloadRequest( |
| 207 const net::URLRequest& request) const override { |
| 208 return should_be_client_lofi_auto_reload_; |
| 209 } |
| 210 |
201 void ignore_is_using_data_reduction_proxy_check() { | 211 void ignore_is_using_data_reduction_proxy_check() { |
202 ignore_is_using_data_reduction_proxy_check_ = true; | 212 ignore_is_using_data_reduction_proxy_check_ = true; |
203 } | 213 } |
204 | 214 |
205 private: | 215 private: |
206 bool should_be_client_lofi_; | 216 bool should_be_client_lofi_; |
| 217 bool should_be_client_lofi_auto_reload_; |
207 bool should_request_lofi_resource_; | 218 bool should_request_lofi_resource_; |
208 bool ignore_is_using_data_reduction_proxy_check_; | 219 bool ignore_is_using_data_reduction_proxy_check_; |
209 }; | 220 }; |
210 | 221 |
211 class TestLoFiUIService : public LoFiUIService { | 222 class TestLoFiUIService : public LoFiUIService { |
212 public: | 223 public: |
213 TestLoFiUIService() : on_lofi_response_(false) {} | 224 TestLoFiUIService() : on_lofi_response_(false) {} |
214 ~TestLoFiUIService() override {} | 225 ~TestLoFiUIService() override {} |
215 | 226 |
216 bool DidNotifyLoFiResponse() const { return on_lofi_response_; } | 227 bool DidNotifyLoFiResponse() const { return on_lofi_response_; } |
217 | 228 |
218 void OnLoFiReponseReceived(const net::URLRequest& request) override { | 229 void OnLoFiReponseReceived(const net::URLRequest& request) override { |
219 on_lofi_response_ = true; | 230 on_lofi_response_ = true; |
220 } | 231 } |
221 | 232 |
222 void ClearResponse() { on_lofi_response_ = false; } | 233 void ClearResponse() { on_lofi_response_ = false; } |
223 | 234 |
224 private: | 235 private: |
225 bool on_lofi_response_; | 236 bool on_lofi_response_; |
226 }; | 237 }; |
227 | 238 |
228 enum ProxyTestConfig { USE_SECURE_PROXY, USE_INSECURE_PROXY, BYPASS_PROXY }; | 239 enum ProxyTestConfig { USE_SECURE_PROXY, USE_INSECURE_PROXY, BYPASS_PROXY }; |
229 | 240 |
230 class DataReductionProxyNetworkDelegateTest : public testing::Test { | 241 class DataReductionProxyNetworkDelegateTest : public testing::Test { |
231 public: | 242 public: |
232 DataReductionProxyNetworkDelegateTest() | 243 DataReductionProxyNetworkDelegateTest() |
233 : context_(true), | 244 : context_(true), |
234 context_storage_(&context_), | 245 context_storage_(&context_), |
| 246 lofi_decider_(nullptr), |
| 247 lofi_ui_service_(nullptr), |
235 ssl_socket_data_provider_(net::ASYNC, net::OK) { | 248 ssl_socket_data_provider_(net::ASYNC, net::OK) { |
236 ssl_socket_data_provider_.next_proto = net::kProtoHTTP11; | 249 ssl_socket_data_provider_.next_proto = net::kProtoHTTP11; |
237 ssl_socket_data_provider_.cert = net::ImportCertFromFile( | 250 ssl_socket_data_provider_.cert = net::ImportCertFromFile( |
238 net::GetTestCertsDirectory(), "unittest.selfsigned.der"); | 251 net::GetTestCertsDirectory(), "unittest.selfsigned.der"); |
239 } | 252 } |
240 | 253 |
241 void Init(ProxyTestConfig proxy_config, bool enable_brotli_globally) { | 254 void Init(ProxyTestConfig proxy_config, bool enable_brotli_globally) { |
242 net::ProxyServer proxy_server; | 255 net::ProxyServer proxy_server; |
243 switch (proxy_config) { | 256 switch (proxy_config) { |
244 case BYPASS_PROXY: | 257 case BYPASS_PROXY: |
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 | 1659 |
1647 // When the ECT is set to the same value, fetching the same resource should | 1660 // When the ECT is set to the same value, fetching the same resource should |
1648 // result in a cache hit. | 1661 // result in a cache hit. |
1649 FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true); | 1662 FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true); |
1650 | 1663 |
1651 // When the ECT is set to a different value, the response should still be | 1664 // When the ECT is set to a different value, the response should still be |
1652 // served from the cache. | 1665 // served from the cache. |
1653 FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true); | 1666 FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true); |
1654 } | 1667 } |
1655 | 1668 |
| 1669 class DataReductionProxyNetworkDelegateClientLoFiTest : public testing::Test { |
| 1670 public: |
| 1671 DataReductionProxyNetworkDelegateClientLoFiTest() : baseline_savings_(0) {} |
| 1672 ~DataReductionProxyNetworkDelegateClientLoFiTest() override; |
| 1673 |
| 1674 void Reset() { |
| 1675 drp_test_context_.reset(); |
| 1676 mock_socket_factory_.reset(); |
| 1677 context_storage_.reset(); |
| 1678 |
| 1679 context_.reset(new net::TestURLRequestContext(true)); |
| 1680 context_storage_.reset(new net::URLRequestContextStorage(context_.get())); |
| 1681 mock_socket_factory_.reset(new net::MockClientSocketFactory()); |
| 1682 context_->set_client_socket_factory(mock_socket_factory_.get()); |
| 1683 |
| 1684 drp_test_context_ = |
| 1685 DataReductionProxyTestContext::Builder() |
| 1686 .WithURLRequestContext(context_.get()) |
| 1687 .WithMockClientSocketFactory(mock_socket_factory_.get()) |
| 1688 .Build(); |
| 1689 |
| 1690 drp_test_context_->AttachToURLRequestContext(context_storage_.get()); |
| 1691 context_->Init(); |
| 1692 base::RunLoop().RunUntilIdle(); |
| 1693 |
| 1694 baseline_savings_ = |
| 1695 drp_test_context()->settings()->GetTotalHttpContentLengthSaved(); |
| 1696 } |
| 1697 |
| 1698 void SetUpLoFiDecider(bool is_client_lofi_image, |
| 1699 bool is_client_lofi_auto_reload) const { |
| 1700 std::unique_ptr<TestLoFiDecider> lofi_decider(new TestLoFiDecider()); |
| 1701 lofi_decider->SetIsUsingClientLoFi(is_client_lofi_image); |
| 1702 lofi_decider->SetIsClientLoFiAutoReload(is_client_lofi_auto_reload); |
| 1703 drp_test_context_->io_data()->set_lofi_decider( |
| 1704 std::unique_ptr<LoFiDecider>(std::move(lofi_decider))); |
| 1705 } |
| 1706 |
| 1707 int64_t GetSavings() const { |
| 1708 return drp_test_context()->settings()->GetTotalHttpContentLengthSaved() - |
| 1709 baseline_savings_; |
| 1710 } |
| 1711 |
| 1712 net::TestURLRequestContext* context() const { return context_.get(); } |
| 1713 net::MockClientSocketFactory* mock_socket_factory() const { |
| 1714 return mock_socket_factory_.get(); |
| 1715 } |
| 1716 DataReductionProxyTestContext* drp_test_context() const { |
| 1717 return drp_test_context_.get(); |
| 1718 } |
| 1719 |
| 1720 private: |
| 1721 base::MessageLoopForIO loop; |
| 1722 std::unique_ptr<net::TestURLRequestContext> context_; |
| 1723 std::unique_ptr<net::URLRequestContextStorage> context_storage_; |
| 1724 std::unique_ptr<net::MockClientSocketFactory> mock_socket_factory_; |
| 1725 std::unique_ptr<DataReductionProxyTestContext> drp_test_context_; |
| 1726 int64_t baseline_savings_; |
| 1727 }; |
| 1728 |
| 1729 DataReductionProxyNetworkDelegateClientLoFiTest:: |
| 1730 ~DataReductionProxyNetworkDelegateClientLoFiTest() {} |
| 1731 |
| 1732 TEST_F(DataReductionProxyNetworkDelegateClientLoFiTest, DataSavingsNonDRP) { |
| 1733 const char kSimple200ResponseHeaders[] = |
| 1734 "HTTP/1.1 200 OK\r\n" |
| 1735 "Content-Length: 140\r\n\r\n"; |
| 1736 |
| 1737 const struct { |
| 1738 const char* headers; |
| 1739 size_t response_length; |
| 1740 bool is_client_lofi_image; |
| 1741 bool is_client_lofi_auto_reload; |
| 1742 int64_t expected_savings; |
| 1743 } tests[] = { |
| 1744 // 200 responses shouldn't see any savings. |
| 1745 {kSimple200ResponseHeaders, 140, false, false, 0}, |
| 1746 {kSimple200ResponseHeaders, 140, true, false, 0}, |
| 1747 |
| 1748 // Client Lo-Fi Auto-reload responses should see negative savings. |
| 1749 {kSimple200ResponseHeaders, 140, false, true, |
| 1750 -(static_cast<int64_t>(sizeof(kSimple200ResponseHeaders) - 1) + 140)}, |
| 1751 {kSimple200ResponseHeaders, 140, true, true, |
| 1752 -(static_cast<int64_t>(sizeof(kSimple200ResponseHeaders) - 1) + 140)}, |
| 1753 |
| 1754 // A range response that doesn't use Client Lo-Fi shouldn't see any |
| 1755 // savings. |
| 1756 {"HTTP/1.1 206 Partial Content\r\n" |
| 1757 "Content-Range: bytes 0-2047/10000\r\n" |
| 1758 "Content-Length: 2048\r\n\r\n", |
| 1759 2048, false, false, 0}, |
| 1760 |
| 1761 // A Client Lo-Fi range response should see savings based on the |
| 1762 // Content-Range header. |
| 1763 {"HTTP/1.1 206 Partial Content\r\n" |
| 1764 "Content-Range: bytes 0-2047/10000\r\n" |
| 1765 "Content-Length: 2048\r\n\r\n", |
| 1766 2048, true, false, 10000 - 2048}, |
| 1767 |
| 1768 // A Client Lo-Fi range response should see savings based on the |
| 1769 // Content-Range header, which in this case is 0 savings because the range |
| 1770 // response contained the entire resource. |
| 1771 {"HTTP/1.1 206 Partial Content\r\n" |
| 1772 "Content-Range: bytes 0-999/1000\r\n" |
| 1773 "Content-Length: 1000\r\n\r\n", |
| 1774 1000, true, false, 0}, |
| 1775 |
| 1776 // Client Lo-Fi range responses that don't have a Content-Range with the |
| 1777 // full resource length shouldn't see any savings. |
| 1778 {"HTTP/1.1 206 Partial Content\r\n" |
| 1779 "Content-Length: 2048\r\n\r\n", |
| 1780 2048, true, false, 0}, |
| 1781 {"HTTP/1.1 206 Partial Content\r\n" |
| 1782 "Content-Range: bytes 0-2047/*\r\n" |
| 1783 "Content-Length: 2048\r\n\r\n", |
| 1784 2048, true, false, 0}, |
| 1785 {"HTTP/1.1 206 Partial Content\r\n" |
| 1786 "Content-Range: invalid_content_range\r\n" |
| 1787 "Content-Length: 2048\r\n\r\n", |
| 1788 2048, true, false, 0}, |
| 1789 }; |
| 1790 |
| 1791 for (const auto& test : tests) { |
| 1792 Reset(); |
| 1793 SetUpLoFiDecider(test.is_client_lofi_image, |
| 1794 test.is_client_lofi_auto_reload); |
| 1795 |
| 1796 std::string response_body(test.response_length, 'a'); |
| 1797 net::MockRead reads[] = {net::MockRead(test.headers), |
| 1798 net::MockRead(response_body.c_str()), |
| 1799 net::MockRead(net::ASYNC, net::OK)}; |
| 1800 net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); |
| 1801 mock_socket_factory()->AddSocketDataProvider(&socket); |
| 1802 |
| 1803 net::TestDelegate test_delegate; |
| 1804 std::unique_ptr<net::URLRequest> request = context()->CreateRequest( |
| 1805 GURL("http://example.com"), net::RequestPriority::IDLE, &test_delegate); |
| 1806 |
| 1807 request->Start(); |
| 1808 base::RunLoop().RunUntilIdle(); |
| 1809 |
| 1810 EXPECT_EQ(test.expected_savings, GetSavings()) << (&test - tests); |
| 1811 } |
| 1812 } |
| 1813 |
| 1814 TEST_F(DataReductionProxyNetworkDelegateClientLoFiTest, DataSavingsThroughDRP) { |
| 1815 Reset(); |
| 1816 drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| 1817 SetUpLoFiDecider(true, false); |
| 1818 |
| 1819 const char kHeaders[] = |
| 1820 "HTTP/1.1 206 Partial Content\r\n" |
| 1821 "Content-Range: bytes 0-2047/10000\r\n" |
| 1822 "Content-Length: 2048\r\n" |
| 1823 "Via: 1.1 Chrome-Compression-Proxy\r\n" |
| 1824 "X-Original-Content-Length: 3000\r\n\r\n"; |
| 1825 |
| 1826 std::string response_body(2048, 'a'); |
| 1827 net::MockRead reads[] = {net::MockRead(kHeaders), |
| 1828 net::MockRead(response_body.c_str()), |
| 1829 net::MockRead(net::ASYNC, net::OK)}; |
| 1830 net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); |
| 1831 mock_socket_factory()->AddSocketDataProvider(&socket); |
| 1832 |
| 1833 net::TestDelegate test_delegate; |
| 1834 std::unique_ptr<net::URLRequest> request = context()->CreateRequest( |
| 1835 GURL("http://example.com"), net::RequestPriority::IDLE, &test_delegate); |
| 1836 |
| 1837 request->Start(); |
| 1838 base::RunLoop().RunUntilIdle(); |
| 1839 |
| 1840 // Since the Data Reduction Proxy is enabled, the length of the raw headers |
| 1841 // should be used in the estimated original size. The X-OCL should be ignored. |
| 1842 EXPECT_EQ(static_cast<int64_t>(net::HttpUtil::AssembleRawHeaders( |
| 1843 kHeaders, sizeof(kHeaders) - 1) |
| 1844 .size() + |
| 1845 10000 - request->GetTotalReceivedBytes()), |
| 1846 GetSavings()); |
| 1847 } |
| 1848 |
1656 } // namespace | 1849 } // namespace |
1657 | 1850 |
1658 } // namespace data_reduction_proxy | 1851 } // namespace data_reduction_proxy |
OLD | NEW |