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

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

Powered by Google App Engine
This is Rietveld 408576698