blob: ee063645429ba38ca4d332a6d7a00a514420370e [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h"
#include "net/http/http_response_headers.h"
#include "net/proxy/proxy_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace data_reduction_proxy {
class DataReductionProxyHeadersTest : public testing::Test {
protected:
void SetUp() override {
storage_delegate_.reset(new TestDataReductionProxyEventStorageDelegate());
event_creator_.reset(
new DataReductionProxyEventCreator(storage_delegate_.get()));
}
DataReductionProxyEventCreator* event_creator() const {
return event_creator_.get();
}
private:
std::unique_ptr<DataReductionProxyEventCreator> event_creator_;
std::unique_ptr<TestDataReductionProxyEventStorageDelegate> storage_delegate_;
};
TEST_F(DataReductionProxyHeadersTest, IsEmptyImagePreview) {
const struct {
const char* headers;
bool expected_result;
} tests[] = {
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: foo\n",
false,
},
{
"HTTP/1.1 200 OK\n", false,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: empty-image\n",
true,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: empty-image;foo\n",
true,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: Empty-Image\n",
true,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: foo;empty-image\n",
false,
},
{
"HTTP/1.1 200 OK\n"
"Another-Header: empty-image\n",
false,
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
EXPECT_EQ(tests[i].expected_result, IsEmptyImagePreview(*parsed));
}
}
TEST_F(DataReductionProxyHeadersTest, IsEmptyImagePreviewValue) {
const struct {
const char* chrome_proxy_content_transform_header;
const char* chrome_proxy_header;
bool expected_result;
} tests[] = {
{"", "", false},
{"foo", "bar", false},
{"empty-image", "", true},
{"empty-image;foo", "", true},
{"Empty-Image", "", true},
{"foo;empty-image", "", false},
{"empty-image", "foo", true},
};
for (const auto& test : tests) {
EXPECT_EQ(test.expected_result,
IsEmptyImagePreview(test.chrome_proxy_content_transform_header,
test.chrome_proxy_header));
}
}
TEST_F(DataReductionProxyHeadersTest, IsLitePagePreview) {
const struct {
const char* headers;
bool expected_result;
} tests[] = {
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: foo\n",
false,
},
{
"HTTP/1.1 200 OK\n", false,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: lite-page\n",
true,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: lite-page;foo\n",
true,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: Lite-Page\n",
true,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy-Content-Transform: foo;lite-page\n",
false,
},
{
"HTTP/1.1 200 OK\n"
"Another-Header: lite-page\n",
false,
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
EXPECT_EQ(tests[i].expected_result, IsLitePagePreview(*parsed));
}
}
TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyActionValue) {
const struct {
const char* headers;
std::string action_key;
bool expected_result;
std::string expected_action_value;
} tests[] = {
{ "HTTP/1.1 200 OK\n"
"Content-Length: 999\n",
"a",
false,
"",
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Content-Length: 999\n",
"a",
false,
"",
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=86400\n"
"Content-Length: 999\n",
"bypass",
true,
"86400",
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass86400\n"
"Content-Length: 999\n",
"bypass",
false,
"",
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=0\n"
"Content-Length: 999\n",
"bypass",
true,
"0",
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=1500\n"
"Chrome-Proxy: bypass=86400\n"
"Content-Length: 999\n",
"bypass",
true,
"1500",
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block=1500, block=3600\n"
"Content-Length: 999\n",
"block",
true,
"1500",
},
{ "HTTP/1.1 200 OK\n"
"connection: proxy-bypass\n"
"Chrome-Proxy: key=123 \n"
"Content-Length: 999\n",
"key",
true,
"123",
},
{ "HTTP/1.1 200 OK\n"
"connection: proxy-bypass\n"
"Chrome-Proxy: block-once\n"
"Content-Length: 999\n",
"block-once",
false,
"",
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
std::string action_value;
bool has_action_key = GetDataReductionProxyActionValue(
parsed.get(), tests[i].action_key, &action_value);
EXPECT_EQ(tests[i].expected_result, has_action_key);
if (has_action_key) {
EXPECT_EQ(tests[i].expected_action_value, action_value);
}
}
}
TEST_F(DataReductionProxyHeadersTest, GetProxyBypassInfo) {
const struct {
const char* headers;
bool expected_result;
int64_t expected_retry_delay;
bool expected_bypass_all;
bool expected_mark_proxies_as_bad;
} tests[] = {
{ "HTTP/1.1 200 OK\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=86400\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=-1\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=xyz\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: foo=abc, bypass=86400\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=86400, bar=abc\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=3600\n"
"Chrome-Proxy: bypass=86400\n"
"Content-Length: 999\n",
true,
3600,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=3600, bypass=86400\n"
"Content-Length: 999\n",
true,
3600,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=, bypass=86400\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass\n"
"Chrome-Proxy: bypass=86400\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block=, block=3600\n"
"Content-Length: 999\n",
true,
3600,
true,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=86400, block=3600\n"
"Content-Length: 999\n",
true,
3600,
true,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: proxy-bypass\n"
"Chrome-Proxy: block=, bypass=86400\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: proxy-bypass\n"
"Chrome-Proxy: block=-1\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: proxy-bypass\n"
"Chrome-Proxy: block=99999999999999999999\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once\n"
"Content-Length: 999\n",
true,
0,
true,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once=\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once=10\n"
"Content-Length: 999\n",
false,
0,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once, bypass=86400, block=3600\n"
"Content-Length: 999\n",
true,
3600,
true,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once\n"
"Chrome-Proxy: bypass=86400, block=3600\n"
"Content-Length: 999\n",
true,
3600,
true,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once, bypass=86400\n"
"Content-Length: 999\n",
true,
86400,
false,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: block-once, block=3600\n"
"Content-Length: 999\n",
true,
3600,
true,
true,
},
{ "HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=, block=, block-once\n"
"Content-Length: 999\n",
true,
0,
true,
false,
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
DataReductionProxyInfo data_reduction_proxy_info;
EXPECT_EQ(tests[i].expected_result,
ParseHeadersForBypassInfo(*parsed, &data_reduction_proxy_info));
EXPECT_EQ(tests[i].expected_retry_delay,
data_reduction_proxy_info.bypass_duration.InSeconds());
EXPECT_EQ(tests[i].expected_bypass_all,
data_reduction_proxy_info.bypass_all);
EXPECT_EQ(tests[i].expected_mark_proxies_as_bad,
data_reduction_proxy_info.mark_proxies_as_bad);
}
}
TEST_F(DataReductionProxyHeadersTest, ParseHeadersAndSetProxyInfo) {
std::string headers =
"HTTP/1.1 200 OK\n"
"connection: keep-alive\n"
"Chrome-Proxy: bypass=0\n"
"Content-Length: 999\n";
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
DataReductionProxyInfo data_reduction_proxy_info;
EXPECT_TRUE(ParseHeadersForBypassInfo(*parsed, &data_reduction_proxy_info));
EXPECT_LE(60, data_reduction_proxy_info.bypass_duration.InSeconds());
EXPECT_GE(5 * 60, data_reduction_proxy_info.bypass_duration.InSeconds());
EXPECT_FALSE(data_reduction_proxy_info.bypass_all);
}
TEST_F(DataReductionProxyHeadersTest, HasDataReductionProxyViaHeader) {
const struct {
const char* headers;
bool expected_result;
bool expected_has_intermediary;
bool ignore_intermediary;
} tests[] = {
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Proxy\n",
false,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1\n",
false,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
true,
true,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.0 Chrome-Compression-Proxy\n",
true,
true,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Foo-Bar, 1.1 Chrome-Compression-Proxy\n",
true,
true,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy, 1.1 Bar-Foo\n",
true,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 chrome-compression-proxy\n",
false,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Foo-Bar\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
true,
true,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n"
"Via: 1.1 Foo-Bar\n",
true,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Proxy\n",
false,
false,
false,
},
{ "HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome Compression Proxy\n",
false,
false,
false,
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
bool has_chrome_proxy_via_header, has_intermediary;
if (tests[i].ignore_intermediary) {
has_chrome_proxy_via_header =
HasDataReductionProxyViaHeader(*parsed, NULL);
}
else {
has_chrome_proxy_via_header =
HasDataReductionProxyViaHeader(*parsed, &has_intermediary);
}
EXPECT_EQ(tests[i].expected_result, has_chrome_proxy_via_header);
if (has_chrome_proxy_via_header && !tests[i].ignore_intermediary) {
EXPECT_EQ(tests[i].expected_has_intermediary, has_intermediary);
}
}
}
TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyBypassEventType) {
const struct {
const char* headers;
DataReductionProxyBypassType expected_result;
} tests[] = {
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=0\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MEDIUM,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=1\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_SHORT,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=59\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_SHORT,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=60\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MEDIUM,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=300\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MEDIUM,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=301\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_LONG,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: block-once\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_CURRENT,
},
{
"HTTP/1.1 500 Internal Server Error\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR,
},
{
"HTTP/1.1 501 Not Implemented\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 502 Bad Gateway\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
},
{
"HTTP/1.1 503 Service Unavailable\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE,
},
{
"HTTP/1.1 504 Gateway Timeout\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 505 HTTP Version Not Supported\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 304 Not Modified\n", BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 200 OK\n", BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER,
},
{
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=59\n",
BYPASS_EVENT_TYPE_SHORT,
},
{
"HTTP/1.1 502 Bad Gateway\n",
BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
},
{
"HTTP/1.1 502 Bad Gateway\n"
"Chrome-Proxy: bypass=59\n",
BYPASS_EVENT_TYPE_SHORT,
},
{
"HTTP/1.1 502 Bad Gateway\n"
"Chrome-Proxy: bypass=59\n",
BYPASS_EVENT_TYPE_SHORT,
},
{
"HTTP/1.1 414 Request-URI Too Long\n",
BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_4XX,
},
{
"HTTP/1.1 414 Request-URI Too Long\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 407 Proxy Authentication Required\n",
BYPASS_EVENT_TYPE_MALFORMED_407,
},
{
"HTTP/1.1 407 Proxy Authentication Required\n"
"Proxy-Authenticate: Basic\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
BYPASS_EVENT_TYPE_MAX,
}};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
DataReductionProxyInfo chrome_proxy_info;
EXPECT_EQ(tests[i].expected_result,
GetDataReductionProxyBypassType(std::vector<GURL>(), *parsed,
&chrome_proxy_info));
}
}
TEST_F(DataReductionProxyHeadersTest,
GetDataReductionProxyBypassEventTypeURLRedirectCycle) {
const struct {
const char* headers;
std::vector<GURL> url_chain;
DataReductionProxyBypassType expected_result;
} tests[] = {
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{GURL("http://google.com/1"),
GURL("http://google.com/2"),
GURL("http://google.com/1")},
BYPASS_EVENT_TYPE_URL_REDIRECT_CYCLE,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{
GURL("http://google.com/1"), GURL("http://google.com/2"),
GURL("http://google.com/1"), GURL("http://google.com/2")},
BYPASS_EVENT_TYPE_URL_REDIRECT_CYCLE,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{GURL("http://google.com/1")}, BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{GURL("http://google.com/1"),
GURL("http://google.com/2")},
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{GURL("http://google.com/1"),
GURL("http://google.com/2"),
GURL("http://google.com/3")},
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{
GURL("http://google.com/1"), GURL("http://google.com/2"),
GURL("http://google.com/3"), GURL("http://google.com/1")},
BYPASS_EVENT_TYPE_URL_REDIRECT_CYCLE,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>{
GURL("http://google.com/1"), GURL("http://google.com/2"),
GURL("http://google.com/1"), GURL("http://google.com/3")},
BYPASS_EVENT_TYPE_MAX,
},
{
"HTTP/1.1 200 OK\n"
"Via: 1.1 Chrome-Compression-Proxy\n",
std::vector<GURL>(), BYPASS_EVENT_TYPE_MAX,
}};
for (const auto& test : tests) {
std::string headers(test.headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
DataReductionProxyInfo chrome_proxy_info;
EXPECT_EQ(test.expected_result,
GetDataReductionProxyBypassType(test.url_chain, *parsed,
&chrome_proxy_info));
}
}
TEST_F(DataReductionProxyHeadersTest,
GetDataReductionProxyActionFingerprintChromeProxy) {
const struct {
std::string label;
const char* headers;
bool expected_fingerprint_exist;
std::string expected_fingerprint;
} tests[] = {
{ "fingerprint doesn't exist",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=0\n",
false,
"",
},
{ "fingerprint occurs once",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=1, fcp=fp\n",
true,
"fp",
},
{ "fingerprint occurs twice",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=2, fcp=fp1, fcp=fp2\n",
true,
"fp1",
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
std::string fingerprint;
bool fingerprint_exist = GetDataReductionProxyActionFingerprintChromeProxy(
parsed.get(), &fingerprint);
EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
<< tests[i].label;
if (fingerprint_exist)
EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
}
}
TEST_F(DataReductionProxyHeadersTest,
GetDataReductionProxyActionFingerprintVia) {
const struct {
std::string label;
const char* headers;
bool expected_fingerprint_exist;
std::string expected_fingerprint;
} tests[] = {
{ "fingerprint doesn't exist",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=0\n",
false,
"",
},
{ "fingerprint occurs once",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=1, fvia=fvia\n",
true,
"fvia",
},
{ "fingerprint occurs twice",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=2, fvia=fvia1, fvia=fvia2\n",
true,
"fvia1",
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
std::string fingerprint;
bool fingerprint_exist =
GetDataReductionProxyActionFingerprintVia(parsed.get(), &fingerprint);
EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
<< tests[i].label;
if (fingerprint_exist)
EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
}
}
TEST_F(DataReductionProxyHeadersTest,
GetDataReductionProxyActionFingerprintOtherHeaders) {
const struct {
std::string label;
const char* headers;
bool expected_fingerprint_exist;
std::string expected_fingerprint;
} tests[] = {
{ "fingerprint doesn't exist",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=0\n",
false,
"",
},
{ "fingerprint occurs once",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=1, foh=foh\n",
true,
"foh",
},
{ "fingerprint occurs twice",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=2, foh=foh1, foh=foh2\n",
true,
"foh1",
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
std::string fingerprint;
bool fingerprint_exist = GetDataReductionProxyActionFingerprintOtherHeaders(
parsed.get(), &fingerprint);
EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
<< tests[i].label;
if (fingerprint_exist)
EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
}
}
TEST_F(DataReductionProxyHeadersTest,
GetDataReductionProxyActionFingerprintContentLength) {
const struct {
std::string label;
const char* headers;
bool expected_fingerprint_exist;
std::string expected_fingerprint;
} tests[] = {
{ "fingerprint doesn't exist",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=0\n",
false,
"",
},
{ "fingerprint occurs once",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=1, fcl=fcl\n",
true,
"fcl",
},
{ "fingerprint occurs twice",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: bypass=2, fcl=fcl1, fcl=fcl2\n",
true,
"fcl1",
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::string headers(tests[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
std::string fingerprint;
bool fingerprint_exist =
GetDataReductionProxyActionFingerprintContentLength(parsed.get(),
&fingerprint);
EXPECT_EQ(tests[i].expected_fingerprint_exist, fingerprint_exist)
<< tests[i].label;
if (fingerprint_exist)
EXPECT_EQ(tests[i].expected_fingerprint, fingerprint) << tests[i].label;
}
}
TEST_F(DataReductionProxyHeadersTest,
GetDataReductionProxyHeaderWithFingerprintRemoved) {
const struct {
std::string label;
const char* headers;
std::string expected_output_values_string;
} test[] = {
{
"Checks the case that there is no Chrome-Proxy header's fingerprint.",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: 1,2,3,5\n",
"1,2,3,5,",
},
{
"Checks the case that there is Chrome-Proxy header's fingerprint.",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: 1,2,3,fcp=4,5\n",
"1,2,3,5,",
},
{
"Checks the case that there is Chrome-Proxy header's fingerprint, and it"
"occurs at the end.",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: 1,2,3,fcp=4,",
"1,2,3,",
},
{
"Checks the case that there is Chrome-Proxy header's fingerprint, and it"
"occurs at the beginning.",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: fcp=1,2,3,",
"2,3,",
},
{
"Checks the case that value is longer than prefix.",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: fcp=1,fcp!=1,fcp!=2,fcpfcp=3",
"fcp!=1,fcp!=2,fcpfcp=3,",
},
{
"Checks the case that value is shorter than prefix but similar.",
"HTTP/1.1 200 OK\n"
"Chrome-Proxy: fcp=1,fcp,fcp=",
"fcp,fcp=,",
},
};
for (size_t i = 0; i < arraysize(test); ++i) {
std::string headers(test[i].headers);
HeadersToRaw(&headers);
scoped_refptr<net::HttpResponseHeaders> parsed(
new net::HttpResponseHeaders(headers));
std::vector<std::string> output_values;
GetDataReductionProxyHeaderWithFingerprintRemoved(parsed.get(),
&output_values);
std::string output_values_string;
for (size_t j = 0; j < output_values.size(); ++j)
output_values_string += output_values[j] + ",";
EXPECT_EQ(test[i].expected_output_values_string, output_values_string)
<< test[i].label;
}
}
} // namespace data_reduction_proxy