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

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

Powered by Google App Engine
This is Rietveld 408576698