OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/spdy/header_coalescer.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "net/spdy/platform/api/spdy_string.h" | |
10 #include "net/spdy/platform/api/spdy_string_utils.h" | |
11 #include "testing/gmock/include/gmock/gmock.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 using ::testing::ElementsAre; | |
15 using ::testing::Pair; | |
16 | |
17 namespace net { | |
18 namespace test { | |
19 | |
20 class HeaderCoalescerTest : public ::testing::Test { | |
21 public: | |
22 protected: | |
23 HeaderCoalescer header_coalescer_; | |
24 }; | |
25 | |
26 TEST_F(HeaderCoalescerTest, CorrectHeaders) { | |
27 header_coalescer_.OnHeader(":foo", "bar"); | |
28 header_coalescer_.OnHeader("baz", "qux"); | |
29 EXPECT_FALSE(header_coalescer_.error_seen()); | |
30 | |
31 SpdyHeaderBlock header_block = header_coalescer_.release_headers(); | |
32 EXPECT_THAT(header_block, | |
33 ElementsAre(Pair(":foo", "bar"), Pair("baz", "qux"))); | |
34 } | |
35 | |
36 TEST_F(HeaderCoalescerTest, EmptyHeaderKey) { | |
37 EXPECT_FALSE(header_coalescer_.error_seen()); | |
38 header_coalescer_.OnHeader("", "foo"); | |
39 EXPECT_TRUE(header_coalescer_.error_seen()); | |
40 } | |
41 | |
42 TEST_F(HeaderCoalescerTest, HeaderBlockTooLarge) { | |
43 // 3 byte key, 256 * 1024 - 40 byte value, 32 byte overhead: | |
44 // less than 256 * 1024 bytes in total. | |
45 SpdyString data(256 * 1024 - 40, 'a'); | |
46 header_coalescer_.OnHeader("foo", data); | |
47 EXPECT_FALSE(header_coalescer_.error_seen()); | |
48 | |
49 // Another 3 + 3 + 32 bytes: too large. | |
50 header_coalescer_.OnHeader("bar", "baz"); | |
51 EXPECT_TRUE(header_coalescer_.error_seen()); | |
52 } | |
53 | |
54 TEST_F(HeaderCoalescerTest, PseudoHeadersMustNotFollowRegularHeaders) { | |
55 header_coalescer_.OnHeader("foo", "bar"); | |
56 EXPECT_FALSE(header_coalescer_.error_seen()); | |
57 header_coalescer_.OnHeader(":baz", "qux"); | |
58 EXPECT_TRUE(header_coalescer_.error_seen()); | |
59 } | |
60 | |
61 TEST_F(HeaderCoalescerTest, Append) { | |
62 header_coalescer_.OnHeader("foo", "bar"); | |
63 header_coalescer_.OnHeader("cookie", "baz"); | |
64 header_coalescer_.OnHeader("foo", "quux"); | |
65 header_coalescer_.OnHeader("cookie", "qux"); | |
66 EXPECT_FALSE(header_coalescer_.error_seen()); | |
67 | |
68 SpdyHeaderBlock header_block = header_coalescer_.release_headers(); | |
69 EXPECT_THAT(header_block, | |
70 ElementsAre(Pair("foo", SpdyStringPiece("bar\0quux", 8)), | |
71 Pair("cookie", "baz; qux"))); | |
72 } | |
73 | |
74 TEST_F(HeaderCoalescerTest, CRLFInHeaderValue) { | |
75 EXPECT_FALSE(header_coalescer_.error_seen()); | |
76 header_coalescer_.OnHeader("foo", "bar\r\nbaz"); | |
77 EXPECT_TRUE(header_coalescer_.error_seen()); | |
78 } | |
79 | |
80 TEST_F(HeaderCoalescerTest, HeaderNameNotValid) { | |
81 SpdyStringPiece header_name("\x01\x7F\x80\xff"); | |
82 header_coalescer_.OnHeader(header_name, "foo"); | |
83 EXPECT_TRUE(header_coalescer_.error_seen()); | |
84 } | |
85 | |
86 // RFC 7230 Section 3.2. Valid header name is defined as: | |
87 // field-name = token | |
88 // token = 1*tchar | |
89 // tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / | |
90 // "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA | |
91 TEST_F(HeaderCoalescerTest, HeaderNameValid) { | |
92 SpdyStringPiece header_name( | |
93 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'*+-." | |
94 "^_`|~"); | |
95 header_coalescer_.OnHeader(header_name, "foo"); | |
96 EXPECT_FALSE(header_coalescer_.error_seen()); | |
97 SpdyHeaderBlock header_block = header_coalescer_.release_headers(); | |
98 EXPECT_THAT(header_block, ElementsAre(Pair(header_name, "foo"))); | |
99 } | |
100 | |
101 // RFC 7230 Section 3.2. Valid header value is defined as: | |
102 // field-value = *( field-content / obs-fold ) | |
103 // field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] | |
104 // field-vchar = VCHAR / obs-text | |
105 // | |
106 // obs-fold = CRLF 1*( SP / HTAB ) | |
107 // ; obsolete line folding | |
108 // ; see Section 3.2.4 | |
109 TEST_F(HeaderCoalescerTest, HeaderValueValid) { | |
110 // Add two headers, one with an HTAB and one with a SP. | |
111 std::vector<char> header_values[2]; | |
112 char prefixes[] = {'\t', ' '}; | |
113 for (int i = 0; i < 2; ++i) { | |
114 header_values[i] = std::vector<char>(); | |
115 header_values[i].push_back(prefixes[i]); | |
116 // obs-text. From 0x80 to 0xff. | |
117 for (int j = 0x80; j <= 0xff; ++j) { | |
118 header_values[i].push_back(j); | |
119 } | |
120 // vchar | |
121 for (int j = 0x21; j <= 0x7E; ++j) { | |
122 header_values[i].push_back(j); | |
123 } | |
124 header_coalescer_.OnHeader( | |
125 SpdyStringPrintf("%s_%d", "foo", i), | |
126 SpdyStringPiece(header_values[i].data(), header_values[i].size())); | |
127 EXPECT_FALSE(header_coalescer_.error_seen()); | |
128 } | |
129 SpdyHeaderBlock header_block = header_coalescer_.release_headers(); | |
130 EXPECT_THAT( | |
131 header_block, | |
132 ElementsAre(Pair("foo_0", SpdyStringPiece(header_values[0].data(), | |
133 header_values[0].size())), | |
134 Pair("foo_1", SpdyStringPiece(header_values[1].data(), | |
135 header_values[1].size())))); | |
136 } | |
137 | |
138 } // namespace test | |
139 | |
140 } // namespace net | |
OLD | NEW |