http_response_headers_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TestData {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* raw_headers;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* expected_headers;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_response_code;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpVersion expected_parsed_version;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpVersion expected_version;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContentTypeTestData {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string raw_headers;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string mime_type;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool has_mimetype;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string charset;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool has_charset;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string all_content_type;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpResponseHeadersTest : public testing::Test {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Transform "normal"-looking headers (\n-separated) to the appropriate
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// input format for ParseRawHeaders (\0-separated).
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HeadersToRaw(std::string* headers) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::replace(headers->begin(), headers->end(), '\n', '\0');
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!headers->empty())
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *headers += '\0';
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCommon(const TestData& test) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string raw_headers(test.raw_headers);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&raw_headers);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_headers(test.expected_headers);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(raw_headers));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed->GetNormalizedHeaders(&headers);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transform to readable output format (so it's easier to see diffs).
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::replace(headers.begin(), headers.end(), ' ', '_');
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::replace(headers.begin(), headers.end(), '\n', '\\');
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::replace(expected_headers.begin(), expected_headers.end(), ' ', '_');
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::replace(expected_headers.begin(), expected_headers.end(), '\n', '\\');
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_headers, headers);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test.expected_response_code, parsed->response_code());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(test.expected_parsed_version == parsed->GetParsedHttpVersion());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(test.expected_version == parsed->GetHttpVersion());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // end namespace
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that we normalize headers properly.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersWhitespace) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1    202   Accepted  \n"
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE  : text/html; charset=utf-8  \n"
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: a \n"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie:   b \n",
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 202 Accepted\n"
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: a, b\n",
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    202,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that we normalize headers properly (header name is invalid if starts
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with LWS).
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersLeadingWhitespace) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1    202   Accepted  \n"
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Starts with space -- will be skipped as invalid.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  Content-TYPE  : text/html; charset=utf-8  \n"
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: a \n"
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie:   b \n",
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 202 Accepted\n"
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: a, b\n",
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    202,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, BlankHeaders) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 200 OK\n"
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header1 :          \n"
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header2: \n"
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header3:\n"
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header4\n"
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header5    :\n",
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 200 OK\n"
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header1: \n"
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header2: \n"
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header3: \n"
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Header5: \n",
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersVersion) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't believe the http/0.9 version if there are headers!
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hTtP/0.9 201\n"
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n",
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.0 201 OK\n"
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n",
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    201,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(0,9),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,0)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, PreserveHttp09) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accept the HTTP/0.9 version number if there are no headers.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is how HTTP/0.9 responses get constructed from HttpNetworkTransaction.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hTtP/0.9 200 OK\n",
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/0.9 200 OK\n",
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(0,9),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(0,9)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersMissingOK) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 201\n"
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n",
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 201 OK\n"
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n",
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    201,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersBadStatus) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "SCREWED_UP_STATUS_LINE\n"
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n",
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.0 200 OK\n"
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-TYPE: text/html; charset=utf-8\n",
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(0,0), // Parse error
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,0)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersInvalidStatusCode) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 -1  Unknown\n",
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 200 OK\n",
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersEmpty) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "",
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.0 200 OK\n",
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(0,0), // Parse Error
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,0)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersStartWithColon) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1    202   Accepted  \n"
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo: bar\n"
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ": a \n"
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    " : b\n"
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "baz: blat \n",
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 202 Accepted\n"
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo: bar\n"
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "baz: blat\n",
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    202,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersStartWithColonAtEOL) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1    202   Accepted  \n"
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo:   \n"
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar:\n"
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "baz: blat \n"
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "zip:\n",
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 202 Accepted\n"
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo: \n"
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar: \n"
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "baz: blat\n"
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "zip: \n",
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    202,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, NormalizeHeadersOfWhitepace) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n   \n",
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.0 200 OK\n",
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(0,0),  // Parse error
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,0)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, RepeatedSetCookie) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestData test = {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 200 OK\n"
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: x=1\n"
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: y=2\n",
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 200 OK\n"
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Set-Cookie: x=1, y=2\n",
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    200,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpVersion(1,1)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCommon(test);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetNormalizedHeader) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers =
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: private\n"
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-Control: no-store\n";
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(headers));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->GetNormalizedHeader("cache-control", &value));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("private, no-store", value);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, Persist) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseHeaders::PersistOptions options;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* raw_headers;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_headers;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_ALL,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control:private\n"
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-Control:no-store\n",
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: private, no-store\n"
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "server: blah\n",
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "server: blah\n"
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE |
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "fOo: 1\n"
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Transfer-Encoding: chunked\n"
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CoNnection: keep-alive\n"
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: private, no-cache=\"foo\"\n",
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: private, no-cache=\"foo\"\n"
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private,no-cache=\"foo, bar\"\n"
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bar",
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private,no-cache=\"foo, bar\"\n"
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore bogus no-cache value
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private,no-cache=foo\n",
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private,no-cache=foo\n"
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore bogus no-cache value
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\n",
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\n"
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore empty no-cache value
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\"\"\n",
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\"\"\n"
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore wrong quotes no-cache value
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\'foo\'\n",
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\'foo\'\n"
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore unterminated quotes no-cache value
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\"foo\n",
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\"foo\n"
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // accept sloppy LWS
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 2\n"
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\" foo\t, bar\"\n",
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: private, no-cache=\" foo\t, bar\"\n"
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // header name appears twice, separated by another header
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_ALL,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 2\n"
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 3\n",
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1, 3\n"
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 2\n"
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // header name appears twice, separated by another header (type 2)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_ALL,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1, 3\n"
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 2\n"
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 4\n",
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1, 3, 4\n"
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 2\n"
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test filtering of cookie headers.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_COOKIES,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Set-Cookie: foo=bar; httponly\n"
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Set-Cookie: bar=foo\n"
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 1\n"
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Set-Cookie2: bar2=foo2\n",
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 1\n"
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test LWS at the end of a header.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_ALL,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450   \n"
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Encoding: gzip\n",
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Encoding: gzip\n"
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test LWS at the end of a header.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_RAW,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450   \n"
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Encoding: gzip\n",
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Encoding: gzip\n"
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test filtering of transport security state headers.
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { net::HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Strict-Transport-Security: max-age=1576800\n"
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 1\n"
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Public-Key-Pins: max-age=100000; "
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "pin-sha1=\"ObT42aoSpAqWdY9WfRfL7i0HsVk=\";"
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "pin-sha1=\"7kW49EVwZG0hSNx41ZO/fUPN0ek=\"",
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 1\n"
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers = tests[i].raw_headers;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed1(
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Pickle pickle;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed1->Persist(&pickle, tests[i].options);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PickleIterator iter(pickle);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed2(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(pickle, &iter));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string h2;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed2->GetNormalizedHeaders(&h2);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_headers), h2);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, EnumerateHeader_Coalesced) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that commas in quoted strings are not regarded as value separators.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that whitespace following a value is trimmed properly
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers =
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control:private , no-cache=\"set-cookie,server\" \n"
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-Control: no-store\n";
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(headers));
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(&iter, "cache-control", &value));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("private", value);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(&iter, "cache-control", &value));
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("no-cache=\"set-cookie,server\"", value);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(&iter, "cache-control", &value));
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("no-store", value);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parsed->EnumerateHeader(&iter, "cache-control", &value));
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, EnumerateHeader_Challenge) {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Even though WWW-Authenticate has commas, it should not be treated as
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coalesced values.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers =
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 OK\n"
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate:Digest realm=foobar, nonce=x, domain=y\n"
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate:Basic realm=quatar\n";
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(headers));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(&iter, "WWW-Authenticate", &value));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Digest realm=foobar, nonce=x, domain=y", value);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(&iter, "WWW-Authenticate", &value));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Basic realm=quatar", value);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parsed->EnumerateHeader(&iter, "WWW-Authenticate", &value));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, EnumerateHeader_DateValued) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The comma in a date valued header should not be treated as a
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // field-value separator
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers =
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Date: Tue, 07 Aug 2007 23:10:55 GMT\n"
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Last-Modified: Wed, 01 Aug 2007 23:23:45 GMT\n";
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(headers));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(NULL, "date", &value));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Tue, 07 Aug 2007 23:10:55 GMT", value);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->EnumerateHeader(NULL, "last-modified", &value));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Wed, 01 Aug 2007 23:23:45 GMT", value);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, DefaultDateToGMT) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify we make the best interpretation when parsing dates that incorrectly
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // do not end in "GMT" as RFC2616 requires.
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers =
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Date: Tue, 07 Aug 2007 23:10:55\n"
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Last-Modified: Tue, 07 Aug 2007 19:10:55 EDT\n"
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Expires: Tue, 07 Aug 2007 23:10:55 UTC\n";
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(headers));
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time expected_value;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(base::Time::FromString("Tue, 07 Aug 2007 23:10:55 GMT",
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &expected_value));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time value;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the timezone is missing, GMT is a good guess as its what RFC2616
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requires.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->GetDateValue(&value));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_value, value);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If GMT is missing but an RFC822-conforming one is present, use that.
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed->GetLastModifiedValue(&value));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_value, value);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If an unknown timezone is present, treat like a missing timezone and
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default to GMT.  The only example of a web server not specifying "GMT"
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // used "UTC" which is equivalent to GMT.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parsed->GetExpiresValue(&value))
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_value, value);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetMimeType) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ContentTypeTestData tests[] = {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n",
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html" },
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Multiple content-type headers should give us the last one.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n"
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n",
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html, text/html" },
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/plain\n"
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n"
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/plain\n"
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n",
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain, text/html, text/plain, text/html" },
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test charset parsing.
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n"
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html; charset=ISO-8859-1\n",
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "iso-8859-1", true,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html, text/html; charset=ISO-8859-1" },
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test charset in double quotes.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n"
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html; charset=\"ISO-8859-1\"\n",
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "iso-8859-1", true,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html, text/html; charset=\"ISO-8859-1\"" },
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If there are multiple matching content-type headers, we carry
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // over the charset value.
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html;charset=utf-8\n"
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n",
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "utf-8", true,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html;charset=utf-8, text/html" },
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test single quotes.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html;charset='utf-8'\n"
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n",
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "utf-8", true,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html;charset='utf-8', text/html" },
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Last charset wins if matching content-type.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html;charset=utf-8\n"
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html;charset=iso-8859-1\n",
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "iso-8859-1", true,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html;charset=utf-8, text/html;charset=iso-8859-1" },
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Charset is ignored if the content types change.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/plain;charset=utf-8\n"
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html\n",
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain;charset=utf-8, text/html" },
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Empty content-type
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: \n",
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "" },
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Emtpy charset
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html;charset=\n",
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html;charset=" },
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Multiple charsets, last one wins.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html;charset=utf-8; charset=iso-8859-1\n",
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "iso-8859-1", true,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html;charset=utf-8; charset=iso-8859-1" },
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Multiple params.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html; foo=utf-8; charset=iso-8859-1\n",
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "iso-8859-1", true,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html; foo=utf-8; charset=iso-8859-1" },
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html ; charset=utf-8 ; bar=iso-8859-1\n",
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "utf-8", true,
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html ; charset=utf-8 ; bar=iso-8859-1" },
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Comma embeded in quotes.
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html ; charset='utf-8,text/plain' ;\n",
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "utf-8,text/plain", true,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html ; charset='utf-8,text/plain' ;" },
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Charset with leading spaces.
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html ; charset= 'utf-8' ;\n",
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "utf-8", true,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html ; charset= 'utf-8' ;" },
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Media type comments in mime-type.
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html (html)\n",
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html (html)" },
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Incomplete charset= param
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/html; char=\n",
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html", true,
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html; char=" },
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invalid media type: no slash
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: texthtml\n",
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "texthtml" },
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invalid media type: */*
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: */*\n",
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "", false,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "*/*" },
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(tests); ++i) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].raw_headers);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string value;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].has_mimetype, parsed->GetMimeType(&value));
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].mime_type, value);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value.clear();
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].has_charset, parsed->GetCharset(&value));
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].charset, value);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(parsed->GetNormalizedHeader("content-type", &value));
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].all_content_type, value);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, RequiresValidation) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool requires_validation;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // no expiry info: expires immediately
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // valid for a little while
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: max-age=10000\n"
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // expires in the future
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "expires: Wed, 28 Nov 2007 01:00:00 GMT\n"
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // expired already
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "expires: Wed, 28 Nov 2007 00:00:00 GMT\n"
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // max-age trumps expires
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "expires: Wed, 28 Nov 2007 00:00:00 GMT\n"
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: max-age=10000\n"
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // last-modified heuristic: modified a while ago
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n"
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 203 Non-Authoritative Information\n"
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n"
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n"
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // last-modified heuristic: modified recently
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n"
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 203 Non-Authoritative Information\n"
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n"
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n"
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached permanent redirect
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved Permanently\n"
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached redirect: not reusable even though by default it would be
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 300 Multiple Choices\n"
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-Control: no-cache\n"
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached forever by default
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 410 Gone\n"
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached temporary redirect: not reusable
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 302 Found\n"
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached temporary redirect: reusable
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 302 Found\n"
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: max-age=10000\n"
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cache-control: max-age=N overrides expires: date in the past
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "expires: Wed, 28 Nov 2007 00:20:11 GMT\n"
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: max-age=10000\n"
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cache-control: no-store overrides expires: in the future
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "expires: Wed, 29 Nov 2007 00:40:11 GMT\n"
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cache-control: no-store,private,no-cache=\"foo\"\n"
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pragma: no-cache overrides last-modified heuristic
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "date: Wed, 28 Nov 2007 00:40:11 GMT\n"
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n"
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "pragma: no-cache\n"
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(darin): add many many more tests here
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time request_time, response_time, current_time;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::FromString("Wed, 28 Nov 2007 00:40:09 GMT", &request_time);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::FromString("Wed, 28 Nov 2007 00:40:12 GMT", &response_time);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::FromString("Wed, 28 Nov 2007 00:45:20 GMT", &current_time);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool requires_validation =
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parsed->RequiresValidation(request_time, response_time, current_time);
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].requires_validation, requires_validation);
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, Update) {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* orig_headers;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* new_headers;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_headers;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n",
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1/1 304 Not Modified\n"
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: private\n",
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1/1 304 Not Modified\n"
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: private\n",
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1/1 304 Not Modified\n"
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-CONTROL: max-age=10000\n",
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-CONTROL: max-age=10000\n"
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n",
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1/1 304 Not Modified\n"
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control:      max-age=10001   \n",
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10001\n"
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string orig_headers(tests[i].orig_headers);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&orig_headers);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(orig_headers));
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string new_headers(tests[i].new_headers);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&new_headers);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> new_parsed(
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(new_headers));
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->Update(*new_parsed);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string resulting_headers;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->GetNormalizedHeaders(&resulting_headers);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, EnumerateHeaderLines) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_lines;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n",
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ""
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n",
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\n"
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Bar: 2\n"
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 3\n",
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1\nBar: 2\nFoo: 3\n"
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1, 2, 3\n",
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: 1, 2, 3\n"
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name, value, lines;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* iter = NULL;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (parsed->EnumerateHeaderLines(&iter, &name, &value)) {
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lines.append(name);
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lines.append(": ");
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lines.append(value);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lines.append("\n");
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_lines), lines);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, IsRedirect) {
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* location;
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_redirect;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n",
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foopy/\n",
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foopy/",
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: \t \n",
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we use the first location header as the target of the redirect
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foo/\n"
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://bar/\n",
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foo/",
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we use the first _valid_ location header as the target of the redirect
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: \n"
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://bar/\n",
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://bar/",
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // bug 1050541 (location header w/ an unescaped comma)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foo/bar,baz.html\n",
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foo/bar,baz.html",
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // bug 1224617 (location header w/ non-ASCII bytes)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foo/bar?key=\xE4\xF6\xFC\n",
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foo/bar?key=%E4%F6%FC",
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Shift_JIS, Big5, and GBK contain multibyte characters with the trailing
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // byte falling in the ASCII range.
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foo/bar?key=\x81\x5E\xD8\xBF\n",
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foo/bar?key=%81^%D8%BF",
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foo/bar?key=\x82\x40\xBD\xC4\n",
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foo/bar?key=%82@%BD%C4",
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 301 Moved\n"
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Location: http://foo/bar?key=\x83\x5C\x82\x5D\xCB\xD7\n",
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://foo/bar?key=%83\\%82]%CB%D7",
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string location;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(parsed->IsRedirect(&location), tests[i].is_redirect);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(location, tests[i].location);
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetContentLength) {
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 expected_len;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n",
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10\n",
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: \n",
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: abc\n",
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: -10\n",
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length:  +10\n",
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 23xb5\n",
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 0xA\n",
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 010\n",
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Content-Length too big, will overflow an int64
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 40000000000000000000\n",
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length:       10\n",
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10  \n",
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: \t10\n",
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: \v10\n",
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: \f10\n",
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "cOnTeNt-LENgth: 33\n",
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      33
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 34\r\n",
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_len, parsed->GetContentLength());
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeaders, GetContentRange) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expected_return_value;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 expected_first_byte_position;
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 expected_last_byte_position;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 expected_instance_size;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }  tests[] = {
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content",
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range:",
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: megabytes 0-10/50",
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: 0-10/50",
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: Bytes 0-50/51",
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      51
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-50/51",
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      51
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes\t0-50/51",
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range:     bytes 0-50/51",
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      51
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range:     bytes    0    -   50  \t / \t51",
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      51
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0\t-\t50\t/\t51\t",
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      51
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range:   \tbytes\t\t\t 0\t-\t50\t/\t51\t",
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      51
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: \t   bytes \t  0    -   50   /   5   1",
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: \t   bytes \t  0    -   5 0   /   51",
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 50-0/51",
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 416 Requested range not satisfiable\n"
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes * /*",
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 416 Requested range not satisfiable\n"
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes *   /    *   ",
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-50/*",
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-50  /    * ",
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-10000000000/10000000001",
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10000000000ll,
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10000000001ll
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-10000000000/10000000000",
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10000000000ll,
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10000000000ll
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 64 bits wraparound.
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0 - 9223372036854775807 / 100",
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kint64max,
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      100
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 64 bits wraparound.
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0 - 100 / -9223372036854775808",
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      100,
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kint64min
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes */50",
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-50/10",
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 40-50/45",
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      40,
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      45
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-50/-10",
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -10
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-0/1",
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-40000000000000000000/40000000000000000001",
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 1-/100",
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes -/100",
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes -1/100",
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes 0-1233/*",
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1233,
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Range: bytes -123 - -1/100",
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 first_byte_position;
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 last_byte_position;
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 instance_size;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool return_value = parsed->GetContentRange(&first_byte_position,
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                &last_byte_position,
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                &instance_size);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_return_value, return_value);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_first_byte_position, first_byte_position);
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_last_byte_position, last_byte_position);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_instance_size, instance_size);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, IsKeepAlive) {
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expected_keep_alive;
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The status line fabricated by HttpNetworkTransaction for a 0.9 response.
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Treated as 0.9.
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/0.9 200 OK",
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This could come from a broken server.  Treated as 1.0 because it has a
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // header.
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/0.9 200 OK\n"
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n",
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n",
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n",
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: close\n",
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n",
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: kEeP-AliVe\n",
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-aliveX\n",
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: close\n",
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n",
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-connection: close\n",
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-connection: keep-alive\n",
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-connection: close\n",
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-connection: keep-alive\n",
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_keep_alive, parsed->IsKeepAlive());
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, HasStrongValidators) {
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* headers;
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expected_result;
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/0.9 200 OK",
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.0 200 OK\n"
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Date: Wed, 28 Nov 2007 01:40:10 GMT\n"
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n"
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ETag: \"foo\"\n",
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Date: Wed, 28 Nov 2007 01:40:10 GMT\n"
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n"
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ETag: \"foo\"\n",
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Date: Wed, 28 Nov 2007 00:41:10 GMT\n"
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n",
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Date: Wed, 28 Nov 2007 00:41:09 GMT\n"
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n",
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ETag: \"foo\"\n",
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is not really a weak etag:
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "etag: \"w/foo\"\n",
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is a weak etag:
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "etag: w/\"foo\"\n",
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "etag:    W  /   \"foo\"\n",
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers(tests[i].headers);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&headers);
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].expected_result, parsed->HasStrongValidators()) <<
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Failed test case " << i;
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetStatusText) {
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers("HTTP/1.1 404 Not Found");
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText());
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetStatusTextMissing) {
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers("HTTP/1.1 404");
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since the status line gets normalized, we have OK
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("OK"), parsed->GetStatusText());
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetStatusTextMultiSpace) {
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers("HTTP/1.0     404     Not   Found");
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("Not   Found"), parsed->GetStatusText());
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, GetStatusBadStatusLine) {
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers("Foo bar.");
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(headers));
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The bad status line would have gotten rewritten as
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP/1.0 200 OK.
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("OK"), parsed->GetStatusText());
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, AddHeader) {
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* orig_headers;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* new_header;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_headers;
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450",
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000    \n",
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450  ",
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string orig_headers(tests[i].orig_headers);
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&orig_headers);
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(orig_headers));
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string new_header(tests[i].new_header);
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->AddHeader(new_header);
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string resulting_headers;
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->GetNormalizedHeaders(&resulting_headers);
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers);
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, RemoveHeader) {
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* orig_headers;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* to_remove;
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_headers;
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n",
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length",
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive  \n"
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length  : 450  \n"
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length",
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string orig_headers(tests[i].orig_headers);
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&orig_headers);
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(orig_headers));
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(tests[i].to_remove);
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->RemoveHeader(name);
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string resulting_headers;
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->GetNormalizedHeaders(&resulting_headers);
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers);
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, RemoveIndividualHeader) {
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* orig_headers;
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* to_remove_name;
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* to_remove_value;
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_headers;
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n",
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length",
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "450",
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive  \n"
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length  : 450  \n"
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length",
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "450",
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive  \n"
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length",  // Matching name.
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "999",  // Mismatching value.
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive  \n"
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: bar, baz\n"
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: bar\n"
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo",
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bar, baz",  // Space in value.
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: bar\n"
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive  \n"
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: bar, baz\n"
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo",
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "baz",  // Only partial match -> ignored.
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Foo: bar, baz\n"
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string orig_headers(tests[i].orig_headers);
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&orig_headers);
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(orig_headers));
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(tests[i].to_remove_name);
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string value(tests[i].to_remove_value);
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->RemoveHeaderLine(name, value);
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string resulting_headers;
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->GetNormalizedHeaders(&resulting_headers);
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers);
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, ReplaceStatus) {
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* orig_headers;
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* new_status;
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected_headers;
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 206 Partial Content\n"
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n",
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK",
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\n"
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n",
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 304 Not Modified",
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 304 Not Modified\n"
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "HTTP/1.1 200 OK\n"
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive  \n"
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length  : 450   \n"
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n",
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1//1 304 Not Modified",
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.0 304 Not Modified\n"
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "connection: keep-alive\n"
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 450\n"
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cache-control: max-age=10000\n"
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string orig_headers(tests[i].orig_headers);
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HeadersToRaw(&orig_headers);
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> parsed(
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::HttpResponseHeaders(orig_headers));
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(tests[i].new_status);
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->ReplaceStatusLine(name);
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string resulting_headers;
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed->GetNormalizedHeaders(&resulting_headers);
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers);
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HttpResponseHeadersTest, ToNetLogParamAndBackAgain) {
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string headers("HTTP/1.1 404\n"
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "Content-Length: 450\n"
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "Connection: keep-alive\n");
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeadersToRaw(&headers);
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> parsed(
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::HttpResponseHeaders(headers));
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> event_param(
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parsed->NetLogCallback(net::NetLog::LOG_ALL_BUT_BYTES));
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> recreated;
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(net::HttpResponseHeaders::FromNetLogParam(event_param.get(),
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        &recreated));
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(recreated.get());
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parsed->GetHttpVersion(), recreated->GetHttpVersion());
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parsed->response_code(), recreated->response_code());
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parsed->GetContentLength(), recreated->GetContentLength());
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parsed->IsKeepAlive(), recreated->IsKeepAlive());
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string normalized_parsed;
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed->GetNormalizedHeaders(&normalized_parsed);
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string normalized_recreated;
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed->GetNormalizedHeaders(&normalized_recreated);
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(normalized_parsed, normalized_recreated);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1846