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