Home | History | Annotate | Download | only in common
      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 "net/http/http_response_headers.h"
      8 #include "net/proxy/proxy_service.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 namespace {
     12 
     13 // Transform "normal"-looking headers (\n-separated) to the appropriate
     14 // input format for ParseRawHeaders (\0-separated).
     15 void HeadersToRaw(std::string* headers) {
     16   std::replace(headers->begin(), headers->end(), '\n', '\0');
     17   if (!headers->empty())
     18     *headers += '\0';
     19 }
     20 
     21 }  // namespace
     22 
     23 namespace data_reduction_proxy {
     24 
     25 class DataReductionProxyHeadersTest : public testing::Test {};
     26 
     27 TEST_F(DataReductionProxyHeadersTest, GetProxyBypassInfo) {
     28   const struct {
     29      const char* headers;
     30      bool expected_result;
     31      int64 expected_retry_delay;
     32      bool expected_bypass_all;
     33   } tests[] = {
     34     { "HTTP/1.1 200 OK\n"
     35       "Content-Length: 999\n",
     36       false,
     37       0,
     38       false,
     39     },
     40     { "HTTP/1.1 200 OK\n"
     41       "connection: keep-alive\n"
     42       "Content-Length: 999\n",
     43       false,
     44       0,
     45       false,
     46     },
     47     { "HTTP/1.1 200 OK\n"
     48       "connection: keep-alive\n"
     49       "Chrome-Proxy: bypass=86400\n"
     50       "Content-Length: 999\n",
     51       true,
     52       86400,
     53       false,
     54     },
     55     { "HTTP/1.1 200 OK\n"
     56       "connection: keep-alive\n"
     57       "Chrome-Proxy: bypass=0\n"
     58       "Content-Length: 999\n",
     59       true,
     60       0,
     61       false,
     62     },
     63     { "HTTP/1.1 200 OK\n"
     64       "connection: keep-alive\n"
     65       "Chrome-Proxy: bypass=-1\n"
     66       "Content-Length: 999\n",
     67       false,
     68       0,
     69       false,
     70     },
     71     { "HTTP/1.1 200 OK\n"
     72       "connection: keep-alive\n"
     73       "Chrome-Proxy: bypass=xyz\n"
     74       "Content-Length: 999\n",
     75       false,
     76       0,
     77       false,
     78     },
     79     { "HTTP/1.1 200 OK\n"
     80       "connection: keep-alive\n"
     81       "Chrome-Proxy: bypass\n"
     82       "Content-Length: 999\n",
     83       false,
     84       0,
     85       false,
     86     },
     87     { "HTTP/1.1 200 OK\n"
     88       "connection: keep-alive\n"
     89       "Chrome-Proxy: foo=abc, bypass=86400\n"
     90       "Content-Length: 999\n",
     91       true,
     92       86400,
     93       false,
     94     },
     95     { "HTTP/1.1 200 OK\n"
     96       "connection: keep-alive\n"
     97       "Chrome-Proxy: bypass=86400, bar=abc\n"
     98       "Content-Length: 999\n",
     99       true,
    100       86400,
    101       false,
    102     },
    103     { "HTTP/1.1 200 OK\n"
    104       "connection: keep-alive\n"
    105       "Chrome-Proxy: bypass=3600\n"
    106       "Chrome-Proxy: bypass=86400\n"
    107       "Content-Length: 999\n",
    108       true,
    109       3600,
    110       false,
    111     },
    112     { "HTTP/1.1 200 OK\n"
    113       "connection: keep-alive\n"
    114       "Chrome-Proxy: bypass=3600, bypass=86400\n"
    115       "Content-Length: 999\n",
    116       true,
    117       3600,
    118       false,
    119     },
    120     { "HTTP/1.1 200 OK\n"
    121       "connection: keep-alive\n"
    122       "Chrome-Proxy: bypass=, bypass=86400\n"
    123       "Content-Length: 999\n",
    124       true,
    125       86400,
    126       false,
    127     },
    128     { "HTTP/1.1 200 OK\n"
    129       "connection: keep-alive\n"
    130       "Chrome-Proxy: bypass\n"
    131       "Chrome-Proxy: bypass=86400\n"
    132       "Content-Length: 999\n",
    133       true,
    134       86400,
    135       false,
    136     },
    137     { "HTTP/1.1 200 OK\n"
    138       "connection: keep-alive\n"
    139       "Chrome-Proxy: block=, block=3600\n"
    140       "Content-Length: 999\n",
    141       true,
    142       3600,
    143       true,
    144     },
    145     { "HTTP/1.1 200 OK\n"
    146       "connection: keep-alive\n"
    147       "Chrome-Proxy: bypass=86400, block=3600\n"
    148       "Content-Length: 999\n",
    149       true,
    150       3600,
    151       true,
    152     },
    153     { "HTTP/1.1 200 OK\n"
    154       "connection: proxy-bypass\n"
    155       "Chrome-Proxy: block=, bypass=86400\n"
    156       "Content-Length: 999\n",
    157       true,
    158       86400,
    159       false,
    160     },
    161     { "HTTP/1.1 200 OK\n"
    162       "connection: proxy-bypass\n"
    163       "Chrome-Proxy: block=-1\n"
    164       "Content-Length: 999\n",
    165       false,
    166       0,
    167       false,
    168     },
    169     { "HTTP/1.1 200 OK\n"
    170       "connection: proxy-bypass\n"
    171       "Chrome-Proxy: block=99999999999999999999\n"
    172       "Content-Length: 999\n",
    173       false,
    174       0,
    175       false,
    176     },
    177   };
    178   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    179     std::string headers(tests[i].headers);
    180     HeadersToRaw(&headers);
    181     scoped_refptr<net::HttpResponseHeaders> parsed(
    182         new net::HttpResponseHeaders(headers));
    183 
    184     DataReductionProxyInfo data_reduction_proxy_info;
    185     EXPECT_EQ(tests[i].expected_result,
    186               GetDataReductionProxyInfo(parsed, &data_reduction_proxy_info));
    187     EXPECT_EQ(tests[i].expected_retry_delay,
    188               data_reduction_proxy_info.bypass_duration.InSeconds());
    189     EXPECT_EQ(tests[i].expected_bypass_all,
    190               data_reduction_proxy_info.bypass_all);
    191   }
    192 }
    193 
    194 TEST_F(DataReductionProxyHeadersTest, HasDataReductionProxyViaHeader) {
    195   const struct {
    196      const char* headers;
    197      bool expected_result;
    198   } tests[] = {
    199     { "HTTP/1.1 200 OK\n"
    200       "Via: 1.1 Chrome-Proxy\n",
    201       false,
    202     },
    203     { "HTTP/1.1 200 OK\n"
    204       "Via: 1\n",
    205       false,
    206     },
    207     { "HTTP/1.1 200 OK\n"
    208       "Via: 1.1 Chrome-Compression-Proxy\n",
    209       true,
    210     },
    211     { "HTTP/1.1 200 OK\n"
    212       "Via: 1.0 Chrome-Compression-Proxy\n",
    213       true,
    214     },
    215     { "HTTP/1.1 200 OK\n"
    216       "Via: 1.1 Foo-Bar, 1.1 Chrome-Compression-Proxy\n",
    217       true,
    218     },
    219     { "HTTP/1.1 200 OK\n"
    220       "Via: 1.1 Chrome-Compression-Proxy, 1.1 Bar-Foo\n",
    221       true,
    222     },
    223     { "HTTP/1.1 200 OK\n"
    224       "Via: 1.1 chrome-compression-proxy\n",
    225       false,
    226     },
    227     { "HTTP/1.1 200 OK\n"
    228       "Via: 1.1 Foo-Bar\n"
    229       "Via: 1.1 Chrome-Compression-Proxy\n",
    230       true,
    231     },
    232     { "HTTP/1.1 200 OK\n"
    233       "Via: 1.1 Chrome-Proxy\n",
    234       false,
    235     },
    236     { "HTTP/1.1 200 OK\n"
    237       "Via: 1.1 Chrome Compression Proxy\n",
    238       true,
    239     },
    240     { "HTTP/1.1 200 OK\n"
    241       "Via: 1.1 Foo-Bar, 1.1 Chrome Compression Proxy\n",
    242       true,
    243     },
    244     { "HTTP/1.1 200 OK\n"
    245       "Via: 1.1 Chrome Compression Proxy, 1.1 Bar-Foo\n",
    246       true,
    247     },
    248     { "HTTP/1.1 200 OK\n"
    249       "Via: 1.1 chrome compression proxy\n",
    250       false,
    251     },
    252     { "HTTP/1.1 200 OK\n"
    253       "Via: 1.1 Foo-Bar\n"
    254       "Via: 1.1 Chrome Compression Proxy\n",
    255       true,
    256     },
    257   };
    258   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    259     std::string headers(tests[i].headers);
    260     HeadersToRaw(&headers);
    261     scoped_refptr<net::HttpResponseHeaders> parsed(
    262         new net::HttpResponseHeaders(headers));
    263 
    264     EXPECT_EQ(tests[i].expected_result,
    265               HasDataReductionProxyViaHeader(parsed));
    266   }
    267 }
    268 
    269 TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyBypassEventType) {
    270   const struct {
    271      const char* headers;
    272      net::ProxyService::DataReductionProxyBypassEventType expected_result;
    273   } tests[] = {
    274     { "HTTP/1.1 200 OK\n"
    275       "Chrome-Proxy: bypass=0\n"
    276       "Via: 1.1 Chrome-Compression-Proxy\n",
    277       net::ProxyService::SHORT_BYPASS,
    278     },
    279     { "HTTP/1.1 200 OK\n"
    280       "Chrome-Proxy: bypass=1799\n"
    281       "Via: 1.1 Chrome-Compression-Proxy\n",
    282       net::ProxyService::SHORT_BYPASS,
    283     },
    284     { "HTTP/1.1 200 OK\n"
    285       "Chrome-Proxy: bypass=1800\n"
    286       "Via: 1.1 Chrome-Compression-Proxy\n",
    287       net::ProxyService::LONG_BYPASS,
    288     },
    289     { "HTTP/1.1 500 Internal Server Error\n"
    290       "Via: 1.1 Chrome-Compression-Proxy\n",
    291       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
    292     },
    293     { "HTTP/1.1 501 Not Implemented\n"
    294       "Via: 1.1 Chrome-Compression-Proxy\n",
    295       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
    296     },
    297     { "HTTP/1.1 502 Bad Gateway\n"
    298       "Via: 1.1 Chrome-Compression-Proxy\n",
    299       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
    300     },
    301     { "HTTP/1.1 503 Service Unavailable\n"
    302       "Via: 1.1 Chrome-Compression-Proxy\n",
    303       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
    304     },
    305     { "HTTP/1.1 504 Gateway Timeout\n"
    306       "Via: 1.1 Chrome-Compression-Proxy\n",
    307       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
    308     },
    309     { "HTTP/1.1 505 HTTP Version Not Supported\n"
    310       "Via: 1.1 Chrome-Compression-Proxy\n",
    311       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
    312     },
    313     { "HTTP/1.1 304 Not Modified\n",
    314         net::ProxyService::BYPASS_EVENT_TYPE_MAX,
    315     },
    316     { "HTTP/1.1 200 OK\n",
    317         net::ProxyService::MISSING_VIA_HEADER,
    318     },
    319     { "HTTP/1.1 200 OK\n"
    320       "Chrome-Proxy: bypass=1799\n",
    321       net::ProxyService::SHORT_BYPASS,
    322     },
    323     { "HTTP/1.1 502 Bad Gateway\n",
    324       net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS,
    325     },
    326     { "HTTP/1.1 502 Bad Gateway\n"
    327       "Chrome-Proxy: bypass=1799\n",
    328       net::ProxyService::SHORT_BYPASS,
    329     },
    330     { "HTTP/1.1 502 Bad Gateway\n"
    331       "Chrome-Proxy: bypass=1799\n",
    332       net::ProxyService::SHORT_BYPASS,
    333     },
    334     { "HTTP/1.1 414 Request-URI Too Long\n",
    335       net::ProxyService::PROXY_4XX_BYPASS,
    336     },
    337     { "HTTP/1.1 414 Request-URI Too Long\n"
    338       "Via: 1.1 Chrome-Compression-Proxy\n",
    339       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
    340     },
    341     { "HTTP/1.1 407 Proxy Authentication Required\n",
    342       net::ProxyService::MALFORMED_407_BYPASS,
    343     },
    344     { "HTTP/1.1 407 Proxy Authentication Required\n"
    345       "Proxy-Authenticate: Basic\n"
    346       "Via: 1.1 Chrome-Compression-Proxy\n",
    347       net::ProxyService::BYPASS_EVENT_TYPE_MAX,
    348     }
    349   };
    350   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    351     std::string headers(tests[i].headers);
    352     HeadersToRaw(&headers);
    353     scoped_refptr<net::HttpResponseHeaders> parsed(
    354         new net::HttpResponseHeaders(headers));
    355     DataReductionProxyInfo chrome_proxy_info;
    356     EXPECT_EQ(tests[i].expected_result,
    357               GetDataReductionProxyBypassEventType(parsed, &chrome_proxy_info));
    358   }
    359 }
    360 }  // namespace data_reduction_proxy
    361