• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
6 
7 #include "net/http/http_response_headers.h"
8 #include "net/proxy/proxy_service.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 namespace {
12 
13 // Transform "normal"-looking headers (\n-separated) to the appropriate
14 // input format for ParseRawHeaders (\0-separated).
HeadersToRaw(std::string * headers)15 void HeadersToRaw(std::string* headers) {
16   std::replace(headers->begin(), headers->end(), '\n', '\0');
17   if (!headers->empty())
18     *headers += '\0';
19 }
20 
21 }  // namespace
22 
23 namespace data_reduction_proxy {
24 
25 class DataReductionProxyHeadersTest : public testing::Test {};
26 
TEST_F(DataReductionProxyHeadersTest,GetProxyBypassInfo)27 TEST_F(DataReductionProxyHeadersTest, GetProxyBypassInfo) {
28   const struct {
29      const char* headers;
30      bool expected_result;
31      int64 expected_retry_delay;
32      bool expected_bypass_all;
33   } tests[] = {
34     { "HTTP/1.1 200 OK\n"
35       "Content-Length: 999\n",
36       false,
37       0,
38       false,
39     },
40     { "HTTP/1.1 200 OK\n"
41       "connection: keep-alive\n"
42       "Content-Length: 999\n",
43       false,
44       0,
45       false,
46     },
47     { "HTTP/1.1 200 OK\n"
48       "connection: keep-alive\n"
49       "Chrome-Proxy: bypass=86400\n"
50       "Content-Length: 999\n",
51       true,
52       86400,
53       false,
54     },
55     { "HTTP/1.1 200 OK\n"
56       "connection: keep-alive\n"
57       "Chrome-Proxy: bypass=0\n"
58       "Content-Length: 999\n",
59       true,
60       0,
61       false,
62     },
63     { "HTTP/1.1 200 OK\n"
64       "connection: keep-alive\n"
65       "Chrome-Proxy: bypass=-1\n"
66       "Content-Length: 999\n",
67       false,
68       0,
69       false,
70     },
71     { "HTTP/1.1 200 OK\n"
72       "connection: keep-alive\n"
73       "Chrome-Proxy: bypass=xyz\n"
74       "Content-Length: 999\n",
75       false,
76       0,
77       false,
78     },
79     { "HTTP/1.1 200 OK\n"
80       "connection: keep-alive\n"
81       "Chrome-Proxy: bypass\n"
82       "Content-Length: 999\n",
83       false,
84       0,
85       false,
86     },
87     { "HTTP/1.1 200 OK\n"
88       "connection: keep-alive\n"
89       "Chrome-Proxy: foo=abc, bypass=86400\n"
90       "Content-Length: 999\n",
91       true,
92       86400,
93       false,
94     },
95     { "HTTP/1.1 200 OK\n"
96       "connection: keep-alive\n"
97       "Chrome-Proxy: bypass=86400, bar=abc\n"
98       "Content-Length: 999\n",
99       true,
100       86400,
101       false,
102     },
103     { "HTTP/1.1 200 OK\n"
104       "connection: keep-alive\n"
105       "Chrome-Proxy: bypass=3600\n"
106       "Chrome-Proxy: bypass=86400\n"
107       "Content-Length: 999\n",
108       true,
109       3600,
110       false,
111     },
112     { "HTTP/1.1 200 OK\n"
113       "connection: keep-alive\n"
114       "Chrome-Proxy: bypass=3600, bypass=86400\n"
115       "Content-Length: 999\n",
116       true,
117       3600,
118       false,
119     },
120     { "HTTP/1.1 200 OK\n"
121       "connection: keep-alive\n"
122       "Chrome-Proxy: bypass=, bypass=86400\n"
123       "Content-Length: 999\n",
124       true,
125       86400,
126       false,
127     },
128     { "HTTP/1.1 200 OK\n"
129       "connection: keep-alive\n"
130       "Chrome-Proxy: bypass\n"
131       "Chrome-Proxy: bypass=86400\n"
132       "Content-Length: 999\n",
133       true,
134       86400,
135       false,
136     },
137     { "HTTP/1.1 200 OK\n"
138       "connection: keep-alive\n"
139       "Chrome-Proxy: block=, block=3600\n"
140       "Content-Length: 999\n",
141       true,
142       3600,
143       true,
144     },
145     { "HTTP/1.1 200 OK\n"
146       "connection: keep-alive\n"
147       "Chrome-Proxy: bypass=86400, block=3600\n"
148       "Content-Length: 999\n",
149       true,
150       3600,
151       true,
152     },
153     { "HTTP/1.1 200 OK\n"
154       "connection: proxy-bypass\n"
155       "Chrome-Proxy: block=, bypass=86400\n"
156       "Content-Length: 999\n",
157       true,
158       86400,
159       false,
160     },
161     { "HTTP/1.1 200 OK\n"
162       "connection: proxy-bypass\n"
163       "Chrome-Proxy: block=-1\n"
164       "Content-Length: 999\n",
165       false,
166       0,
167       false,
168     },
169     { "HTTP/1.1 200 OK\n"
170       "connection: proxy-bypass\n"
171       "Chrome-Proxy: block=99999999999999999999\n"
172       "Content-Length: 999\n",
173       false,
174       0,
175       false,
176     },
177   };
178   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
179     std::string headers(tests[i].headers);
180     HeadersToRaw(&headers);
181     scoped_refptr<net::HttpResponseHeaders> parsed(
182         new net::HttpResponseHeaders(headers));
183 
184     DataReductionProxyInfo data_reduction_proxy_info;
185     EXPECT_EQ(tests[i].expected_result,
186               GetDataReductionProxyInfo(parsed, &data_reduction_proxy_info));
187     EXPECT_EQ(tests[i].expected_retry_delay,
188               data_reduction_proxy_info.bypass_duration.InSeconds());
189     EXPECT_EQ(tests[i].expected_bypass_all,
190               data_reduction_proxy_info.bypass_all);
191   }
192 }
193 
TEST_F(DataReductionProxyHeadersTest,HasDataReductionProxyViaHeader)194 TEST_F(DataReductionProxyHeadersTest, HasDataReductionProxyViaHeader) {
195   const struct {
196      const char* headers;
197      bool expected_result;
198   } tests[] = {
199     { "HTTP/1.1 200 OK\n"
200       "Via: 1.1 Chrome-Proxy\n",
201       false,
202     },
203     { "HTTP/1.1 200 OK\n"
204       "Via: 1\n",
205       false,
206     },
207     { "HTTP/1.1 200 OK\n"
208       "Via: 1.1 Chrome-Compression-Proxy\n",
209       true,
210     },
211     { "HTTP/1.1 200 OK\n"
212       "Via: 1.0 Chrome-Compression-Proxy\n",
213       true,
214     },
215     { "HTTP/1.1 200 OK\n"
216       "Via: 1.1 Foo-Bar, 1.1 Chrome-Compression-Proxy\n",
217       true,
218     },
219     { "HTTP/1.1 200 OK\n"
220       "Via: 1.1 Chrome-Compression-Proxy, 1.1 Bar-Foo\n",
221       true,
222     },
223     { "HTTP/1.1 200 OK\n"
224       "Via: 1.1 chrome-compression-proxy\n",
225       false,
226     },
227     { "HTTP/1.1 200 OK\n"
228       "Via: 1.1 Foo-Bar\n"
229       "Via: 1.1 Chrome-Compression-Proxy\n",
230       true,
231     },
232     { "HTTP/1.1 200 OK\n"
233       "Via: 1.1 Chrome-Proxy\n",
234       false,
235     },
236     { "HTTP/1.1 200 OK\n"
237       "Via: 1.1 Chrome Compression Proxy\n",
238       true,
239     },
240     { "HTTP/1.1 200 OK\n"
241       "Via: 1.1 Foo-Bar, 1.1 Chrome Compression Proxy\n",
242       true,
243     },
244     { "HTTP/1.1 200 OK\n"
245       "Via: 1.1 Chrome Compression Proxy, 1.1 Bar-Foo\n",
246       true,
247     },
248     { "HTTP/1.1 200 OK\n"
249       "Via: 1.1 chrome compression proxy\n",
250       false,
251     },
252     { "HTTP/1.1 200 OK\n"
253       "Via: 1.1 Foo-Bar\n"
254       "Via: 1.1 Chrome Compression Proxy\n",
255       true,
256     },
257   };
258   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
259     std::string headers(tests[i].headers);
260     HeadersToRaw(&headers);
261     scoped_refptr<net::HttpResponseHeaders> parsed(
262         new net::HttpResponseHeaders(headers));
263 
264     EXPECT_EQ(tests[i].expected_result,
265               HasDataReductionProxyViaHeader(parsed));
266   }
267 }
268 
TEST_F(DataReductionProxyHeadersTest,GetDataReductionProxyBypassEventType)269 TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyBypassEventType) {
270   const struct {
271      const char* headers;
272      net::ProxyService::DataReductionProxyBypassEventType expected_result;
273   } tests[] = {
274     { "HTTP/1.1 200 OK\n"
275       "Chrome-Proxy: bypass=0\n"
276       "Via: 1.1 Chrome-Compression-Proxy\n",
277       net::ProxyService::SHORT_BYPASS,
278     },
279     { "HTTP/1.1 200 OK\n"
280       "Chrome-Proxy: bypass=1799\n"
281       "Via: 1.1 Chrome-Compression-Proxy\n",
282       net::ProxyService::SHORT_BYPASS,
283     },
284     { "HTTP/1.1 200 OK\n"
285       "Chrome-Proxy: bypass=1800\n"
286       "Via: 1.1 Chrome-Compression-Proxy\n",
287       net::ProxyService::LONG_BYPASS,
288     },
289     { "HTTP/1.1 500 Internal Server Error\n"
290       "Via: 1.1 Chrome-Compression-Proxy\n",
291       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
292     },
293     { "HTTP/1.1 501 Not Implemented\n"
294       "Via: 1.1 Chrome-Compression-Proxy\n",
295       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
296     },
297     { "HTTP/1.1 502 Bad Gateway\n"
298       "Via: 1.1 Chrome-Compression-Proxy\n",
299       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
300     },
301     { "HTTP/1.1 503 Service Unavailable\n"
302       "Via: 1.1 Chrome-Compression-Proxy\n",
303       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
304     },
305     { "HTTP/1.1 504 Gateway Timeout\n"
306       "Via: 1.1 Chrome-Compression-Proxy\n",
307       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
308     },
309     { "HTTP/1.1 505 HTTP Version Not Supported\n"
310       "Via: 1.1 Chrome-Compression-Proxy\n",
311       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
312     },
313     { "HTTP/1.1 304 Not Modified\n",
314         net::ProxyService::BYPASS_EVENT_TYPE_MAX,
315     },
316     { "HTTP/1.1 200 OK\n",
317         net::ProxyService::MISSING_VIA_HEADER,
318     },
319     { "HTTP/1.1 200 OK\n"
320       "Chrome-Proxy: bypass=1799\n",
321       net::ProxyService::SHORT_BYPASS,
322     },
323     { "HTTP/1.1 502 Bad Gateway\n",
324       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
325     },
326     { "HTTP/1.1 502 Bad Gateway\n"
327       "Chrome-Proxy: bypass=1799\n",
328       net::ProxyService::SHORT_BYPASS,
329     },
330     { "HTTP/1.1 502 Bad Gateway\n"
331       "Chrome-Proxy: bypass=1799\n",
332       net::ProxyService::SHORT_BYPASS,
333     },
334     { "HTTP/1.1 414 Request-URI Too Long\n",
335       net::ProxyService::PROXY_4XX_BYPASS,
336     },
337     { "HTTP/1.1 414 Request-URI Too Long\n"
338       "Via: 1.1 Chrome-Compression-Proxy\n",
339       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
340     },
341     { "HTTP/1.1 407 Proxy Authentication Required\n",
342       net::ProxyService::MALFORMED_407_BYPASS,
343     },
344     { "HTTP/1.1 407 Proxy Authentication Required\n"
345       "Proxy-Authenticate: Basic\n"
346       "Via: 1.1 Chrome-Compression-Proxy\n",
347       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
348     }
349   };
350   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
351     std::string headers(tests[i].headers);
352     HeadersToRaw(&headers);
353     scoped_refptr<net::HttpResponseHeaders> parsed(
354         new net::HttpResponseHeaders(headers));
355     DataReductionProxyInfo chrome_proxy_info;
356     EXPECT_EQ(tests[i].expected_result,
357               GetDataReductionProxyBypassEventType(parsed, &chrome_proxy_info));
358   }
359 }
360 }  // namespace data_reduction_proxy
361