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