Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / components / data_reduction_proxy / common / data_reduction_proxy_headers_unittest.cc
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 <vector>
8
9 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers_test_utils.h"
10 #include "net/http/http_response_headers.h"
11 #include "net/proxy/proxy_service.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace data_reduction_proxy {
15
16 class DataReductionProxyHeadersTest : public testing::Test {};
17
18 TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyActionValue) {
19   const struct {
20      const char* headers;
21      std::string action_key;
22      bool expected_result;
23      std::string expected_action_value;
24   } tests[] = {
25     { "HTTP/1.1 200 OK\n"
26       "Content-Length: 999\n",
27       "a",
28       false,
29       "",
30     },
31     { "HTTP/1.1 200 OK\n"
32       "connection: keep-alive\n"
33       "Content-Length: 999\n",
34       "a",
35       false,
36       "",
37     },
38     { "HTTP/1.1 200 OK\n"
39       "connection: keep-alive\n"
40       "Chrome-Proxy: bypass=86400\n"
41       "Content-Length: 999\n",
42       "bypass",
43       true,
44       "86400",
45     },
46     { "HTTP/1.1 200 OK\n"
47       "connection: keep-alive\n"
48       "Chrome-Proxy: bypass86400\n"
49       "Content-Length: 999\n",
50       "bypass",
51       false,
52       "",
53     },
54     { "HTTP/1.1 200 OK\n"
55       "connection: keep-alive\n"
56       "Chrome-Proxy: bypass=0\n"
57       "Content-Length: 999\n",
58       "bypass",
59       true,
60       "0",
61     },
62     { "HTTP/1.1 200 OK\n"
63       "connection: keep-alive\n"
64       "Chrome-Proxy: bypass=1500\n"
65       "Chrome-Proxy: bypass=86400\n"
66       "Content-Length: 999\n",
67       "bypass",
68       true,
69       "1500",
70     },
71     { "HTTP/1.1 200 OK\n"
72       "connection: keep-alive\n"
73       "Chrome-Proxy: block=1500, block=3600\n"
74       "Content-Length: 999\n",
75       "block",
76       true,
77       "1500",
78     },
79     { "HTTP/1.1 200 OK\n"
80       "connection: proxy-bypass\n"
81       "Chrome-Proxy:    key=123   \n"
82       "Content-Length: 999\n",
83       "key",
84       true,
85       "123",
86     },
87     { "HTTP/1.1 200 OK\n"
88       "connection: proxy-bypass\n"
89       "Chrome-Proxy: block-once\n"
90       "Content-Length: 999\n",
91       "block-once",
92       false,
93       "",
94     },
95   };
96   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
97     std::string headers(tests[i].headers);
98     HeadersToRaw(&headers);
99     scoped_refptr<net::HttpResponseHeaders> parsed(
100         new net::HttpResponseHeaders(headers));
101
102     std::string action_value;
103     bool has_action_key = GetDataReductionProxyActionValue(
104         parsed.get(), tests[i].action_key, &action_value);
105     EXPECT_EQ(tests[i].expected_result, has_action_key);
106     if (has_action_key) {
107       EXPECT_EQ(tests[i].expected_action_value, action_value);
108     }
109   }
110 }
111
112 TEST_F(DataReductionProxyHeadersTest, GetProxyBypassInfo) {
113   const struct {
114      const char* headers;
115      bool expected_result;
116      int64 expected_retry_delay;
117      bool expected_bypass_all;
118      bool expected_mark_proxies_as_bad;
119   } tests[] = {
120     { "HTTP/1.1 200 OK\n"
121       "Content-Length: 999\n",
122       false,
123       0,
124       false,
125       false,
126     },
127     { "HTTP/1.1 200 OK\n"
128       "connection: keep-alive\n"
129       "Content-Length: 999\n",
130       false,
131       0,
132       false,
133       false,
134     },
135     { "HTTP/1.1 200 OK\n"
136       "connection: keep-alive\n"
137       "Chrome-Proxy: bypass=86400\n"
138       "Content-Length: 999\n",
139       true,
140       86400,
141       false,
142       true,
143     },
144     { "HTTP/1.1 200 OK\n"
145       "connection: keep-alive\n"
146       "Chrome-Proxy: bypass=-1\n"
147       "Content-Length: 999\n",
148       false,
149       0,
150       false,
151       false,
152     },
153     { "HTTP/1.1 200 OK\n"
154       "connection: keep-alive\n"
155       "Chrome-Proxy: bypass=xyz\n"
156       "Content-Length: 999\n",
157       false,
158       0,
159       false,
160       false,
161     },
162     { "HTTP/1.1 200 OK\n"
163       "connection: keep-alive\n"
164       "Chrome-Proxy: bypass\n"
165       "Content-Length: 999\n",
166       false,
167       0,
168       false,
169       false,
170     },
171     { "HTTP/1.1 200 OK\n"
172       "connection: keep-alive\n"
173       "Chrome-Proxy: foo=abc, bypass=86400\n"
174       "Content-Length: 999\n",
175       true,
176       86400,
177       false,
178       true,
179     },
180     { "HTTP/1.1 200 OK\n"
181       "connection: keep-alive\n"
182       "Chrome-Proxy: bypass=86400, bar=abc\n"
183       "Content-Length: 999\n",
184       true,
185       86400,
186       false,
187       true,
188     },
189     { "HTTP/1.1 200 OK\n"
190       "connection: keep-alive\n"
191       "Chrome-Proxy: bypass=3600\n"
192       "Chrome-Proxy: bypass=86400\n"
193       "Content-Length: 999\n",
194       true,
195       3600,
196       false,
197       true,
198     },
199     { "HTTP/1.1 200 OK\n"
200       "connection: keep-alive\n"
201       "Chrome-Proxy: bypass=3600, bypass=86400\n"
202       "Content-Length: 999\n",
203       true,
204       3600,
205       false,
206       true,
207     },
208     { "HTTP/1.1 200 OK\n"
209       "connection: keep-alive\n"
210       "Chrome-Proxy: bypass=, bypass=86400\n"
211       "Content-Length: 999\n",
212       true,
213       86400,
214       false,
215       true,
216     },
217     { "HTTP/1.1 200 OK\n"
218       "connection: keep-alive\n"
219       "Chrome-Proxy: bypass\n"
220       "Chrome-Proxy: bypass=86400\n"
221       "Content-Length: 999\n",
222       true,
223       86400,
224       false,
225       true,
226     },
227     { "HTTP/1.1 200 OK\n"
228       "connection: keep-alive\n"
229       "Chrome-Proxy: block=, block=3600\n"
230       "Content-Length: 999\n",
231       true,
232       3600,
233       true,
234       true,
235     },
236     { "HTTP/1.1 200 OK\n"
237       "connection: keep-alive\n"
238       "Chrome-Proxy: bypass=86400, block=3600\n"
239       "Content-Length: 999\n",
240       true,
241       3600,
242       true,
243       true,
244     },
245     { "HTTP/1.1 200 OK\n"
246       "connection: proxy-bypass\n"
247       "Chrome-Proxy: block=, bypass=86400\n"
248       "Content-Length: 999\n",
249       true,
250       86400,
251       false,
252       true,
253     },
254     { "HTTP/1.1 200 OK\n"
255       "connection: proxy-bypass\n"
256       "Chrome-Proxy: block=-1\n"
257       "Content-Length: 999\n",
258       false,
259       0,
260       false,
261       false,
262     },
263     { "HTTP/1.1 200 OK\n"
264       "connection: proxy-bypass\n"
265       "Chrome-Proxy: block=99999999999999999999\n"
266       "Content-Length: 999\n",
267       false,
268       0,
269       false,
270       false,
271     },
272     { "HTTP/1.1 200 OK\n"
273       "connection: keep-alive\n"
274       "Chrome-Proxy: block-once\n"
275       "Content-Length: 999\n",
276       true,
277       0,
278       true,
279       false,
280     },
281     { "HTTP/1.1 200 OK\n"
282       "connection: keep-alive\n"
283       "Chrome-Proxy: block-once=\n"
284       "Content-Length: 999\n",
285       false,
286       0,
287       false,
288       false,
289     },
290     { "HTTP/1.1 200 OK\n"
291       "connection: keep-alive\n"
292       "Chrome-Proxy: block-once=10\n"
293       "Content-Length: 999\n",
294       false,
295       0,
296       false,
297       false,
298     },
299     { "HTTP/1.1 200 OK\n"
300       "connection: keep-alive\n"
301       "Chrome-Proxy: block-once, bypass=86400, block=3600\n"
302       "Content-Length: 999\n",
303       true,
304       3600,
305       true,
306       true,
307     },
308     { "HTTP/1.1 200 OK\n"
309       "connection: keep-alive\n"
310       "Chrome-Proxy: block-once\n"
311       "Chrome-Proxy: bypass=86400, block=3600\n"
312       "Content-Length: 999\n",
313       true,
314       3600,
315       true,
316       true,
317     },
318     { "HTTP/1.1 200 OK\n"
319       "connection: keep-alive\n"
320       "Chrome-Proxy: block-once, bypass=86400\n"
321       "Content-Length: 999\n",
322       true,
323       86400,
324       false,
325       true,
326     },
327     { "HTTP/1.1 200 OK\n"
328       "connection: keep-alive\n"
329       "Chrome-Proxy: block-once, block=3600\n"
330       "Content-Length: 999\n",
331       true,
332       3600,
333       true,
334       true,
335     },
336     { "HTTP/1.1 200 OK\n"
337       "connection: keep-alive\n"
338       "Chrome-Proxy: bypass=, block=, block-once\n"
339       "Content-Length: 999\n",
340       true,
341       0,
342       true,
343       false,
344     },
345   };
346   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
347     std::string headers(tests[i].headers);
348     HeadersToRaw(&headers);
349     scoped_refptr<net::HttpResponseHeaders> parsed(
350         new net::HttpResponseHeaders(headers));
351
352     DataReductionProxyInfo data_reduction_proxy_info;
353     EXPECT_EQ(
354         tests[i].expected_result,
355         ParseHeadersAndSetProxyInfo(parsed.get(), &data_reduction_proxy_info));
356     EXPECT_EQ(tests[i].expected_retry_delay,
357               data_reduction_proxy_info.bypass_duration.InSeconds());
358     EXPECT_EQ(tests[i].expected_bypass_all,
359               data_reduction_proxy_info.bypass_all);
360     EXPECT_EQ(tests[i].expected_mark_proxies_as_bad,
361               data_reduction_proxy_info.mark_proxies_as_bad);
362   }
363 }
364
365 TEST_F(DataReductionProxyHeadersTest, ParseHeadersAndSetProxyInfo) {
366   std::string headers =
367       "HTTP/1.1 200 OK\n"
368       "connection: keep-alive\n"
369       "Chrome-Proxy: bypass=0\n"
370       "Content-Length: 999\n";
371   HeadersToRaw(&headers);
372   scoped_refptr<net::HttpResponseHeaders> parsed(
373       new net::HttpResponseHeaders(headers));
374
375   DataReductionProxyInfo data_reduction_proxy_info;
376   EXPECT_TRUE(
377       ParseHeadersAndSetProxyInfo(parsed.get(), &data_reduction_proxy_info));
378   EXPECT_LE(60, data_reduction_proxy_info.bypass_duration.InSeconds());
379   EXPECT_GE(5 * 60, data_reduction_proxy_info.bypass_duration.InSeconds());
380   EXPECT_FALSE(data_reduction_proxy_info.bypass_all);
381 }
382
383 TEST_F(DataReductionProxyHeadersTest, HasDataReductionProxyViaHeader) {
384   const struct {
385     const char* headers;
386     bool expected_result;
387     bool expected_has_intermediary;
388     bool ignore_intermediary;
389   } tests[] = {
390     { "HTTP/1.1 200 OK\n"
391       "Via: 1.1 Chrome-Proxy\n",
392       false,
393       false,
394       false,
395     },
396     { "HTTP/1.1 200 OK\n"
397       "Via: 1\n",
398       false,
399       false,
400       false,
401     },
402     { "HTTP/1.1 200 OK\n"
403       "Via: 1.1 Chrome-Compression-Proxy\n",
404       true,
405       true,
406       false,
407     },
408     { "HTTP/1.1 200 OK\n"
409       "Via: 1.0 Chrome-Compression-Proxy\n",
410       true,
411       true,
412       false,
413     },
414     { "HTTP/1.1 200 OK\n"
415       "Via: 1.1 Foo-Bar, 1.1 Chrome-Compression-Proxy\n",
416       true,
417       true,
418       false,
419     },
420     { "HTTP/1.1 200 OK\n"
421       "Via: 1.1 Chrome-Compression-Proxy, 1.1 Bar-Foo\n",
422       true,
423       false,
424       false,
425     },
426     { "HTTP/1.1 200 OK\n"
427       "Via: 1.1 chrome-compression-proxy\n",
428       false,
429       false,
430       false,
431     },
432     { "HTTP/1.1 200 OK\n"
433       "Via: 1.1 Foo-Bar\n"
434       "Via: 1.1 Chrome-Compression-Proxy\n",
435       true,
436       true,
437       false,
438     },
439     { "HTTP/1.1 200 OK\n"
440       "Via: 1.1 Chrome-Compression-Proxy\n"
441       "Via: 1.1 Foo-Bar\n",
442       true,
443       false,
444       false,
445     },
446     { "HTTP/1.1 200 OK\n"
447       "Via: 1.1 Chrome-Proxy\n",
448       false,
449       false,
450       false,
451     },
452     { "HTTP/1.1 200 OK\n"
453       "Via: 1.1 Chrome Compression Proxy\n",
454       true,
455       true,
456       false,
457     },
458     { "HTTP/1.1 200 OK\n"
459       "Via: 1.1 Foo-Bar, 1.1 Chrome Compression Proxy\n",
460       true,
461       true,
462       false,
463     },
464     { "HTTP/1.1 200 OK\n"
465       "Via: 1.1 Chrome Compression Proxy, 1.1 Bar-Foo\n",
466       true,
467       false,
468       false,
469     },
470     { "HTTP/1.1 200 OK\n"
471       "Via: 1.1 chrome compression proxy\n",
472       false,
473       false,
474       false,
475     },
476     { "HTTP/1.1 200 OK\n"
477       "Via: 1.1 Foo-Bar\n"
478       "Via: 1.1 Chrome Compression Proxy\n",
479       true,
480       true,
481       false,
482     },
483     { "HTTP/1.1 200 OK\n"
484       "Via: 1.1 Chrome Compression Proxy\n"
485       "Via: 1.1 Foo-Bar\n",
486       true,
487       false,
488       false,
489     },
490     { "HTTP/1.1 200 OK\n"
491       "Via: 1.1 Chrome Compression Proxy\n"
492       "Via: 1.1 Foo-Bar\n",
493       true,
494       false,
495       true,
496     },
497   };
498   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
499     std::string headers(tests[i].headers);
500     HeadersToRaw(&headers);
501     scoped_refptr<net::HttpResponseHeaders> parsed(
502         new net::HttpResponseHeaders(headers));
503
504     bool has_chrome_proxy_via_header, has_intermediary;
505     if (tests[i].ignore_intermediary) {
506       has_chrome_proxy_via_header =
507           HasDataReductionProxyViaHeader(parsed.get(), NULL);
508     }
509     else {
510       has_chrome_proxy_via_header =
511           HasDataReductionProxyViaHeader(parsed.get(), &has_intermediary);
512     }
513     EXPECT_EQ(tests[i].expected_result, has_chrome_proxy_via_header);
514     if (has_chrome_proxy_via_header && !tests[i].ignore_intermediary) {
515       EXPECT_EQ(tests[i].expected_has_intermediary, has_intermediary);
516     }
517   }
518 }
519
520 TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyBypassEventType) {
521   const struct {
522      const char* headers;
523      DataReductionProxyBypassType expected_result;
524   } tests[] = {
525     { "HTTP/1.1 200 OK\n"
526       "Chrome-Proxy: bypass=0\n"
527       "Via: 1.1 Chrome-Compression-Proxy\n",
528       BYPASS_EVENT_TYPE_MEDIUM,
529     },
530     { "HTTP/1.1 200 OK\n"
531       "Chrome-Proxy: bypass=1\n"
532       "Via: 1.1 Chrome-Compression-Proxy\n",
533       BYPASS_EVENT_TYPE_SHORT,
534     },
535     { "HTTP/1.1 200 OK\n"
536       "Chrome-Proxy: bypass=59\n"
537       "Via: 1.1 Chrome-Compression-Proxy\n",
538       BYPASS_EVENT_TYPE_SHORT,
539     },
540     { "HTTP/1.1 200 OK\n"
541       "Chrome-Proxy: bypass=60\n"
542       "Via: 1.1 Chrome-Compression-Proxy\n",
543       BYPASS_EVENT_TYPE_MEDIUM,
544     },
545     { "HTTP/1.1 200 OK\n"
546       "Chrome-Proxy: bypass=300\n"
547       "Via: 1.1 Chrome-Compression-Proxy\n",
548       BYPASS_EVENT_TYPE_MEDIUM,
549     },
550     { "HTTP/1.1 200 OK\n"
551       "Chrome-Proxy: bypass=301\n"
552       "Via: 1.1 Chrome-Compression-Proxy\n",
553       BYPASS_EVENT_TYPE_LONG,
554     },
555     { "HTTP/1.1 200 OK\n"
556       "Chrome-Proxy: block-once\n"
557       "Via: 1.1 Chrome-Compression-Proxy\n",
558       BYPASS_EVENT_TYPE_CURRENT,
559     },
560     { "HTTP/1.1 500 Internal Server Error\n"
561       "Via: 1.1 Chrome-Compression-Proxy\n",
562       BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR,
563     },
564     { "HTTP/1.1 501 Not Implemented\n"
565       "Via: 1.1 Chrome-Compression-Proxy\n",
566       BYPASS_EVENT_TYPE_MAX,
567     },
568     { "HTTP/1.1 502 Bad Gateway\n"
569       "Via: 1.1 Chrome-Compression-Proxy\n",
570       BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
571     },
572     { "HTTP/1.1 503 Service Unavailable\n"
573       "Via: 1.1 Chrome-Compression-Proxy\n",
574       BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE,
575     },
576     { "HTTP/1.1 504 Gateway Timeout\n"
577       "Via: 1.1 Chrome-Compression-Proxy\n",
578       BYPASS_EVENT_TYPE_MAX,
579     },
580     { "HTTP/1.1 505 HTTP Version Not Supported\n"
581       "Via: 1.1 Chrome-Compression-Proxy\n",
582       BYPASS_EVENT_TYPE_MAX,
583     },
584     { "HTTP/1.1 304 Not Modified\n",
585         BYPASS_EVENT_TYPE_MAX,
586     },
587     { "HTTP/1.1 200 OK\n",
588         BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER,
589     },
590     { "HTTP/1.1 200 OK\n"
591       "Chrome-Proxy: bypass=59\n",
592       BYPASS_EVENT_TYPE_SHORT,
593     },
594     { "HTTP/1.1 502 Bad Gateway\n",
595         BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
596     },
597     { "HTTP/1.1 502 Bad Gateway\n"
598       "Chrome-Proxy: bypass=59\n",
599       BYPASS_EVENT_TYPE_SHORT,
600     },
601     { "HTTP/1.1 502 Bad Gateway\n"
602       "Chrome-Proxy: bypass=59\n",
603       BYPASS_EVENT_TYPE_SHORT,
604     },
605     { "HTTP/1.1 414 Request-URI Too Long\n",
606         BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_4XX,
607     },
608     { "HTTP/1.1 414 Request-URI Too Long\n"
609       "Via: 1.1 Chrome-Compression-Proxy\n",
610       BYPASS_EVENT_TYPE_MAX,
611     },
612     { "HTTP/1.1 407 Proxy Authentication Required\n",
613         BYPASS_EVENT_TYPE_MALFORMED_407,
614     },
615     { "HTTP/1.1 407 Proxy Authentication Required\n"
616       "Proxy-Authenticate: Basic\n"
617       "Via: 1.1 Chrome-Compression-Proxy\n",
618       BYPASS_EVENT_TYPE_MAX,
619     }
620   };
621   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
622     std::string headers(tests[i].headers);
623     HeadersToRaw(&headers);
624     scoped_refptr<net::HttpResponseHeaders> parsed(
625         new net::HttpResponseHeaders(headers));
626     DataReductionProxyInfo chrome_proxy_info;
627     EXPECT_EQ(
628         tests[i].expected_result,
629         GetDataReductionProxyBypassType(parsed.get(), &chrome_proxy_info));
630   }
631 }
632
633 TEST_F(DataReductionProxyHeadersTest,
634        GetDataReductionProxyActionFingerprintChromeProxy) {
635   const struct {
636      std::string label;
637      const char* headers;
638      bool expected_fingerprint_exist;
639      std::string expected_fingerprint;
640   } tests[] = {
641     { "fingerprint doesn't exist",
642       "HTTP/1.1 200 OK\n"
643       "Chrome-Proxy: bypass=0\n",
644       false,
645       "",
646     },
647     { "fingerprint occurs once",
648       "HTTP/1.1 200 OK\n"
649       "Chrome-Proxy: bypass=1, fcp=fp\n",
650       true,
651       "fp",
652     },
653     { "fingerprint occurs twice",
654       "HTTP/1.1 200 OK\n"
655       "Chrome-Proxy: bypass=2, fcp=fp1, fcp=fp2\n",
656       true,
657       "fp1",
658     },
659   };
660   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
661     std::string headers(tests[i].headers);
662     HeadersToRaw(&headers);
663     scoped_refptr<net::HttpResponseHeaders> parsed(
664         new net::HttpResponseHeaders(headers));
665
666     std::string fingerprint;
667     bool fingerprint_exist = GetDataReductionProxyActionFingerprintChromeProxy(
668         parsed.get(), &fingerprint);
669     EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
670         << tests[i].label;
671
672     if (fingerprint_exist)
673       EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
674   }
675 }
676
677 TEST_F(DataReductionProxyHeadersTest,
678        GetDataReductionProxyActionFingerprintVia) {
679   const struct {
680      std::string label;
681      const char* headers;
682      bool expected_fingerprint_exist;
683      std::string expected_fingerprint;
684   } tests[] = {
685     { "fingerprint doesn't exist",
686       "HTTP/1.1 200 OK\n"
687       "Chrome-Proxy: bypass=0\n",
688       false,
689       "",
690     },
691     { "fingerprint occurs once",
692       "HTTP/1.1 200 OK\n"
693       "Chrome-Proxy: bypass=1, fvia=fvia\n",
694       true,
695       "fvia",
696     },
697     { "fingerprint occurs twice",
698       "HTTP/1.1 200 OK\n"
699       "Chrome-Proxy: bypass=2, fvia=fvia1, fvia=fvia2\n",
700       true,
701       "fvia1",
702     },
703   };
704   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
705     std::string headers(tests[i].headers);
706     HeadersToRaw(&headers);
707     scoped_refptr<net::HttpResponseHeaders> parsed(
708         new net::HttpResponseHeaders(headers));
709
710     std::string fingerprint;
711     bool fingerprint_exist =
712         GetDataReductionProxyActionFingerprintVia(parsed.get(), &fingerprint);
713     EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
714         << tests[i].label;
715
716     if (fingerprint_exist)
717       EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
718   }
719 }
720
721 TEST_F(DataReductionProxyHeadersTest,
722        GetDataReductionProxyActionFingerprintOtherHeaders) {
723   const struct {
724      std::string label;
725      const char* headers;
726      bool expected_fingerprint_exist;
727      std::string expected_fingerprint;
728   } tests[] = {
729     { "fingerprint doesn't exist",
730       "HTTP/1.1 200 OK\n"
731       "Chrome-Proxy: bypass=0\n",
732       false,
733       "",
734     },
735     { "fingerprint occurs once",
736       "HTTP/1.1 200 OK\n"
737       "Chrome-Proxy: bypass=1, foh=foh\n",
738       true,
739       "foh",
740     },
741     { "fingerprint occurs twice",
742       "HTTP/1.1 200 OK\n"
743       "Chrome-Proxy: bypass=2, foh=foh1, foh=foh2\n",
744       true,
745       "foh1",
746     },
747   };
748   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
749     std::string headers(tests[i].headers);
750     HeadersToRaw(&headers);
751     scoped_refptr<net::HttpResponseHeaders> parsed(
752         new net::HttpResponseHeaders(headers));
753
754     std::string fingerprint;
755     bool fingerprint_exist = GetDataReductionProxyActionFingerprintOtherHeaders(
756         parsed.get(), &fingerprint);
757     EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
758         << tests[i].label;
759
760     if (fingerprint_exist)
761       EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
762   }
763 }
764
765 TEST_F(DataReductionProxyHeadersTest,
766        GetDataReductionProxyActionFingerprintContentLength) {
767   const struct {
768      std::string label;
769      const char* headers;
770      bool expected_fingerprint_exist;
771      std::string expected_fingerprint;
772   } tests[] = {
773     { "fingerprint doesn't exist",
774       "HTTP/1.1 200 OK\n"
775       "Chrome-Proxy: bypass=0\n",
776       false,
777       "",
778     },
779     { "fingerprint occurs once",
780       "HTTP/1.1 200 OK\n"
781       "Chrome-Proxy: bypass=1, fcl=fcl\n",
782       true,
783       "fcl",
784     },
785     { "fingerprint occurs twice",
786       "HTTP/1.1 200 OK\n"
787       "Chrome-Proxy: bypass=2, fcl=fcl1, fcl=fcl2\n",
788       true,
789       "fcl1",
790     },
791   };
792   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
793     std::string headers(tests[i].headers);
794     HeadersToRaw(&headers);
795     scoped_refptr<net::HttpResponseHeaders> parsed(
796         new net::HttpResponseHeaders(headers));
797
798     std::string fingerprint;
799     bool fingerprint_exist =
800         GetDataReductionProxyActionFingerprintContentLength(parsed.get(),
801                                                             &fingerprint);
802     EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
803         << tests[i].label;
804
805     if (fingerprint_exist)
806       EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
807   }
808 }
809
810 TEST_F(DataReductionProxyHeadersTest,
811        GetDataReductionProxyHeaderWithFingerprintRemoved) {
812   const struct {
813     std::string label;
814     const char* headers;
815     std::string expected_output_values_string;
816   } test[] = {
817     {
818       "Checks the case that there is no Chrome-Proxy header's fingerprint.",
819       "HTTP/1.1 200 OK\n"
820       "Chrome-Proxy: 1,2,3,5\n",
821       "1,2,3,5,",
822     },
823     {
824       "Checks the case that there is Chrome-Proxy header's fingerprint.",
825       "HTTP/1.1 200 OK\n"
826       "Chrome-Proxy: 1,2,3,fcp=4,5\n",
827       "1,2,3,5,",
828     },
829     {
830       "Checks the case that there is Chrome-Proxy header's fingerprint, and it"
831       "occurs at the end.",
832       "HTTP/1.1 200 OK\n"
833       "Chrome-Proxy: 1,2,3,fcp=4,",
834       "1,2,3,",
835     },
836     {
837       "Checks the case that there is Chrome-Proxy header's fingerprint, and it"
838       "occurs at the beginning.",
839       "HTTP/1.1 200 OK\n"
840       "Chrome-Proxy: fcp=1,2,3,",
841       "2,3,",
842     },
843     {
844       "Checks the case that value is longer than prefix.",
845       "HTTP/1.1 200 OK\n"
846       "Chrome-Proxy: fcp=1,fcp!=1,fcp!=2,fcpfcp=3",
847       "fcp!=1,fcp!=2,fcpfcp=3,",
848     },
849     {
850       "Checks the case that value is shorter than prefix but similar.",
851       "HTTP/1.1 200 OK\n"
852       "Chrome-Proxy: fcp=1,fcp,fcp=",
853       "fcp,fcp=,",
854     },
855   };
856
857   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
858     std::string headers(test[i].headers);
859     HeadersToRaw(&headers);
860     scoped_refptr<net::HttpResponseHeaders> parsed(
861         new net::HttpResponseHeaders(headers));
862
863     std::vector<std::string> output_values;
864     GetDataReductionProxyHeaderWithFingerprintRemoved(parsed.get(),
865                                                       &output_values);
866
867     std::string output_values_string;
868     for (size_t j = 0; j < output_values.size(); ++j)
869       output_values_string += output_values[j] + ",";
870
871     EXPECT_EQ(test[i].expected_output_values_string, output_values_string)
872         << test[i].label;
873   }
874 }
875
876 }  // namespace data_reduction_proxy