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 |