Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detection_unittest.cc

Issue 338483002: Chrome Participated Tamper Detect (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/browser/data_reduction_proxy_tamper_de tection.h"
6
7 #include <string.h>
8 #include <algorithm>
9 #include <map>
10 #include <vector>
11
12 #include "base/base64.h"
13 #include "base/md5.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_split.h"
17 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
18 #include "net/android/network_library.h"
19 #include "net/http/http_response_headers.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 #if defined(OS_ANDROID)
23 #include "base/android/jni_android.h"
24 #include "net/android/network_library.h"
25 #endif
26
27 namespace {
28
29 void HeadersToRaw(std::string* headers) {
30 std::replace(headers->begin(), headers->end(), '\n', '\0');
31 if (!headers->empty())
32 *headers += '\0';
33 }
34
35 // Calcuates MD5 hash value for a string and then base64 encode it. Testcases
36 // contain expected fingerprint in plain text, which needs to be encoded before
37 // comparison.
38 std::string GetEncoded(const std::string& input) {
39 base::MD5Digest digest;
40 base::MD5Sum(input.c_str(), input.size(), &digest);
41 std::string base64encoded;
42 base::Base64Encode(std::string((char*)digest.a,
43 ARRAYSIZE_UNSAFE(digest.a)), &base64encoded);
44 return base64encoded;
45 }
46
47 // Replaces all contents within "[]" by corresponding base64 encoded MD5 value.
48 // It can handle nested case like: [[abc]def]. This helper function transforms
49 // fingerprint in plain text to actual encoded fingerprint.
50 void ReplaceWithEncodedString(std::string* input) {
51 size_t start, end, temp;
52 while (true) {
53 start = input->find("[");
54 if (start == std::string::npos) break;
55 while (true) {
56 temp = input->find("[", start + 1);
57 end = input->find("]", start + 1);
58 if (end >= 0 && end < temp)
59 break;
60 else
61 start = temp;
62 }
63 std::string need_to_encode = input->substr(start + 1, end - start - 1);
64 *input = input->substr(0, start) + GetEncoded(need_to_encode) +
65 input->substr(end + 1);
66 }
67 }
68
69 // Returns a vector contains all the values from a comma-separated string.
70 // Some testcases contain string representation of a vector, this helper
71 // function generates a vector from a input string.
72 std::vector<std::string> StringsToVector(std::string& values) {
73 std::vector<std::string> ret;
74 if (values.size() == 0)
75 return ret;
76 size_t now = -1, next;
77 while((next = values.find(",", now+1)) != std::string::npos)
78 {
79 ret.push_back(values.substr(now+1, next-now-1));
80 now = next;
81 };
82 return ret;
83 }
84
85 } // namespace
86
87 namespace data_reduction_proxy {
88
89 class DataReductionProxyTamperDetectionTest : public testing::Test {};
90
91 // Tests function ValidateChromeProxyHeader.
92 TEST_F(DataReductionProxyTamperDetectionTest, ChromeProxy) {
93 // |received_fingerprint| is not the actual fingerprint from data reduction
94 // proxy, instead, the base64 encoded field is in plain text (within "[]")
95 // and needs to be encoded first.
96 struct {
97 std::string label;
98 std::string raw_header;
99 std::string received_fingerprint;
100 bool expected_tampered_with;
101 } test[] = {
102 {
103 "Checks sorting.",
104 "HTTP/1.1 200 OK\n"
105 "Chrome-Proxy: c,b,a,3,2,1,fcp=f\n",
106 "[1,2,3,a,b,c,]",
107 false,
108 },
109 {
110 "Checks Chrome-Proxy's fingerprint removing.",
111 "HTTP/1.1 200 OK\n"
112 "Chrome-Proxy: a,b,c,d,e,3,2,1,fcp=f\n",
113 "[1,2,3,a,b,c,d,e,]",
114 false,
115 },
116 {
117 "Checks no Chrome-Proxy header case (should not happen).",
118 "HTTP/1.1 200 OK\n",
119 "[]",
120 false,
121 },
122 {
123 "Checks empty Chrome-Proxy header case (should not happen).",
124 "HTTP/1.1 200 OK\n"
125 "Chrome-Proxy: \n",
126 "[,]",
127 false,
128 },
129 {
130 "Checks Chrome-Proxy header with its fingerprint only case.",
131 "HTTP/1.1 200 OK\n"
132 "Chrome-Proxy: fcp=f\n",
133 "[]",
134 false,
135 },
136 {
137 "Checks empty Chrome-Proxy header case, with extra ',' and ' '",
138 "HTTP/1.1 200 OK\n"
139 "Chrome-Proxy: fcp=f , \n",
140 "[]",
141 false,
142 },
143 {
144 "Changed no value to empty value.",
145 "HTTP/1.1 200 OK\n"
146 "Chrome-Proxy: fcp=f\n",
147 "[,]",
148 true,
149 },
150 {
151 "Changed header values.",
152 "HTTP/1.1 200 OK\n"
153 "Chrome-Proxy: a,b=2,c,d=1,fcp=f\n",
154 "[a,b=3,c,d=1,]",
155 true,
156 },
157 {
158 "Changed order of header values.",
159 "HTTP/1.1 200 OK\n"
160 "Chrome-Proxy: c,b,a,fcp=1\n",
161 "[c,b,a,]",
162 true,
163 },
164 {
165 "Checks Chrome-Proxy header with extra ' '.",
166 "HTTP/1.1 200 OK\n"
167 "Chrome-Proxy: a , b , c, d, fcp=f\n",
168 "[a,b,c,d,]",
169 false
170 },
171 {
172 "Check Chrome-Proxy header with multiple lines and ' '.",
173 "HTTP/1.1 200 OK\n"
174 "Chrome-Proxy: a , c , d, fcp=f \n"
175 "Chrome-Proxy: b \n",
176 "[a,b,c,d,]",
177 false
178 },
179 {
180 "Checks Chrome-Proxy header with multiple lines, at different positions",
181 "HTTP/1.1 200 OK\n"
182 "Chrome-Proxy: a \n"
183 "Chrome-Proxy: c \n"
184 "Content-Type: 1\n"
185 "Cache-Control: 2\n"
186 "ETag: 3\n"
187 "Chrome-Proxy: b \n"
188 "Connection: 4\n"
189 "Expires: 5\n"
190 "Chrome-Proxy: fcp=f \n"
191 "Via: \n"
192 "Content-Length: 12345\n",
193 "[a,b,c,]",
194 false
195 },
196 {
197 "Checks Chrome-Proxy header with multiple same values.",
198 "HTTP/1.1 200 OK\n"
199 "Chrome-Proxy: a \n"
200 "Chrome-Proxy: b\n"
201 "Chrome-Proxy: c\n"
202 "Chrome-Proxy: d, fcp=f \n"
203 "Chrome-Proxy: a \n",
204 "[a,a,b,c,d,]",
205 false
206 },
207 {
208 "Changed Chrome-Proxy header with multiple lines..",
209 "HTTP/1.1 200 OK\n"
210 "Chrome-Proxy: a\n"
211 "Chrome-Proxy: a\n"
212 "Chrome-Proxy: b\n"
213 "Chrome-Proxy: c,fcp=f\n",
214 "[a,b,c,]",
215 true,
216 },
217 {
218 "Checks case whose received fingerprint is empty.",
219 "HTTP/1.1 200 OK\n"
220 "Chrome-Proxy: a,b,c,fcp=1\n",
221 "[]",
222 true,
223 },
224 {
225 "Checks case whose received fingerprint cannot be base64 decoded.",
226 "HTTP/1.1 200 OK\n"
227 "Chrome-Proxy: a,b,c,fcp=1\n",
228 "not_base64_encoded",
229 true,
230 },
231 };
232
233 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
234 ReplaceWithEncodedString(&test[i].received_fingerprint);
235
236 std::string raw_headers(test[i].raw_header);
237 HeadersToRaw(&raw_headers);
238 scoped_refptr<net::HttpResponseHeaders> headers(
239 new net::HttpResponseHeaders(raw_headers));
240
241 DataReductionProxyTamperDetection tamper_detection(headers, true, 0);
242
243 bool tampered = tamper_detection.ValidateChromeProxyHeader(
244 test[i].received_fingerprint);
245
246 EXPECT_EQ(test[i].expected_tampered_with, tampered) << test[i].label;
247 }
248 }
249
250 // Tests function ValidateViaHeader.
251 TEST_F(DataReductionProxyTamperDetectionTest, Via) {
252 struct {
253 std::string label;
254 std::string raw_header;
255 std::string received_fingerprint;
256 bool expected_tampered_with;
257 bool expected_has_chrome_proxy_via_header;
258 } test[] = {
259 {
260 "Checks the case that Chrome-Compression-Proxy occurs at the last.",
261 "HTTP/1.1 200 OK\n"
262 "Via: a, b, c, 1.1 Chrome-Compression-Proxy\n",
263 "",
264 false,
265 true,
266 },
267 {
268 "Checks when there is intermediary.",
269 "HTTP/1.1 200 OK\n"
270 "Via: a, b, c, 1.1 Chrome-Compression-Proxy, xyz\n",
271 "",
272 true,
273 true,
274 },
275 {
276 "Checks the case of empty Via header.",
277 "HTTP/1.1 200 OK\n"
278 "Via: \n",
279 "",
280 false,
281 false,
282 },
283 {
284 "Checks the case that only the data reduction proxy's Via header occurs.",
285 "HTTP/1.1 200 OK\n"
286 "Via: 1.1 Chrome-Compression-Proxy \n",
287 "",
288 false,
289 true,
290 },
291 {
292 "Checks the case that there are ' ', i.e., empty value after the data"
293 " reduction proxy's Via header.",
294 "HTTP/1.1 200 OK\n"
295 "Via: 1.1 Chrome-Compression-Proxy , , \n",
296 "",
297 false,
298 true,
299 },
300 {
301 "Checks the case when there is no Via header",
302 "HTTP/1.1 200 OK\n",
303 "",
304 false,
305 false,
306 },
307 // Same to above test cases, but with deprecated data reduciton proxy Via
308 // header.
309 {
310 "Checks the case that Chrome Compression Proxy occurs at the last.",
311 "HTTP/1.1 200 OK\n"
312 "Via: a, b, c, 1.1 Chrome Compression Proxy\n",
313 "",
314 false,
315 true,
316 },
317 {
318 "Checks when there is intermediary.",
319 "HTTP/1.1 200 OK\n"
320 "Via: a, b, c, 1.1 Chrome Compression Proxy, xyz\n",
321 "",
322 true,
323 true,
324 },
325 {
326 "Checks the case of empty Via header.",
327 "HTTP/1.1 200 OK\n"
328 "Via: \n",
329 "",
330 false,
331 false,
332 },
333 {
334 "Checks the case that only the data reduction proxy's Via header occurs.",
335 "HTTP/1.1 200 OK\n"
336 "Via: 1.1 Chrome Compression Proxy \n",
337 "",
338 false,
339 true,
340 },
341 {
342 "Checks the case that there are ' ', i.e., empty value after the data"
343 "reduction proxy's Via header.",
344 "HTTP/1.1 200 OK\n"
345 "Via: 1.1 Chrome Compression Proxy , , \n",
346 "",
347 false,
348 true,
349 },
350 {
351 "Checks the case when there is no Via header",
352 "HTTP/1.1 200 OK\n",
353 "",
354 false,
355 false,
356 },
357 };
358
359 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
360 std::string raw_headers(test[i].raw_header);
361 HeadersToRaw(&raw_headers);
362 scoped_refptr<net::HttpResponseHeaders> headers(
363 new net::HttpResponseHeaders(raw_headers));
364
365 DataReductionProxyTamperDetection tamper_detection(headers, true, 0);
366
367 bool has_chrome_proxy_via_header;
368 bool tampered = tamper_detection.ValidateViaHeader(
369 test[i].received_fingerprint, &has_chrome_proxy_via_header);
370
371 EXPECT_EQ(test[i].expected_tampered_with, tampered) << test[i].label;
372 EXPECT_EQ(test[i].expected_has_chrome_proxy_via_header,
373 has_chrome_proxy_via_header) << test[i].label;
374 }
375 }
376
377 // Tests function ValidateOtherHeaders.
378 TEST_F(DataReductionProxyTamperDetectionTest, OtherHeaders) {
379 // For following testcases, |received_fingerprint| is not the actual
380 // fingerprint from data reduction proxy, instead, the base64 encoded field
381 // is in plain text (within "[]") and needs to be encoded first. For example,
382 // "[12345;]|content-length" needs to be encoded to
383 // "Base64Encoded(MD5(12345;))|content-length" before calling the checking
384 // function.
385 struct {
386 std::string label;
387 std::string raw_header;
388 std::string received_fingerprint;
389 bool expected_tampered_with;
390 } test[] = {
391 {
392 "Checks the case that only one header is requested.",
393 "HTTP/1.1 200 OK\n"
394 "Content-Length: 12345\n",
395 "[12345,;]|content-length",
396 false
397 },
398 {
399 "Checks the case that there is only one requested header and it does not"
400 "exist.",
401 "HTTP/1.1 200 OK\n",
402 "[;]|non_exist_header",
403 false
404 },
405 {
406 "Checks the case of multiple headers are requested.",
407 "HTTP/1.1 200 OK\n"
408 "Content-Type: 1\n"
409 "Cache-Control: 2\n"
410 "ETag: 3\n"
411 "Connection: 4\n"
412 "Expires: 5\n",
413 "[1,;2,;3,;4,;5,;]|content-type|cache-control|etag|connection|expires",
414 false
415 },
416 {
417 "Checks the case that one header has multiple values.",
418 "HTTP/1.1 200 OK\n"
419 "Content-Type: aaa1, bbb1, ccc1\n"
420 "Cache-Control: aaa2\n",
421 "[aaa1,bbb1,ccc1,;aaa2,;]|content-type|cache-control",
422 false
423 },
424 {
425 "Checks the case that one header has multiple lines.",
426 "HTTP/1.1 200 OK\n"
427 "Content-Type: aaa1, ccc1\n"
428 "Content-Type: xxx1, bbb1, ccc1\n"
429 "Cache-Control: aaa2\n",
430 "[aaa1,bbb1,ccc1,ccc1,xxx1,;aaa2,;]|content-type|cache-control",
431 false
432 },
433 {
434 "Checks the case that more than one headers have multiple values.",
435 "HTTP/1.1 200 OK\n"
436 "Content-Type: aaa1, ccc1\n"
437 "Cache-Control: ccc2 , bbb2\n"
438 "Content-Type: bbb1, ccc1\n"
439 "Cache-Control: aaa2 \n",
440 "[aaa1,bbb1,ccc1,ccc1,;aaa2,bbb2,ccc2,;]|content-type|cache-control",
441 false
442 },
443 {
444 "Checks the case that one of the requested headers is missing (Expires).",
445 "HTTP/1.1 200 OK\n"
446 "Content-Type: aaa1, ccc1\n",
447 "[aaa1,ccc1,;;]|content-type|expires",
448 false
449 },
450 {
451 "Checks the case that some of the requested headers have empty value.",
452 "HTTP/1.1 200 OK\n"
453 "Content-Type: \n"
454 "Cache-Control: \n",
455 "[,;,;]|content-type|cache-control",
456 false
457 },
458 {
459 "Checks the case that all the requested headers are missing.",
460 "HTTP/1.1 200 OK\n",
461 "[;;]|content-type|expires",
462 false
463 },
464 {
465 "Checks the case that some headers are missing, some of them are empty.",
466 "HTTP/1.1 200 OK\n"
467 "Cache-Control: \n",
468 "[;,;]|content-type|cache-control",
469 false
470 },
471 {
472 "Checks the case there is no requested header (header list is empty).",
473 "HTTP/1.1 200 OK\n"
474 "Chrome-Proxy: aut=aauutthh,bbbypas=0,aaxxx=xxx,bbbloc=1\n"
475 "Content-Type: 1\n"
476 "Cache-Control: 2\n",
477 "[]",
478 false
479 },
480 {
481 "Checks tampered requested header values.",
482 "HTTP/1.1 200 OK\n"
483 "Content-Type: aaa1, ccc1\n"
484 "Cache-Control: ccc2 , bbb2\n",
485 "[aaa1,bbb1,;bbb2,ccc2,;]|content-type|cache-control",
486 true
487 },
488 };
489
490 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
491 ReplaceWithEncodedString(&(test[i].received_fingerprint));
492
493 std::string raw_headers(test[i].raw_header);
494 HeadersToRaw(&raw_headers);
495 scoped_refptr<net::HttpResponseHeaders> headers(
496 new net::HttpResponseHeaders(raw_headers));
497
498 DataReductionProxyTamperDetection tamper_detection(headers, true, 0);
499
500 bool tampered = tamper_detection.ValidateOtherHeaders(
501 test[i].received_fingerprint);
502
503 EXPECT_EQ(test[i].expected_tampered_with, tampered) << test[i].label;
504 }
505 }
506
507 // Tests function ValidateContentLengthHeader.
508 TEST_F(DataReductionProxyTamperDetectionTest, ContentLength) {
509 struct {
510 std::string label;
511 std::string raw_header;
512 std::string received_fingerprint;
513 bool expected_tampered_with;
514 } test[] = {
515 {
516 "Checks the case fingerprint matches received response.",
517 "HTTP/1.1 200 OK\n"
518 "Content-Length: 12345\n",
519 "12345",
520 false,
521 },
522 {
523 "Checks case that response got modified.",
524 "HTTP/1.1 200 OK\n"
525 "Content-Length: 12345\n",
526 "125",
527 true,
528 },
529 {
530 "Checks the case that the data reduction proxy has not sent"
531 "Content-Length header.",
532 "HTTP/1.1 200 OK\n"
533 "Content-Length: 12345\n",
534 "",
535 false,
536 },
537 {
538 "Checks the case that the data reduction proxy sends invalid"
539 "Content-Length header.",
540 "HTTP/1.1 200 OK\n"
541 "Content-Length: 12345\n",
542 "aaa",
543 false,
544 },
545 {
546 "Checks the case that the data reduction proxy sends invalid"
547 "Content-Length header.",
548 "HTTP/1.1 200 OK\n"
549 "Content-Length: aaa\n",
550 "aaa",
551 false,
552 },
553 {
554 "Checks the case that Content-Length header is missing at the Chromium"
555 "client side.",
556 "HTTP/1.1 200 OK\n",
557 "123",
558 false,
559 },
560 {
561 "Checks the case that Content-Length header are missing at both end.",
562 "HTTP/1.1 200 OK\n",
563 "",
564 false,
565 },
566 };
567
568 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
569 std::string raw_headers(test[i].raw_header);
570 HeadersToRaw(&raw_headers);
571 scoped_refptr<net::HttpResponseHeaders> headers(
572 new net::HttpResponseHeaders(raw_headers));
573
574 DataReductionProxyTamperDetection tamper_detection(headers, true, 0);
575
576 bool tampered = tamper_detection.ValidateContentLengthHeader(
577 test[i].received_fingerprint);
578
579 EXPECT_EQ(test[i].expected_tampered_with, tampered) << test[i].label;
580 }
581 }
582
583 // Tests ValuesToSortedString function.
584 TEST_F(DataReductionProxyTamperDetectionTest, ValuesToSortedString) {
585 struct {
586 std::string label;
587 std::string input_values;
588 std::string expected_output_string;
589 } test[] = {
590 {
591 "Checks the correctness of sorting.",
592 "3,2,1,",
593 "1,2,3,",
594 },
595 {
596 "Checks the case that there is an empty input vector.",
597 "",
598 "",
599 },
600 {
601 "Checks the case that there is an empty string in the input vector.",
602 ",",
603 ",",
604 },
605 };
606
607 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
608 std::vector<std::string> input_values =
609 StringsToVector(test[i].input_values);
610 std::string output_string =
611 DataReductionProxyTamperDetection::ValuesToSortedString(&input_values);
612 EXPECT_EQ(output_string, test[i].expected_output_string) << test[i].label;
613 }
614 }
615
616 // Tests GetHeaderValues function.
617 TEST_F(DataReductionProxyTamperDetectionTest, GetHeaderValues) {
618 struct {
619 std::string label;
620 std::string raw_header;
621 std::string header_name;
622 std::string expected_output_values;
623 } test[] = {
624 {
625 "Checks the correctness of getting single line header.",
626 "HTTP/1.1 200 OK\n"
627 "test: 1, 2, 3\n",
628 "test",
629 "1,2,3,",
630 },
631 {
632 "Checks the correctness of getting multiple lines header.",
633 "HTTP/1.1 200 OK\n"
634 "test: 1, 2, 3\n"
635 "test: 4, 5, 6\n"
636 "test: 7, 8, 9\n",
637 "test",
638 "1,2,3,4,5,6,7,8,9,",
639 },
640 {
641 "Checks the correctness of getting missing header.",
642 "HTTP/1.1 200 OK\n",
643 "test",
644 "",
645 },
646 {
647 "Checks the correctness of getting empty header.",
648 "HTTP/1.1 200 OK\n"
649 "test: \n",
650 "test",
651 ",",
652 },
653 };
654
655 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
656 std::string raw_headers(test[i].raw_header);
657 HeadersToRaw(&raw_headers);
658 scoped_refptr<net::HttpResponseHeaders> headers(
659 new net::HttpResponseHeaders(raw_headers));
660
661 std::vector<std::string> expected_output_values =
662 StringsToVector(test[i].expected_output_values);
663
664 std::vector<std::string> output_values =
665 DataReductionProxyTamperDetection::GetHeaderValues(
666 headers, test[i].header_name);
667 EXPECT_EQ(expected_output_values, output_values) << test[i].label;
668 }
669 }
670
671 // Tests main function DetectAndReport.
672 TEST_F(DataReductionProxyTamperDetectionTest, DetectAndReport) {
673 struct {
674 std::string label;
675 std::string raw_header;
676 bool expected_tampered_with;
677 } test[] = {
678 {
679 "Check no fingerprint added case.",
680 "HTTP/1.1 200 OK\n"
681 "Via: a1, b2, 1.1 Chrome-Compression-Proxy\n"
682 "Content-Length: 12345\n"
683 "Chrome-Proxy: bypass=0\n",
684 false,
685 },
686 {
687 "Check the case Chrome-Proxy fingerprint doesn't match.",
688 "HTTP/1.1 200 OK\n"
689 "Via: a1, b2, 1.1 Chrome-Compression-Proxy\n"
690 "Content-Length: 12345\n"
691 "header1: header_1\n"
692 "header2: header_2\n"
693 "header3: header_3\n"
694 "Chrome-Proxy: fcl=12345, "
695 "foh=[header_1,;header_2,;header_3,;]|header1|header2|header3,fvia=0,"
696 "fcp=abc\n",
697 true,
698 },
699 {
700 "Check the case response matches the fingerprint completely.",
701 "HTTP/1.1 200 OK\n"
702 "Via: a1, b2, 1.1 Chrome-Compression-Proxy\n"
703 "Content-Length: 12345\n"
704 "header1: header_1\n"
705 "header2: header_2\n"
706 "header3: header_3\n"
707 "Chrome-Proxy: fcl=12345, "
708 "foh=[header_1,;header_2,;header_3,;]|header1|header2|header3,"
709 "fvia=0, fcp=[fcl=12345,foh=[header_1,;header_2,;header_3,;]"
710 "|header1|header2|header3,fvia=0,]\n",
711 false,
712 },
713 {
714 "Check the case that Content-Length doesn't match.",
715 "HTTP/1.1 200 OK\n"
716 "Via: a1, b2, 1.1 Chrome-Compression-Proxy\n"
717 "Content-Length: 0\n"
718 "header1: header_1\n"
719 "header2: header_2\n"
720 "header3: header_3\n"
721 "Chrome-Proxy: fcl=12345, "
722 "foh=[header_1,;header_2,;header_3,;]|header1|header2|header3, fvia=0, "
723 "fcp=[fcl=12345,foh=[header_1,;header_2,;header_3,;]|"
724 "header1|header2|header3,fvia=0,]\n",
725 true,
726 },
727 };
728
729 #if defined(OS_ANDROID)
730 JNIEnv* env = base::android::AttachCurrentThread();
731 net::android::RegisterNetworkLibrary(env);
732 #endif
733
734 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test); ++i) {
735 std::string raw_headers(test[i].raw_header);
736 ReplaceWithEncodedString(&raw_headers);
737 HeadersToRaw(&raw_headers);
738 scoped_refptr<net::HttpResponseHeaders> headers(
739 new net::HttpResponseHeaders(raw_headers));
740
741 EXPECT_EQ(test[i].expected_tampered_with,
742 DataReductionProxyTamperDetection::DetectAndReport(headers, true))
743 << test[i].label;
744 }
745 }
746
747 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698