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

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

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

Powered by Google App Engine
This is Rietveld 408576698