| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "net/http/http_util.h" | 9 #include "net/http/http_util.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 11 |
| 12 using net::HttpUtil; | 12 using net::HttpUtil; |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 class HttpUtilTest : public testing::Test {}; | 15 class HttpUtilTest : public testing::Test {}; |
| 16 } | 16 } |
| 17 | 17 |
| 18 TEST(HttpUtilTest, IsSafeHeader) { | 18 TEST(HttpUtilTest, IsSafeHeader) { |
| 19 static const char* unsafe_headers[] = { | 19 static const char* const unsafe_headers[] = { |
| 20 "sec-", | 20 "sec-", |
| 21 "sEc-", | 21 "sEc-", |
| 22 "sec-foo", | 22 "sec-foo", |
| 23 "sEc-FoO", | 23 "sEc-FoO", |
| 24 "proxy-", | 24 "proxy-", |
| 25 "pRoXy-", | 25 "pRoXy-", |
| 26 "proxy-foo", | 26 "proxy-foo", |
| 27 "pRoXy-FoO", | 27 "pRoXy-FoO", |
| 28 "accept-charset", | 28 "accept-charset", |
| 29 "accept-encoding", | 29 "accept-encoding", |
| (...skipping 16 matching lines...) Expand all Loading... |
| 46 "upgrade", | 46 "upgrade", |
| 47 "user-agent", | 47 "user-agent", |
| 48 "via", | 48 "via", |
| 49 }; | 49 }; |
| 50 for (size_t i = 0; i < arraysize(unsafe_headers); ++i) { | 50 for (size_t i = 0; i < arraysize(unsafe_headers); ++i) { |
| 51 EXPECT_FALSE(HttpUtil::IsSafeHeader(unsafe_headers[i])) | 51 EXPECT_FALSE(HttpUtil::IsSafeHeader(unsafe_headers[i])) |
| 52 << unsafe_headers[i]; | 52 << unsafe_headers[i]; |
| 53 EXPECT_FALSE(HttpUtil::IsSafeHeader(StringToUpperASCII(std::string( | 53 EXPECT_FALSE(HttpUtil::IsSafeHeader(StringToUpperASCII(std::string( |
| 54 unsafe_headers[i])))) << unsafe_headers[i]; | 54 unsafe_headers[i])))) << unsafe_headers[i]; |
| 55 } | 55 } |
| 56 static const char* safe_headers[] = { | 56 static const char* const safe_headers[] = { |
| 57 "foo", | 57 "foo", |
| 58 "x-", | 58 "x-", |
| 59 "x-foo", | 59 "x-foo", |
| 60 "content-disposition", | 60 "content-disposition", |
| 61 "update", | 61 "update", |
| 62 "accept-charseta", | 62 "accept-charseta", |
| 63 "accept_charset", | 63 "accept_charset", |
| 64 "accept-encodinga", | 64 "accept-encodinga", |
| 65 "accept_encoding", | 65 "accept_encoding", |
| 66 "access-control-request-headersa", | 66 "access-control-request-headersa", |
| (...skipping 28 matching lines...) Expand all Loading... |
| 95 }; | 95 }; |
| 96 for (size_t i = 0; i < arraysize(safe_headers); ++i) { | 96 for (size_t i = 0; i < arraysize(safe_headers); ++i) { |
| 97 EXPECT_TRUE(HttpUtil::IsSafeHeader(safe_headers[i])) << safe_headers[i]; | 97 EXPECT_TRUE(HttpUtil::IsSafeHeader(safe_headers[i])) << safe_headers[i]; |
| 98 EXPECT_TRUE(HttpUtil::IsSafeHeader(StringToUpperASCII(std::string( | 98 EXPECT_TRUE(HttpUtil::IsSafeHeader(StringToUpperASCII(std::string( |
| 99 safe_headers[i])))) << safe_headers[i]; | 99 safe_headers[i])))) << safe_headers[i]; |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 | 102 |
| 103 TEST(HttpUtilTest, HasHeader) { | 103 TEST(HttpUtilTest, HasHeader) { |
| 104 static const struct { | 104 static const struct { |
| 105 const char* headers; | 105 const char* const headers; |
| 106 const char* name; | 106 const char* const name; |
| 107 bool expected_result; | 107 bool expected_result; |
| 108 } tests[] = { | 108 } tests[] = { |
| 109 { "", "foo", false }, | 109 { "", "foo", false }, |
| 110 { "foo\r\nbar", "foo", false }, | 110 { "foo\r\nbar", "foo", false }, |
| 111 { "ffoo: 1", "foo", false }, | 111 { "ffoo: 1", "foo", false }, |
| 112 { "foo: 1", "foo", true }, | 112 { "foo: 1", "foo", true }, |
| 113 { "foo: 1\r\nbar: 2", "foo", true }, | 113 { "foo: 1\r\nbar: 2", "foo", true }, |
| 114 { "fOO: 1\r\nbar: 2", "foo", true }, | 114 { "fOO: 1\r\nbar: 2", "foo", true }, |
| 115 { "g: 0\r\nfoo: 1\r\nbar: 2", "foo", true }, | 115 { "g: 0\r\nfoo: 1\r\nbar: 2", "foo", true }, |
| 116 }; | 116 }; |
| 117 for (size_t i = 0; i < arraysize(tests); ++i) { | 117 for (size_t i = 0; i < arraysize(tests); ++i) { |
| 118 bool result = HttpUtil::HasHeader(tests[i].headers, tests[i].name); | 118 bool result = HttpUtil::HasHeader(tests[i].headers, tests[i].name); |
| 119 EXPECT_EQ(tests[i].expected_result, result); | 119 EXPECT_EQ(tests[i].expected_result, result); |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 | 122 |
| 123 TEST(HttpUtilTest, StripHeaders) { | 123 TEST(HttpUtilTest, StripHeaders) { |
| 124 static const char* headers = | 124 static const char* const headers = |
| 125 "Origin: origin\r\n" | 125 "Origin: origin\r\n" |
| 126 "Content-Type: text/plain\r\n" | 126 "Content-Type: text/plain\r\n" |
| 127 "Cookies: foo1\r\n" | 127 "Cookies: foo1\r\n" |
| 128 "Custom: baz\r\n" | 128 "Custom: baz\r\n" |
| 129 "COOKIES: foo2\r\n" | 129 "COOKIES: foo2\r\n" |
| 130 "Server: Apache\r\n" | 130 "Server: Apache\r\n" |
| 131 "OrIGin: origin2\r\n"; | 131 "OrIGin: origin2\r\n"; |
| 132 | 132 |
| 133 static const char* header_names[] = { | 133 static const char* const header_names[] = { |
| 134 "origin", "content-type", "cookies" | 134 "origin", "content-type", "cookies" |
| 135 }; | 135 }; |
| 136 | 136 |
| 137 static const char* expected_stripped_headers = | 137 static const char* const expected_stripped_headers = |
| 138 "Custom: baz\r\n" | 138 "Custom: baz\r\n" |
| 139 "Server: Apache\r\n"; | 139 "Server: Apache\r\n"; |
| 140 | 140 |
| 141 EXPECT_EQ(expected_stripped_headers, | 141 EXPECT_EQ(expected_stripped_headers, |
| 142 HttpUtil::StripHeaders(headers, header_names, | 142 HttpUtil::StripHeaders(headers, header_names, |
| 143 arraysize(header_names))); | 143 arraysize(header_names))); |
| 144 } | 144 } |
| 145 | 145 |
| 146 TEST(HttpUtilTest, HeadersIterator) { | 146 TEST(HttpUtilTest, HeadersIterator) { |
| 147 std::string headers = "foo: 1\t\r\nbar: hello world\r\nbaz: 3 \r\n"; | 147 std::string headers = "foo: 1\t\r\nbar: hello world\r\nbaz: 3 \r\n"; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 | 255 |
| 256 // Replace <backslash> <backslash> with <backslash> | 256 // Replace <backslash> <backslash> with <backslash> |
| 257 EXPECT_STREQ("\"xyz\\\\abc\"", HttpUtil::Quote("xyz\\abc").c_str()); | 257 EXPECT_STREQ("\"xyz\\\\abc\"", HttpUtil::Quote("xyz\\abc").c_str()); |
| 258 | 258 |
| 259 // Replace <backslash> X with X | 259 // Replace <backslash> X with X |
| 260 EXPECT_STREQ("\"xyzXabc\"", HttpUtil::Quote("xyzXabc").c_str()); | 260 EXPECT_STREQ("\"xyzXabc\"", HttpUtil::Quote("xyzXabc").c_str()); |
| 261 } | 261 } |
| 262 | 262 |
| 263 TEST(HttpUtilTest, LocateEndOfHeaders) { | 263 TEST(HttpUtilTest, LocateEndOfHeaders) { |
| 264 struct { | 264 struct { |
| 265 const char* input; | 265 const char* const input; |
| 266 int expected_result; | 266 int expected_result; |
| 267 } tests[] = { | 267 } tests[] = { |
| 268 { "foo\r\nbar\r\n\r\n", 12 }, | 268 { "foo\r\nbar\r\n\r\n", 12 }, |
| 269 { "foo\nbar\n\n", 9 }, | 269 { "foo\nbar\n\n", 9 }, |
| 270 { "foo\r\nbar\r\n\r\njunk", 12 }, | 270 { "foo\r\nbar\r\n\r\njunk", 12 }, |
| 271 { "foo\nbar\n\njunk", 9 }, | 271 { "foo\nbar\n\njunk", 9 }, |
| 272 { "foo\nbar\n\r\njunk", 10 }, | 272 { "foo\nbar\n\r\njunk", 10 }, |
| 273 { "foo\nbar\r\n\njunk", 10 }, | 273 { "foo\nbar\r\n\njunk", 10 }, |
| 274 }; | 274 }; |
| 275 for (size_t i = 0; i < arraysize(tests); ++i) { | 275 for (size_t i = 0; i < arraysize(tests); ++i) { |
| 276 int input_len = static_cast<int>(strlen(tests[i].input)); | 276 int input_len = static_cast<int>(strlen(tests[i].input)); |
| 277 int eoh = HttpUtil::LocateEndOfHeaders(tests[i].input, input_len); | 277 int eoh = HttpUtil::LocateEndOfHeaders(tests[i].input, input_len); |
| 278 EXPECT_EQ(tests[i].expected_result, eoh); | 278 EXPECT_EQ(tests[i].expected_result, eoh); |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 | 281 |
| 282 TEST(HttpUtilTest, AssembleRawHeaders) { | 282 TEST(HttpUtilTest, AssembleRawHeaders) { |
| 283 struct { | 283 struct { |
| 284 const char* input; // with '|' representing '\0' | 284 const char* const input; // with '|' representing '\0' |
| 285 const char* expected_result; // with '\0' changed to '|' | 285 const char* const expected_result; // with '\0' changed to '|' |
| 286 } tests[] = { | 286 } tests[] = { |
| 287 { "HTTP/1.0 200 OK\r\nFoo: 1\r\nBar: 2\r\n\r\n", | 287 { "HTTP/1.0 200 OK\r\nFoo: 1\r\nBar: 2\r\n\r\n", |
| 288 "HTTP/1.0 200 OK|Foo: 1|Bar: 2||" }, | 288 "HTTP/1.0 200 OK|Foo: 1|Bar: 2||" }, |
| 289 | 289 |
| 290 { "HTTP/1.0 200 OK\nFoo: 1\nBar: 2\n\n", | 290 { "HTTP/1.0 200 OK\nFoo: 1\nBar: 2\n\n", |
| 291 "HTTP/1.0 200 OK|Foo: 1|Bar: 2||" }, | 291 "HTTP/1.0 200 OK|Foo: 1|Bar: 2||" }, |
| 292 | 292 |
| 293 // Valid line continuation (single SP). | 293 // Valid line continuation (single SP). |
| 294 { | 294 { |
| 295 "HTTP/1.0 200 OK\n" | 295 "HTTP/1.0 200 OK\n" |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 std::replace(input.begin(), input.end(), '|', '\0'); | 587 std::replace(input.begin(), input.end(), '|', '\0'); |
| 588 std::string raw = HttpUtil::AssembleRawHeaders(input.data(), input.size()); | 588 std::string raw = HttpUtil::AssembleRawHeaders(input.data(), input.size()); |
| 589 std::replace(raw.begin(), raw.end(), '\0', '|'); | 589 std::replace(raw.begin(), raw.end(), '\0', '|'); |
| 590 EXPECT_EQ(tests[i].expected_result, raw); | 590 EXPECT_EQ(tests[i].expected_result, raw); |
| 591 } | 591 } |
| 592 } | 592 } |
| 593 | 593 |
| 594 // Test SpecForRequest() and PathForRequest(). | 594 // Test SpecForRequest() and PathForRequest(). |
| 595 TEST(HttpUtilTest, RequestUrlSanitize) { | 595 TEST(HttpUtilTest, RequestUrlSanitize) { |
| 596 struct { | 596 struct { |
| 597 const char* url; | 597 const char* const url; |
| 598 const char* expected_spec; | 598 const char* const expected_spec; |
| 599 const char* expected_path; | 599 const char* const expected_path; |
| 600 } tests[] = { | 600 } tests[] = { |
| 601 { // Check that #hash is removed. | 601 { // Check that #hash is removed. |
| 602 "http://www.google.com:78/foobar?query=1#hash", | 602 "http://www.google.com:78/foobar?query=1#hash", |
| 603 "http://www.google.com:78/foobar?query=1", | 603 "http://www.google.com:78/foobar?query=1", |
| 604 "/foobar?query=1" | 604 "/foobar?query=1" |
| 605 }, | 605 }, |
| 606 { // The reference may itself contain # -- strip all of it. | 606 { // The reference may itself contain # -- strip all of it. |
| 607 "http://192.168.0.1?query=1#hash#10#11#13#14", | 607 "http://192.168.0.1?query=1#hash#10#11#13#14", |
| 608 "http://192.168.0.1/?query=1", | 608 "http://192.168.0.1/?query=1", |
| 609 "/?query=1" | 609 "/?query=1" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 EXPECT_EQ(std::string("en-US,fr;q=0.8,de;q=0.6"), | 650 EXPECT_EQ(std::string("en-US,fr;q=0.8,de;q=0.6"), |
| 651 HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de")); | 651 HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de")); |
| 652 EXPECT_EQ(std::string("en-US,fr;q=0.8,de;q=0.6,ko;q=0.4,zh-CN;q=0.2," | 652 EXPECT_EQ(std::string("en-US,fr;q=0.8,de;q=0.6,ko;q=0.4,zh-CN;q=0.2," |
| 653 "ja;q=0.2"), | 653 "ja;q=0.2"), |
| 654 HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de,ko,zh-CN,ja")); | 654 HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de,ko,zh-CN,ja")); |
| 655 } | 655 } |
| 656 | 656 |
| 657 // HttpResponseHeadersTest.GetMimeType also tests ParseContentType. | 657 // HttpResponseHeadersTest.GetMimeType also tests ParseContentType. |
| 658 TEST(HttpUtilTest, ParseContentType) { | 658 TEST(HttpUtilTest, ParseContentType) { |
| 659 const struct { | 659 const struct { |
| 660 const char* content_type; | 660 const char* const content_type; |
| 661 const char* expected_mime_type; | 661 const char* const expected_mime_type; |
| 662 const char* expected_charset; | 662 const char* const expected_charset; |
| 663 const bool expected_had_charset; | 663 const bool expected_had_charset; |
| 664 const char* expected_boundary; | 664 const char* const expected_boundary; |
| 665 } tests[] = { | 665 } tests[] = { |
| 666 { "text/html; charset=utf-8", | 666 { "text/html; charset=utf-8", |
| 667 "text/html", | 667 "text/html", |
| 668 "utf-8", | 668 "utf-8", |
| 669 true, | 669 true, |
| 670 "" | 670 "" |
| 671 }, | 671 }, |
| 672 { "text/html; charset =utf-8", | 672 { "text/html; charset =utf-8", |
| 673 "text/html", | 673 "text/html", |
| 674 "utf-8", | 674 "utf-8", |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 &charset, &had_charset, &boundary); | 734 &charset, &had_charset, &boundary); |
| 735 EXPECT_EQ(tests[i].expected_mime_type, mime_type) << "i=" << i; | 735 EXPECT_EQ(tests[i].expected_mime_type, mime_type) << "i=" << i; |
| 736 EXPECT_EQ(tests[i].expected_charset, charset) << "i=" << i; | 736 EXPECT_EQ(tests[i].expected_charset, charset) << "i=" << i; |
| 737 EXPECT_EQ(tests[i].expected_had_charset, had_charset) << "i=" << i; | 737 EXPECT_EQ(tests[i].expected_had_charset, had_charset) << "i=" << i; |
| 738 EXPECT_EQ(tests[i].expected_boundary, boundary) << "i=" << i; | 738 EXPECT_EQ(tests[i].expected_boundary, boundary) << "i=" << i; |
| 739 } | 739 } |
| 740 } | 740 } |
| 741 | 741 |
| 742 TEST(HttpUtilTest, ParseRanges) { | 742 TEST(HttpUtilTest, ParseRanges) { |
| 743 const struct { | 743 const struct { |
| 744 const char* headers; | 744 const char* const headers; |
| 745 bool expected_return_value; | 745 bool expected_return_value; |
| 746 size_t expected_ranges_size; | 746 size_t expected_ranges_size; |
| 747 const struct { | 747 const struct { |
| 748 int64 expected_first_byte_position; | 748 int64 expected_first_byte_position; |
| 749 int64 expected_last_byte_position; | 749 int64 expected_last_byte_position; |
| 750 int64 expected_suffix_length; | 750 int64 expected_suffix_length; |
| 751 } expected_ranges[10]; | 751 } expected_ranges[10]; |
| 752 } tests[] = { | 752 } tests[] = { |
| 753 { "Range: bytes=0-10", | 753 { "Range: bytes=0-10", |
| 754 true, | 754 true, |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 TEST(HttpUtilTest, NameValuePairsIteratorMissingEndQuote) { | 1107 TEST(HttpUtilTest, NameValuePairsIteratorMissingEndQuote) { |
| 1108 std::string data = "name='value"; | 1108 std::string data = "name='value"; |
| 1109 HttpUtil::NameValuePairsIterator parser(data.begin(), data.end(), ';'); | 1109 HttpUtil::NameValuePairsIterator parser(data.begin(), data.end(), ';'); |
| 1110 EXPECT_TRUE(parser.valid()); | 1110 EXPECT_TRUE(parser.valid()); |
| 1111 | 1111 |
| 1112 ASSERT_NO_FATAL_FAILURE( | 1112 ASSERT_NO_FATAL_FAILURE( |
| 1113 CheckNextNameValuePair(&parser, true, true, "name", "value")); | 1113 CheckNextNameValuePair(&parser, true, true, "name", "value")); |
| 1114 ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair( | 1114 ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair( |
| 1115 &parser, false, true, std::string(), std::string())); | 1115 &parser, false, true, std::string(), std::string())); |
| 1116 } | 1116 } |
| OLD | NEW |