1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/http/http_util.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <algorithm>
8*6777b538SAndroid Build Coastguard Worker #include <limits>
9*6777b538SAndroid Build Coastguard Worker #include <string_view>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
13*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace net {
16*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,IsSafeHeader)17*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, IsSafeHeader) {
18*6777b538SAndroid Build Coastguard Worker static const char* const unsafe_headers[] = {
19*6777b538SAndroid Build Coastguard Worker "sec-",
20*6777b538SAndroid Build Coastguard Worker "sEc-",
21*6777b538SAndroid Build Coastguard Worker "sec-foo",
22*6777b538SAndroid Build Coastguard Worker "sEc-FoO",
23*6777b538SAndroid Build Coastguard Worker "proxy-",
24*6777b538SAndroid Build Coastguard Worker "pRoXy-",
25*6777b538SAndroid Build Coastguard Worker "proxy-foo",
26*6777b538SAndroid Build Coastguard Worker "pRoXy-FoO",
27*6777b538SAndroid Build Coastguard Worker "accept-charset",
28*6777b538SAndroid Build Coastguard Worker "accept-encoding",
29*6777b538SAndroid Build Coastguard Worker "access-control-request-headers",
30*6777b538SAndroid Build Coastguard Worker "access-control-request-method",
31*6777b538SAndroid Build Coastguard Worker "access-control-request-private-network",
32*6777b538SAndroid Build Coastguard Worker "connection",
33*6777b538SAndroid Build Coastguard Worker "content-length",
34*6777b538SAndroid Build Coastguard Worker "cookie",
35*6777b538SAndroid Build Coastguard Worker "cookie2",
36*6777b538SAndroid Build Coastguard Worker "date",
37*6777b538SAndroid Build Coastguard Worker "dnt",
38*6777b538SAndroid Build Coastguard Worker "expect",
39*6777b538SAndroid Build Coastguard Worker "host",
40*6777b538SAndroid Build Coastguard Worker "keep-alive",
41*6777b538SAndroid Build Coastguard Worker "origin",
42*6777b538SAndroid Build Coastguard Worker "referer",
43*6777b538SAndroid Build Coastguard Worker "set-cookie",
44*6777b538SAndroid Build Coastguard Worker "te",
45*6777b538SAndroid Build Coastguard Worker "trailer",
46*6777b538SAndroid Build Coastguard Worker "transfer-encoding",
47*6777b538SAndroid Build Coastguard Worker "upgrade",
48*6777b538SAndroid Build Coastguard Worker "user-agent",
49*6777b538SAndroid Build Coastguard Worker "via",
50*6777b538SAndroid Build Coastguard Worker };
51*6777b538SAndroid Build Coastguard Worker for (const auto* unsafe_header : unsafe_headers) {
52*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsSafeHeader(unsafe_header, "")) << unsafe_header;
53*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsSafeHeader(base::ToUpperASCII(unsafe_header), ""))
54*6777b538SAndroid Build Coastguard Worker << unsafe_header;
55*6777b538SAndroid Build Coastguard Worker }
56*6777b538SAndroid Build Coastguard Worker static const char* const safe_headers[] = {
57*6777b538SAndroid Build Coastguard Worker "foo",
58*6777b538SAndroid Build Coastguard Worker "x-",
59*6777b538SAndroid Build Coastguard Worker "x-foo",
60*6777b538SAndroid Build Coastguard Worker "content-disposition",
61*6777b538SAndroid Build Coastguard Worker "update",
62*6777b538SAndroid Build Coastguard Worker "accept-charseta",
63*6777b538SAndroid Build Coastguard Worker "accept_charset",
64*6777b538SAndroid Build Coastguard Worker "accept-encodinga",
65*6777b538SAndroid Build Coastguard Worker "accept_encoding",
66*6777b538SAndroid Build Coastguard Worker "access-control-request-headersa",
67*6777b538SAndroid Build Coastguard Worker "access-control-request-header",
68*6777b538SAndroid Build Coastguard Worker "access_control_request_header",
69*6777b538SAndroid Build Coastguard Worker "access-control-request-methoda",
70*6777b538SAndroid Build Coastguard Worker "access_control_request_method",
71*6777b538SAndroid Build Coastguard Worker "connectiona",
72*6777b538SAndroid Build Coastguard Worker "content-lengtha",
73*6777b538SAndroid Build Coastguard Worker "content_length",
74*6777b538SAndroid Build Coastguard Worker "content-transfer-encoding",
75*6777b538SAndroid Build Coastguard Worker "cookiea",
76*6777b538SAndroid Build Coastguard Worker "cookie2a",
77*6777b538SAndroid Build Coastguard Worker "cookie3",
78*6777b538SAndroid Build Coastguard Worker "content-transfer-encodinga",
79*6777b538SAndroid Build Coastguard Worker "content_transfer_encoding",
80*6777b538SAndroid Build Coastguard Worker "datea",
81*6777b538SAndroid Build Coastguard Worker "expecta",
82*6777b538SAndroid Build Coastguard Worker "hosta",
83*6777b538SAndroid Build Coastguard Worker "keep-alivea",
84*6777b538SAndroid Build Coastguard Worker "keep_alive",
85*6777b538SAndroid Build Coastguard Worker "origina",
86*6777b538SAndroid Build Coastguard Worker "referera",
87*6777b538SAndroid Build Coastguard Worker "referrer",
88*6777b538SAndroid Build Coastguard Worker "tea",
89*6777b538SAndroid Build Coastguard Worker "trailera",
90*6777b538SAndroid Build Coastguard Worker "transfer-encodinga",
91*6777b538SAndroid Build Coastguard Worker "transfer_encoding",
92*6777b538SAndroid Build Coastguard Worker "upgradea",
93*6777b538SAndroid Build Coastguard Worker "user-agenta",
94*6777b538SAndroid Build Coastguard Worker "user_agent",
95*6777b538SAndroid Build Coastguard Worker "viaa",
96*6777b538SAndroid Build Coastguard Worker // Following 3 headers are safe if there is no forbidden method in values.
97*6777b538SAndroid Build Coastguard Worker "x-http-method",
98*6777b538SAndroid Build Coastguard Worker "x-http-method-override",
99*6777b538SAndroid Build Coastguard Worker "x-method-override",
100*6777b538SAndroid Build Coastguard Worker };
101*6777b538SAndroid Build Coastguard Worker for (const auto* safe_header : safe_headers) {
102*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsSafeHeader(safe_header, "")) << safe_header;
103*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsSafeHeader(base::ToUpperASCII(safe_header), ""))
104*6777b538SAndroid Build Coastguard Worker << safe_header;
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker
107*6777b538SAndroid Build Coastguard Worker static const char* const disallowed_with_forbidden_methods_headers[] = {
108*6777b538SAndroid Build Coastguard Worker "x-http-method",
109*6777b538SAndroid Build Coastguard Worker "x-http-method-override",
110*6777b538SAndroid Build Coastguard Worker "x-method-override",
111*6777b538SAndroid Build Coastguard Worker };
112*6777b538SAndroid Build Coastguard Worker static const struct {
113*6777b538SAndroid Build Coastguard Worker const char* value;
114*6777b538SAndroid Build Coastguard Worker bool is_safe;
115*6777b538SAndroid Build Coastguard Worker } disallowed_values[] = {{"connect", false},
116*6777b538SAndroid Build Coastguard Worker {"trace", false},
117*6777b538SAndroid Build Coastguard Worker {"track", false},
118*6777b538SAndroid Build Coastguard Worker {"CONNECT", false},
119*6777b538SAndroid Build Coastguard Worker {"cOnnEcT", false},
120*6777b538SAndroid Build Coastguard Worker {"get", true},
121*6777b538SAndroid Build Coastguard Worker {"get,post", true},
122*6777b538SAndroid Build Coastguard Worker {"get,connect", false},
123*6777b538SAndroid Build Coastguard Worker {"get, connect", false},
124*6777b538SAndroid Build Coastguard Worker {"get,connect ", false},
125*6777b538SAndroid Build Coastguard Worker {"get,connect ,post", false},
126*6777b538SAndroid Build Coastguard Worker {"get,,,,connect", false},
127*6777b538SAndroid Build Coastguard Worker {"trace,get,PUT", false}};
128*6777b538SAndroid Build Coastguard Worker for (const auto* header : disallowed_with_forbidden_methods_headers) {
129*6777b538SAndroid Build Coastguard Worker for (const auto& test_case : disallowed_values) {
130*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test_case.is_safe,
131*6777b538SAndroid Build Coastguard Worker HttpUtil::IsSafeHeader(header, test_case.value))
132*6777b538SAndroid Build Coastguard Worker << header << ": " << test_case.value;
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker }
135*6777b538SAndroid Build Coastguard Worker }
136*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HeadersIterator)137*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HeadersIterator) {
138*6777b538SAndroid Build Coastguard Worker std::string headers = "foo: 1\t\r\nbar: hello world\r\nbaz: 3 \r\n";
139*6777b538SAndroid Build Coastguard Worker
140*6777b538SAndroid Build Coastguard Worker HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
143*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("foo"), it.name());
144*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("1"), it.values());
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
147*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("bar"), it.name());
148*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("hello world"), it.values());
149*6777b538SAndroid Build Coastguard Worker
150*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
151*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("baz"), it.name());
152*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("3"), it.values());
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HeadersIterator_MalformedLine)157*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HeadersIterator_MalformedLine) {
158*6777b538SAndroid Build Coastguard Worker std::string headers = "foo: 1\n: 2\n3\nbar: 4";
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n");
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
163*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("foo"), it.name());
164*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("1"), it.values());
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
167*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("bar"), it.name());
168*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("4"), it.values());
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HeadersIterator_MalformedName)173*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HeadersIterator_MalformedName) {
174*6777b538SAndroid Build Coastguard Worker std::string headers = "[ignore me] /: 3\r\n";
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard Worker HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
177*6777b538SAndroid Build Coastguard Worker
178*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HeadersIterator_MalformedNameFollowedByValidLine)181*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HeadersIterator_MalformedNameFollowedByValidLine) {
182*6777b538SAndroid Build Coastguard Worker std::string headers = "[ignore me] /: 3\r\nbar: 4\n";
183*6777b538SAndroid Build Coastguard Worker
184*6777b538SAndroid Build Coastguard Worker HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
185*6777b538SAndroid Build Coastguard Worker
186*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
187*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("bar"), it.name());
188*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("4"), it.values());
189*6777b538SAndroid Build Coastguard Worker
190*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HeadersIterator_AdvanceTo)193*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HeadersIterator_AdvanceTo) {
194*6777b538SAndroid Build Coastguard Worker std::string headers = "foo: 1\r\n: 2\r\n3\r\nbar: 4";
195*6777b538SAndroid Build Coastguard Worker
196*6777b538SAndroid Build Coastguard Worker HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
197*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(it.AdvanceTo("foo"));
198*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("foo", it.name());
199*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(it.AdvanceTo("bar"));
200*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("bar", it.name());
201*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.AdvanceTo("blat"));
202*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext()); // should be at end of headers
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HeadersIterator_Reset)205*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HeadersIterator_Reset) {
206*6777b538SAndroid Build Coastguard Worker std::string headers = "foo: 1\r\n: 2\r\n3\r\nbar: 4";
207*6777b538SAndroid Build Coastguard Worker HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
208*6777b538SAndroid Build Coastguard Worker // Search past "foo".
209*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(it.AdvanceTo("bar"));
210*6777b538SAndroid Build Coastguard Worker // Now try advancing to "foo". This time it should fail since the iterator
211*6777b538SAndroid Build Coastguard Worker // position is past it.
212*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.AdvanceTo("foo"));
213*6777b538SAndroid Build Coastguard Worker it.Reset();
214*6777b538SAndroid Build Coastguard Worker // Now that we reset the iterator position, we should find 'foo'
215*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(it.AdvanceTo("foo"));
216*6777b538SAndroid Build Coastguard Worker }
217*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ValuesIterator)218*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ValuesIterator) {
219*6777b538SAndroid Build Coastguard Worker std::string values = " must-revalidate, no-cache=\"foo, bar\"\t, private ";
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker HttpUtil::ValuesIterator it(values.begin(), values.end(), ',',
222*6777b538SAndroid Build Coastguard Worker true /* ignore_empty_values */);
223*6777b538SAndroid Build Coastguard Worker
224*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
225*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("must-revalidate"), it.value());
226*6777b538SAndroid Build Coastguard Worker
227*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
228*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("no-cache=\"foo, bar\""), it.value());
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
231*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("private"), it.value());
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ValuesIterator_EmptyValues)236*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ValuesIterator_EmptyValues) {
237*6777b538SAndroid Build Coastguard Worker std::string values = ", foopy , \t ,,,";
238*6777b538SAndroid Build Coastguard Worker
239*6777b538SAndroid Build Coastguard Worker HttpUtil::ValuesIterator it(values.begin(), values.end(), ',',
240*6777b538SAndroid Build Coastguard Worker true /* ignore_empty_values */);
241*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it.GetNext());
242*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("foopy"), it.value());
243*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
244*6777b538SAndroid Build Coastguard Worker
245*6777b538SAndroid Build Coastguard Worker HttpUtil::ValuesIterator it_with_empty_values(
246*6777b538SAndroid Build Coastguard Worker values.begin(), values.end(), ',', false /* ignore_empty_values */);
247*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
248*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(""), it_with_empty_values.value());
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
251*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("foopy"), it_with_empty_values.value());
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
254*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(""), it_with_empty_values.value());
255*6777b538SAndroid Build Coastguard Worker
256*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
257*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(""), it_with_empty_values.value());
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
260*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(""), it_with_empty_values.value());
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
263*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(""), it_with_empty_values.value());
264*6777b538SAndroid Build Coastguard Worker
265*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it_with_empty_values.GetNext());
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ValuesIterator_Blanks)268*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ValuesIterator_Blanks) {
269*6777b538SAndroid Build Coastguard Worker std::string values = " \t ";
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker HttpUtil::ValuesIterator it(values.begin(), values.end(), ',',
272*6777b538SAndroid Build Coastguard Worker true /* ignore_empty_values */);
273*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it.GetNext());
274*6777b538SAndroid Build Coastguard Worker
275*6777b538SAndroid Build Coastguard Worker HttpUtil::ValuesIterator it_with_empty_values(
276*6777b538SAndroid Build Coastguard Worker values.begin(), values.end(), ',', false /* ignore_empty_values */);
277*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(it_with_empty_values.GetNext());
278*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(""), it_with_empty_values.value());
279*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(it_with_empty_values.GetNext());
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,Unquote)282*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, Unquote) {
283*6777b538SAndroid Build Coastguard Worker // Replace <backslash> " with ".
284*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyz\"abc", HttpUtil::Unquote("\"xyz\\\"abc\"").c_str());
285*6777b538SAndroid Build Coastguard Worker
286*6777b538SAndroid Build Coastguard Worker // Replace <backslash> <backslash> with <backslash>
287*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyz\\abc", HttpUtil::Unquote("\"xyz\\\\abc\"").c_str());
288*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyz\\\\\\abc",
289*6777b538SAndroid Build Coastguard Worker HttpUtil::Unquote("\"xyz\\\\\\\\\\\\abc\"").c_str());
290*6777b538SAndroid Build Coastguard Worker
291*6777b538SAndroid Build Coastguard Worker // Replace <backslash> X with X
292*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyzXabc", HttpUtil::Unquote("\"xyz\\Xabc\"").c_str());
293*6777b538SAndroid Build Coastguard Worker
294*6777b538SAndroid Build Coastguard Worker // Act as identity function on unquoted inputs.
295*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("X", HttpUtil::Unquote("X").c_str());
296*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("\"", HttpUtil::Unquote("\"").c_str());
297*6777b538SAndroid Build Coastguard Worker
298*6777b538SAndroid Build Coastguard Worker // Allow quotes in the middle of the input.
299*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("foo\"bar", HttpUtil::Unquote("\"foo\"bar\"").c_str());
300*6777b538SAndroid Build Coastguard Worker
301*6777b538SAndroid Build Coastguard Worker // Allow the final quote to be escaped.
302*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("foo", HttpUtil::Unquote("\"foo\\\"").c_str());
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,StrictUnquote)305*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, StrictUnquote) {
306*6777b538SAndroid Build Coastguard Worker std::string out;
307*6777b538SAndroid Build Coastguard Worker
308*6777b538SAndroid Build Coastguard Worker // Replace <backslash> " with ".
309*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"xyz\\\"abc\"", &out));
310*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyz\"abc", out.c_str());
311*6777b538SAndroid Build Coastguard Worker
312*6777b538SAndroid Build Coastguard Worker // Replace <backslash> <backslash> with <backslash>.
313*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"xyz\\\\abc\"", &out));
314*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyz\\abc", out.c_str());
315*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"xyz\\\\\\\\\\\\abc\"", &out));
316*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyz\\\\\\abc", out.c_str());
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker // Replace <backslash> X with X.
319*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"xyz\\Xabc\"", &out));
320*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("xyzXabc", out.c_str());
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker // Empty quoted string.
323*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"\"", &out));
324*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("", out.c_str());
325*6777b538SAndroid Build Coastguard Worker
326*6777b538SAndroid Build Coastguard Worker // Return false on unquoted inputs.
327*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("X", &out));
328*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("", &out));
329*6777b538SAndroid Build Coastguard Worker
330*6777b538SAndroid Build Coastguard Worker // Return false on mismatched quotes.
331*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("\"", &out));
332*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("\"xyz", &out));
333*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("\"abc'", &out));
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker // Return false on escaped terminal quote.
336*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("\"abc\\\"", &out));
337*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("\"\\\"", &out));
338*6777b538SAndroid Build Coastguard Worker
339*6777b538SAndroid Build Coastguard Worker // Allow escaped backslash before terminal quote.
340*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"\\\\\"", &out));
341*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("\\", out.c_str());
342*6777b538SAndroid Build Coastguard Worker
343*6777b538SAndroid Build Coastguard Worker // Don't allow single quotes to act as quote marks.
344*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("'x\"'", &out));
345*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::StrictUnquote("\"x'\"", &out));
346*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("x'", out.c_str());
347*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::StrictUnquote("''", &out));
348*6777b538SAndroid Build Coastguard Worker }
349*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,Quote)350*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, Quote) {
351*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("\"xyz\\\"abc\"", HttpUtil::Quote("xyz\"abc").c_str());
352*6777b538SAndroid Build Coastguard Worker
353*6777b538SAndroid Build Coastguard Worker // Replace <backslash> <backslash> with <backslash>
354*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("\"xyz\\\\abc\"", HttpUtil::Quote("xyz\\abc").c_str());
355*6777b538SAndroid Build Coastguard Worker
356*6777b538SAndroid Build Coastguard Worker // Replace <backslash> X with X
357*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("\"xyzXabc\"", HttpUtil::Quote("xyzXabc").c_str());
358*6777b538SAndroid Build Coastguard Worker }
359*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,LocateEndOfHeaders)360*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, LocateEndOfHeaders) {
361*6777b538SAndroid Build Coastguard Worker struct {
362*6777b538SAndroid Build Coastguard Worker const char* const input;
363*6777b538SAndroid Build Coastguard Worker size_t expected_result;
364*6777b538SAndroid Build Coastguard Worker } tests[] = {
365*6777b538SAndroid Build Coastguard Worker {"\r\n", std::string::npos},
366*6777b538SAndroid Build Coastguard Worker {"\n", std::string::npos},
367*6777b538SAndroid Build Coastguard Worker {"\r", std::string::npos},
368*6777b538SAndroid Build Coastguard Worker {"foo", std::string::npos},
369*6777b538SAndroid Build Coastguard Worker {"\r\n\r\n", 4},
370*6777b538SAndroid Build Coastguard Worker {"foo\r\nbar\r\n\r\n", 12},
371*6777b538SAndroid Build Coastguard Worker {"foo\nbar\n\n", 9},
372*6777b538SAndroid Build Coastguard Worker {"foo\r\nbar\r\n\r\njunk", 12},
373*6777b538SAndroid Build Coastguard Worker {"foo\nbar\n\njunk", 9},
374*6777b538SAndroid Build Coastguard Worker {"foo\nbar\n\r\njunk", 10},
375*6777b538SAndroid Build Coastguard Worker {"foo\nbar\r\n\njunk", 10},
376*6777b538SAndroid Build Coastguard Worker };
377*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
378*6777b538SAndroid Build Coastguard Worker size_t input_len = strlen(test.input);
379*6777b538SAndroid Build Coastguard Worker size_t eoh = HttpUtil::LocateEndOfHeaders(test.input, input_len);
380*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_result, eoh);
381*6777b538SAndroid Build Coastguard Worker }
382*6777b538SAndroid Build Coastguard Worker }
383*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,LocateEndOfAdditionalHeaders)384*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, LocateEndOfAdditionalHeaders) {
385*6777b538SAndroid Build Coastguard Worker struct {
386*6777b538SAndroid Build Coastguard Worker const char* const input;
387*6777b538SAndroid Build Coastguard Worker size_t expected_result;
388*6777b538SAndroid Build Coastguard Worker } tests[] = {
389*6777b538SAndroid Build Coastguard Worker {"\r\n", 2},
390*6777b538SAndroid Build Coastguard Worker {"\n", 1},
391*6777b538SAndroid Build Coastguard Worker {"\r", std::string::npos},
392*6777b538SAndroid Build Coastguard Worker {"foo", std::string::npos},
393*6777b538SAndroid Build Coastguard Worker {"\r\n\r\n", 2},
394*6777b538SAndroid Build Coastguard Worker {"foo\r\nbar\r\n\r\n", 12},
395*6777b538SAndroid Build Coastguard Worker {"foo\nbar\n\n", 9},
396*6777b538SAndroid Build Coastguard Worker {"foo\r\nbar\r\n\r\njunk", 12},
397*6777b538SAndroid Build Coastguard Worker {"foo\nbar\n\njunk", 9},
398*6777b538SAndroid Build Coastguard Worker {"foo\nbar\n\r\njunk", 10},
399*6777b538SAndroid Build Coastguard Worker {"foo\nbar\r\n\njunk", 10},
400*6777b538SAndroid Build Coastguard Worker };
401*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
402*6777b538SAndroid Build Coastguard Worker size_t input_len = strlen(test.input);
403*6777b538SAndroid Build Coastguard Worker size_t eoh = HttpUtil::LocateEndOfAdditionalHeaders(test.input, input_len);
404*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_result, eoh);
405*6777b538SAndroid Build Coastguard Worker }
406*6777b538SAndroid Build Coastguard Worker }
TEST(HttpUtilTest,AssembleRawHeaders)407*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, AssembleRawHeaders) {
408*6777b538SAndroid Build Coastguard Worker // clang-format off
409*6777b538SAndroid Build Coastguard Worker struct {
410*6777b538SAndroid Build Coastguard Worker const char* const input; // with '|' representing '\0'
411*6777b538SAndroid Build Coastguard Worker const char* const expected_result; // with '\0' changed to '|'
412*6777b538SAndroid Build Coastguard Worker } tests[] = {
413*6777b538SAndroid Build Coastguard Worker { "HTTP/1.0 200 OK\r\nFoo: 1\r\nBar: 2\r\n\r\n",
414*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|Foo: 1|Bar: 2||" },
415*6777b538SAndroid Build Coastguard Worker
416*6777b538SAndroid Build Coastguard Worker { "HTTP/1.0 200 OK\nFoo: 1\nBar: 2\n\n",
417*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|Foo: 1|Bar: 2||" },
418*6777b538SAndroid Build Coastguard Worker
419*6777b538SAndroid Build Coastguard Worker // Valid line continuation (single SP).
420*6777b538SAndroid Build Coastguard Worker {
421*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
422*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
423*6777b538SAndroid Build Coastguard Worker " continuation\n"
424*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
425*6777b538SAndroid Build Coastguard Worker
426*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
427*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation|"
428*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
429*6777b538SAndroid Build Coastguard Worker },
430*6777b538SAndroid Build Coastguard Worker
431*6777b538SAndroid Build Coastguard Worker // Valid line continuation (single HT).
432*6777b538SAndroid Build Coastguard Worker {
433*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
434*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
435*6777b538SAndroid Build Coastguard Worker "\tcontinuation\n"
436*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
437*6777b538SAndroid Build Coastguard Worker
438*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
439*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation|"
440*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
441*6777b538SAndroid Build Coastguard Worker },
442*6777b538SAndroid Build Coastguard Worker
443*6777b538SAndroid Build Coastguard Worker // Valid line continuation (multiple SP).
444*6777b538SAndroid Build Coastguard Worker {
445*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
446*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
447*6777b538SAndroid Build Coastguard Worker " continuation\n"
448*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
449*6777b538SAndroid Build Coastguard Worker
450*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
451*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation|"
452*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
453*6777b538SAndroid Build Coastguard Worker },
454*6777b538SAndroid Build Coastguard Worker
455*6777b538SAndroid Build Coastguard Worker // Valid line continuation (multiple HT).
456*6777b538SAndroid Build Coastguard Worker {
457*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
458*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
459*6777b538SAndroid Build Coastguard Worker "\t\t\tcontinuation\n"
460*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
461*6777b538SAndroid Build Coastguard Worker
462*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
463*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation|"
464*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
465*6777b538SAndroid Build Coastguard Worker },
466*6777b538SAndroid Build Coastguard Worker
467*6777b538SAndroid Build Coastguard Worker // Valid line continuation (mixed HT, SP).
468*6777b538SAndroid Build Coastguard Worker {
469*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
470*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
471*6777b538SAndroid Build Coastguard Worker " \t \t continuation\n"
472*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
473*6777b538SAndroid Build Coastguard Worker
474*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
475*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation|"
476*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
477*6777b538SAndroid Build Coastguard Worker },
478*6777b538SAndroid Build Coastguard Worker
479*6777b538SAndroid Build Coastguard Worker // Valid multi-line continuation
480*6777b538SAndroid Build Coastguard Worker {
481*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
482*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
483*6777b538SAndroid Build Coastguard Worker " continuation1\n"
484*6777b538SAndroid Build Coastguard Worker "\tcontinuation2\n"
485*6777b538SAndroid Build Coastguard Worker " continuation3\n"
486*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
487*6777b538SAndroid Build Coastguard Worker
488*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
489*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation1 continuation2 continuation3|"
490*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
491*6777b538SAndroid Build Coastguard Worker },
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard Worker // Continuation of quoted value.
494*6777b538SAndroid Build Coastguard Worker // This is different from what Firefox does, since it
495*6777b538SAndroid Build Coastguard Worker // will preserve the LWS.
496*6777b538SAndroid Build Coastguard Worker {
497*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
498*6777b538SAndroid Build Coastguard Worker "Etag: \"34534-d3\n"
499*6777b538SAndroid Build Coastguard Worker " 134q\"\n"
500*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
501*6777b538SAndroid Build Coastguard Worker
502*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
503*6777b538SAndroid Build Coastguard Worker "Etag: \"34534-d3 134q\"|"
504*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
505*6777b538SAndroid Build Coastguard Worker },
506*6777b538SAndroid Build Coastguard Worker
507*6777b538SAndroid Build Coastguard Worker // Valid multi-line continuation, full LWS lines
508*6777b538SAndroid Build Coastguard Worker {
509*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
510*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
511*6777b538SAndroid Build Coastguard Worker " \n"
512*6777b538SAndroid Build Coastguard Worker "\t\t\t\t\n"
513*6777b538SAndroid Build Coastguard Worker "\t continuation\n"
514*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
515*6777b538SAndroid Build Coastguard Worker
516*6777b538SAndroid Build Coastguard Worker // One SP per continued line = 3.
517*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
518*6777b538SAndroid Build Coastguard Worker "Foo: 1 continuation|"
519*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
520*6777b538SAndroid Build Coastguard Worker },
521*6777b538SAndroid Build Coastguard Worker
522*6777b538SAndroid Build Coastguard Worker // Valid multi-line continuation, all LWS
523*6777b538SAndroid Build Coastguard Worker {
524*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
525*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
526*6777b538SAndroid Build Coastguard Worker " \n"
527*6777b538SAndroid Build Coastguard Worker "\t\t\t\t\n"
528*6777b538SAndroid Build Coastguard Worker "\t \n"
529*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
530*6777b538SAndroid Build Coastguard Worker
531*6777b538SAndroid Build Coastguard Worker // One SP per continued line = 3.
532*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
533*6777b538SAndroid Build Coastguard Worker "Foo: 1 |"
534*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
535*6777b538SAndroid Build Coastguard Worker },
536*6777b538SAndroid Build Coastguard Worker
537*6777b538SAndroid Build Coastguard Worker // Valid line continuation (No value bytes in first line).
538*6777b538SAndroid Build Coastguard Worker {
539*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
540*6777b538SAndroid Build Coastguard Worker "Foo:\n"
541*6777b538SAndroid Build Coastguard Worker " value\n"
542*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
543*6777b538SAndroid Build Coastguard Worker
544*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
545*6777b538SAndroid Build Coastguard Worker "Foo: value|"
546*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
547*6777b538SAndroid Build Coastguard Worker },
548*6777b538SAndroid Build Coastguard Worker
549*6777b538SAndroid Build Coastguard Worker // Not a line continuation (can't continue status line).
550*6777b538SAndroid Build Coastguard Worker {
551*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
552*6777b538SAndroid Build Coastguard Worker " Foo: 1\n"
553*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
554*6777b538SAndroid Build Coastguard Worker
555*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
556*6777b538SAndroid Build Coastguard Worker " Foo: 1|"
557*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
558*6777b538SAndroid Build Coastguard Worker },
559*6777b538SAndroid Build Coastguard Worker
560*6777b538SAndroid Build Coastguard Worker // Not a line continuation (can't continue status line).
561*6777b538SAndroid Build Coastguard Worker {
562*6777b538SAndroid Build Coastguard Worker "HTTP/1.0\n"
563*6777b538SAndroid Build Coastguard Worker " 200 OK\n"
564*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
565*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
566*6777b538SAndroid Build Coastguard Worker
567*6777b538SAndroid Build Coastguard Worker "HTTP/1.0|"
568*6777b538SAndroid Build Coastguard Worker " 200 OK|"
569*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
570*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
571*6777b538SAndroid Build Coastguard Worker },
572*6777b538SAndroid Build Coastguard Worker
573*6777b538SAndroid Build Coastguard Worker // Not a line continuation (can't continue status line).
574*6777b538SAndroid Build Coastguard Worker {
575*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 404\n"
576*6777b538SAndroid Build Coastguard Worker " Not Found\n"
577*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
578*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
579*6777b538SAndroid Build Coastguard Worker
580*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 404|"
581*6777b538SAndroid Build Coastguard Worker " Not Found|"
582*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
583*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
584*6777b538SAndroid Build Coastguard Worker },
585*6777b538SAndroid Build Coastguard Worker
586*6777b538SAndroid Build Coastguard Worker // Unterminated status line.
587*6777b538SAndroid Build Coastguard Worker {
588*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK",
589*6777b538SAndroid Build Coastguard Worker
590*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK||"
591*6777b538SAndroid Build Coastguard Worker },
592*6777b538SAndroid Build Coastguard Worker
593*6777b538SAndroid Build Coastguard Worker // Single terminated, with headers
594*6777b538SAndroid Build Coastguard Worker {
595*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
596*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
597*6777b538SAndroid Build Coastguard Worker "Bar: 2\n",
598*6777b538SAndroid Build Coastguard Worker
599*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
600*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
601*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
602*6777b538SAndroid Build Coastguard Worker },
603*6777b538SAndroid Build Coastguard Worker
604*6777b538SAndroid Build Coastguard Worker // Not terminated, with headers
605*6777b538SAndroid Build Coastguard Worker {
606*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
607*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
608*6777b538SAndroid Build Coastguard Worker "Bar: 2",
609*6777b538SAndroid Build Coastguard Worker
610*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
611*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
612*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
613*6777b538SAndroid Build Coastguard Worker },
614*6777b538SAndroid Build Coastguard Worker
615*6777b538SAndroid Build Coastguard Worker // Not a line continuation (VT)
616*6777b538SAndroid Build Coastguard Worker {
617*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
618*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
619*6777b538SAndroid Build Coastguard Worker "\vInvalidContinuation\n"
620*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
621*6777b538SAndroid Build Coastguard Worker
622*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
623*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
624*6777b538SAndroid Build Coastguard Worker "\vInvalidContinuation|"
625*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
626*6777b538SAndroid Build Coastguard Worker },
627*6777b538SAndroid Build Coastguard Worker
628*6777b538SAndroid Build Coastguard Worker // Not a line continuation (formfeed)
629*6777b538SAndroid Build Coastguard Worker {
630*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
631*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
632*6777b538SAndroid Build Coastguard Worker "\fInvalidContinuation\n"
633*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
634*6777b538SAndroid Build Coastguard Worker
635*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
636*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
637*6777b538SAndroid Build Coastguard Worker "\fInvalidContinuation|"
638*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
639*6777b538SAndroid Build Coastguard Worker },
640*6777b538SAndroid Build Coastguard Worker
641*6777b538SAndroid Build Coastguard Worker // Not a line continuation -- can't continue header names.
642*6777b538SAndroid Build Coastguard Worker {
643*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
644*6777b538SAndroid Build Coastguard Worker "Serv\n"
645*6777b538SAndroid Build Coastguard Worker " er: Apache\n"
646*6777b538SAndroid Build Coastguard Worker "\tInvalidContinuation\n"
647*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
648*6777b538SAndroid Build Coastguard Worker
649*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
650*6777b538SAndroid Build Coastguard Worker "Serv|"
651*6777b538SAndroid Build Coastguard Worker " er: Apache|"
652*6777b538SAndroid Build Coastguard Worker "\tInvalidContinuation|"
653*6777b538SAndroid Build Coastguard Worker "Bar: 2||"
654*6777b538SAndroid Build Coastguard Worker },
655*6777b538SAndroid Build Coastguard Worker
656*6777b538SAndroid Build Coastguard Worker // Not a line continuation -- no value to continue.
657*6777b538SAndroid Build Coastguard Worker {
658*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
659*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
660*6777b538SAndroid Build Coastguard Worker "garbage\n"
661*6777b538SAndroid Build Coastguard Worker " not-a-continuation\n"
662*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
663*6777b538SAndroid Build Coastguard Worker
664*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
665*6777b538SAndroid Build Coastguard Worker "Foo: 1|"
666*6777b538SAndroid Build Coastguard Worker "garbage|"
667*6777b538SAndroid Build Coastguard Worker " not-a-continuation|"
668*6777b538SAndroid Build Coastguard Worker "Bar: 2||",
669*6777b538SAndroid Build Coastguard Worker },
670*6777b538SAndroid Build Coastguard Worker
671*6777b538SAndroid Build Coastguard Worker // Not a line continuation -- no valid name.
672*6777b538SAndroid Build Coastguard Worker {
673*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
674*6777b538SAndroid Build Coastguard Worker ": 1\n"
675*6777b538SAndroid Build Coastguard Worker " garbage\n"
676*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
677*6777b538SAndroid Build Coastguard Worker
678*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
679*6777b538SAndroid Build Coastguard Worker ": 1|"
680*6777b538SAndroid Build Coastguard Worker " garbage|"
681*6777b538SAndroid Build Coastguard Worker "Bar: 2||",
682*6777b538SAndroid Build Coastguard Worker },
683*6777b538SAndroid Build Coastguard Worker
684*6777b538SAndroid Build Coastguard Worker // Not a line continuation -- no valid name (whitespace)
685*6777b538SAndroid Build Coastguard Worker {
686*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
687*6777b538SAndroid Build Coastguard Worker " : 1\n"
688*6777b538SAndroid Build Coastguard Worker " garbage\n"
689*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
690*6777b538SAndroid Build Coastguard Worker
691*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|"
692*6777b538SAndroid Build Coastguard Worker " : 1|"
693*6777b538SAndroid Build Coastguard Worker " garbage|"
694*6777b538SAndroid Build Coastguard Worker "Bar: 2||",
695*6777b538SAndroid Build Coastguard Worker },
696*6777b538SAndroid Build Coastguard Worker
697*6777b538SAndroid Build Coastguard Worker // Embed NULLs in the status line. They should not be understood
698*6777b538SAndroid Build Coastguard Worker // as line separators.
699*6777b538SAndroid Build Coastguard Worker {
700*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|Bar2:0|Baz2:1\r\nFoo: 1\r\nBar: 2\r\n\r\n",
701*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OKBar2:0Baz2:1|Foo: 1|Bar: 2||"
702*6777b538SAndroid Build Coastguard Worker },
703*6777b538SAndroid Build Coastguard Worker
704*6777b538SAndroid Build Coastguard Worker // Embed NULLs in a header line. They should not be understood as
705*6777b538SAndroid Build Coastguard Worker // line separators.
706*6777b538SAndroid Build Coastguard Worker {
707*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\nFoo: 1|Foo2: 3\nBar: 2\n\n",
708*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|Foo: 1Foo2: 3|Bar: 2||"
709*6777b538SAndroid Build Coastguard Worker },
710*6777b538SAndroid Build Coastguard Worker
711*6777b538SAndroid Build Coastguard Worker // The embedded NUL at the start of the line (before "Blah:") should not be
712*6777b538SAndroid Build Coastguard Worker // interpreted as LWS (as that would mistake it for a header line
713*6777b538SAndroid Build Coastguard Worker // continuation).
714*6777b538SAndroid Build Coastguard Worker {
715*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK\n"
716*6777b538SAndroid Build Coastguard Worker "Foo: 1\n"
717*6777b538SAndroid Build Coastguard Worker "|Blah: 3\n"
718*6777b538SAndroid Build Coastguard Worker "Bar: 2\n\n",
719*6777b538SAndroid Build Coastguard Worker "HTTP/1.0 200 OK|Foo: 1|Blah: 3|Bar: 2||"
720*6777b538SAndroid Build Coastguard Worker },
721*6777b538SAndroid Build Coastguard Worker };
722*6777b538SAndroid Build Coastguard Worker // clang-format on
723*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
724*6777b538SAndroid Build Coastguard Worker std::string input = test.input;
725*6777b538SAndroid Build Coastguard Worker std::replace(input.begin(), input.end(), '|', '\0');
726*6777b538SAndroid Build Coastguard Worker std::string raw = HttpUtil::AssembleRawHeaders(input);
727*6777b538SAndroid Build Coastguard Worker std::replace(raw.begin(), raw.end(), '\0', '|');
728*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_result, raw);
729*6777b538SAndroid Build Coastguard Worker }
730*6777b538SAndroid Build Coastguard Worker }
731*6777b538SAndroid Build Coastguard Worker
732*6777b538SAndroid Build Coastguard Worker // Test SpecForRequest().
TEST(HttpUtilTest,RequestUrlSanitize)733*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, RequestUrlSanitize) {
734*6777b538SAndroid Build Coastguard Worker struct {
735*6777b538SAndroid Build Coastguard Worker const char* const url;
736*6777b538SAndroid Build Coastguard Worker const char* const expected_spec;
737*6777b538SAndroid Build Coastguard Worker } tests[] = {
738*6777b538SAndroid Build Coastguard Worker { // Check that #hash is removed.
739*6777b538SAndroid Build Coastguard Worker "http://www.google.com:78/foobar?query=1#hash",
740*6777b538SAndroid Build Coastguard Worker "http://www.google.com:78/foobar?query=1",
741*6777b538SAndroid Build Coastguard Worker },
742*6777b538SAndroid Build Coastguard Worker { // The reference may itself contain # -- strip all of it.
743*6777b538SAndroid Build Coastguard Worker "http://192.168.0.1?query=1#hash#10#11#13#14",
744*6777b538SAndroid Build Coastguard Worker "http://192.168.0.1/?query=1",
745*6777b538SAndroid Build Coastguard Worker },
746*6777b538SAndroid Build Coastguard Worker { // Strip username/password.
747*6777b538SAndroid Build Coastguard Worker "http://user:[email protected]",
748*6777b538SAndroid Build Coastguard Worker "http://google.com/",
749*6777b538SAndroid Build Coastguard Worker },
750*6777b538SAndroid Build Coastguard Worker { // https scheme
751*6777b538SAndroid Build Coastguard Worker "https://www.google.com:78/foobar?query=1#hash",
752*6777b538SAndroid Build Coastguard Worker "https://www.google.com:78/foobar?query=1",
753*6777b538SAndroid Build Coastguard Worker },
754*6777b538SAndroid Build Coastguard Worker { // WebSocket's ws scheme
755*6777b538SAndroid Build Coastguard Worker "ws://www.google.com:78/foobar?query=1#hash",
756*6777b538SAndroid Build Coastguard Worker "ws://www.google.com:78/foobar?query=1",
757*6777b538SAndroid Build Coastguard Worker },
758*6777b538SAndroid Build Coastguard Worker { // WebSocket's wss scheme
759*6777b538SAndroid Build Coastguard Worker "wss://www.google.com:78/foobar?query=1#hash",
760*6777b538SAndroid Build Coastguard Worker "wss://www.google.com:78/foobar?query=1",
761*6777b538SAndroid Build Coastguard Worker }
762*6777b538SAndroid Build Coastguard Worker };
763*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(tests); ++i) {
764*6777b538SAndroid Build Coastguard Worker SCOPED_TRACE(i);
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker GURL url(GURL(tests[i].url));
767*6777b538SAndroid Build Coastguard Worker std::string expected_spec(tests[i].expected_spec);
768*6777b538SAndroid Build Coastguard Worker
769*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(expected_spec, HttpUtil::SpecForRequest(url));
770*6777b538SAndroid Build Coastguard Worker }
771*6777b538SAndroid Build Coastguard Worker }
772*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,GenerateAcceptLanguageHeader)773*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, GenerateAcceptLanguageHeader) {
774*6777b538SAndroid Build Coastguard Worker std::string header = HttpUtil::GenerateAcceptLanguageHeader("");
775*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(header.empty());
776*6777b538SAndroid Build Coastguard Worker
777*6777b538SAndroid Build Coastguard Worker header = HttpUtil::GenerateAcceptLanguageHeader("es");
778*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("es"), header);
779*6777b538SAndroid Build Coastguard Worker
780*6777b538SAndroid Build Coastguard Worker header = HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de");
781*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string("en-US,fr;q=0.9,de;q=0.8"), header);
782*6777b538SAndroid Build Coastguard Worker
783*6777b538SAndroid Build Coastguard Worker header = HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de,ko,zh-CN,ja");
784*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
785*6777b538SAndroid Build Coastguard Worker std::string("en-US,fr;q=0.9,de;q=0.8,ko;q=0.7,zh-CN;q=0.6,ja;q=0.5"),
786*6777b538SAndroid Build Coastguard Worker header);
787*6777b538SAndroid Build Coastguard Worker }
788*6777b538SAndroid Build Coastguard Worker
789*6777b538SAndroid Build Coastguard Worker // HttpResponseHeadersTest.GetMimeType also tests ParseContentType.
TEST(HttpUtilTest,ParseContentType)790*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ParseContentType) {
791*6777b538SAndroid Build Coastguard Worker // clang-format off
792*6777b538SAndroid Build Coastguard Worker const struct {
793*6777b538SAndroid Build Coastguard Worker const char* const content_type;
794*6777b538SAndroid Build Coastguard Worker const char* const expected_mime_type;
795*6777b538SAndroid Build Coastguard Worker const char* const expected_charset;
796*6777b538SAndroid Build Coastguard Worker const bool expected_had_charset;
797*6777b538SAndroid Build Coastguard Worker const char* const expected_boundary;
798*6777b538SAndroid Build Coastguard Worker } tests[] = {
799*6777b538SAndroid Build Coastguard Worker { "text/html",
800*6777b538SAndroid Build Coastguard Worker "text/html",
801*6777b538SAndroid Build Coastguard Worker "",
802*6777b538SAndroid Build Coastguard Worker false,
803*6777b538SAndroid Build Coastguard Worker ""
804*6777b538SAndroid Build Coastguard Worker },
805*6777b538SAndroid Build Coastguard Worker { "text/html;",
806*6777b538SAndroid Build Coastguard Worker "text/html",
807*6777b538SAndroid Build Coastguard Worker "",
808*6777b538SAndroid Build Coastguard Worker false,
809*6777b538SAndroid Build Coastguard Worker ""
810*6777b538SAndroid Build Coastguard Worker },
811*6777b538SAndroid Build Coastguard Worker { "text/html; charset=utf-8",
812*6777b538SAndroid Build Coastguard Worker "text/html",
813*6777b538SAndroid Build Coastguard Worker "utf-8",
814*6777b538SAndroid Build Coastguard Worker true,
815*6777b538SAndroid Build Coastguard Worker ""
816*6777b538SAndroid Build Coastguard Worker },
817*6777b538SAndroid Build Coastguard Worker // Parameter name is "charset ", not "charset". See https://crbug.com/772834.
818*6777b538SAndroid Build Coastguard Worker { "text/html; charset =utf-8",
819*6777b538SAndroid Build Coastguard Worker "text/html",
820*6777b538SAndroid Build Coastguard Worker "",
821*6777b538SAndroid Build Coastguard Worker false,
822*6777b538SAndroid Build Coastguard Worker ""
823*6777b538SAndroid Build Coastguard Worker },
824*6777b538SAndroid Build Coastguard Worker { "text/html; charset= utf-8",
825*6777b538SAndroid Build Coastguard Worker "text/html",
826*6777b538SAndroid Build Coastguard Worker "utf-8",
827*6777b538SAndroid Build Coastguard Worker true,
828*6777b538SAndroid Build Coastguard Worker ""
829*6777b538SAndroid Build Coastguard Worker },
830*6777b538SAndroid Build Coastguard Worker { "text/html; charset=utf-8 ",
831*6777b538SAndroid Build Coastguard Worker "text/html",
832*6777b538SAndroid Build Coastguard Worker "utf-8",
833*6777b538SAndroid Build Coastguard Worker true,
834*6777b538SAndroid Build Coastguard Worker ""
835*6777b538SAndroid Build Coastguard Worker },
836*6777b538SAndroid Build Coastguard Worker
837*6777b538SAndroid Build Coastguard Worker { "text/html; boundary=\"WebKit-ada-df-dsf-adsfadsfs\"",
838*6777b538SAndroid Build Coastguard Worker "text/html",
839*6777b538SAndroid Build Coastguard Worker "",
840*6777b538SAndroid Build Coastguard Worker false,
841*6777b538SAndroid Build Coastguard Worker "WebKit-ada-df-dsf-adsfadsfs"
842*6777b538SAndroid Build Coastguard Worker },
843*6777b538SAndroid Build Coastguard Worker // Parameter name is "boundary ", not "boundary".
844*6777b538SAndroid Build Coastguard Worker // See https://crbug.com/772834.
845*6777b538SAndroid Build Coastguard Worker { "text/html; boundary =\"WebKit-ada-df-dsf-adsfadsfs\"",
846*6777b538SAndroid Build Coastguard Worker "text/html",
847*6777b538SAndroid Build Coastguard Worker "",
848*6777b538SAndroid Build Coastguard Worker false,
849*6777b538SAndroid Build Coastguard Worker ""
850*6777b538SAndroid Build Coastguard Worker },
851*6777b538SAndroid Build Coastguard Worker // Parameter value includes leading space. See https://crbug.com/772834.
852*6777b538SAndroid Build Coastguard Worker { "text/html; boundary= \"WebKit-ada-df-dsf-adsfadsfs\"",
853*6777b538SAndroid Build Coastguard Worker "text/html",
854*6777b538SAndroid Build Coastguard Worker "",
855*6777b538SAndroid Build Coastguard Worker false,
856*6777b538SAndroid Build Coastguard Worker "WebKit-ada-df-dsf-adsfadsfs"
857*6777b538SAndroid Build Coastguard Worker },
858*6777b538SAndroid Build Coastguard Worker // Parameter value includes leading space. See https://crbug.com/772834.
859*6777b538SAndroid Build Coastguard Worker { "text/html; boundary= \"WebKit-ada-df-dsf-adsfadsfs\" ",
860*6777b538SAndroid Build Coastguard Worker "text/html",
861*6777b538SAndroid Build Coastguard Worker "",
862*6777b538SAndroid Build Coastguard Worker false,
863*6777b538SAndroid Build Coastguard Worker "WebKit-ada-df-dsf-adsfadsfs"
864*6777b538SAndroid Build Coastguard Worker },
865*6777b538SAndroid Build Coastguard Worker { "text/html; boundary=\"WebKit-ada-df-dsf-adsfadsfs \"",
866*6777b538SAndroid Build Coastguard Worker "text/html",
867*6777b538SAndroid Build Coastguard Worker "",
868*6777b538SAndroid Build Coastguard Worker false,
869*6777b538SAndroid Build Coastguard Worker "WebKit-ada-df-dsf-adsfadsfs"
870*6777b538SAndroid Build Coastguard Worker },
871*6777b538SAndroid Build Coastguard Worker { "text/html; boundary=WebKit-ada-df-dsf-adsfadsfs",
872*6777b538SAndroid Build Coastguard Worker "text/html",
873*6777b538SAndroid Build Coastguard Worker "",
874*6777b538SAndroid Build Coastguard Worker false,
875*6777b538SAndroid Build Coastguard Worker "WebKit-ada-df-dsf-adsfadsfs"
876*6777b538SAndroid Build Coastguard Worker },
877*6777b538SAndroid Build Coastguard Worker { "text/html; charset",
878*6777b538SAndroid Build Coastguard Worker "text/html",
879*6777b538SAndroid Build Coastguard Worker "",
880*6777b538SAndroid Build Coastguard Worker false,
881*6777b538SAndroid Build Coastguard Worker ""
882*6777b538SAndroid Build Coastguard Worker },
883*6777b538SAndroid Build Coastguard Worker { "text/html; charset=",
884*6777b538SAndroid Build Coastguard Worker "text/html",
885*6777b538SAndroid Build Coastguard Worker "",
886*6777b538SAndroid Build Coastguard Worker false,
887*6777b538SAndroid Build Coastguard Worker ""
888*6777b538SAndroid Build Coastguard Worker },
889*6777b538SAndroid Build Coastguard Worker { "text/html; charset= ",
890*6777b538SAndroid Build Coastguard Worker "text/html",
891*6777b538SAndroid Build Coastguard Worker "",
892*6777b538SAndroid Build Coastguard Worker false,
893*6777b538SAndroid Build Coastguard Worker ""
894*6777b538SAndroid Build Coastguard Worker },
895*6777b538SAndroid Build Coastguard Worker { "text/html; charset= ;",
896*6777b538SAndroid Build Coastguard Worker "text/html",
897*6777b538SAndroid Build Coastguard Worker "",
898*6777b538SAndroid Build Coastguard Worker false,
899*6777b538SAndroid Build Coastguard Worker ""
900*6777b538SAndroid Build Coastguard Worker },
901*6777b538SAndroid Build Coastguard Worker // Empty quoted strings are allowed.
902*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\"\"",
903*6777b538SAndroid Build Coastguard Worker "text/html",
904*6777b538SAndroid Build Coastguard Worker "",
905*6777b538SAndroid Build Coastguard Worker true,
906*6777b538SAndroid Build Coastguard Worker ""
907*6777b538SAndroid Build Coastguard Worker },
908*6777b538SAndroid Build Coastguard Worker
909*6777b538SAndroid Build Coastguard Worker // Leading and trailing whitespace in quotes is trimmed.
910*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\" \"",
911*6777b538SAndroid Build Coastguard Worker "text/html",
912*6777b538SAndroid Build Coastguard Worker "",
913*6777b538SAndroid Build Coastguard Worker true,
914*6777b538SAndroid Build Coastguard Worker ""
915*6777b538SAndroid Build Coastguard Worker },
916*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\" foo \"",
917*6777b538SAndroid Build Coastguard Worker "text/html",
918*6777b538SAndroid Build Coastguard Worker "foo",
919*6777b538SAndroid Build Coastguard Worker true,
920*6777b538SAndroid Build Coastguard Worker ""
921*6777b538SAndroid Build Coastguard Worker },
922*6777b538SAndroid Build Coastguard Worker
923*6777b538SAndroid Build Coastguard Worker // With multiple values, should use the first one.
924*6777b538SAndroid Build Coastguard Worker { "text/html; charset=foo; charset=utf-8",
925*6777b538SAndroid Build Coastguard Worker "text/html",
926*6777b538SAndroid Build Coastguard Worker "foo",
927*6777b538SAndroid Build Coastguard Worker true,
928*6777b538SAndroid Build Coastguard Worker ""
929*6777b538SAndroid Build Coastguard Worker },
930*6777b538SAndroid Build Coastguard Worker { "text/html; charset; charset=; charset=utf-8",
931*6777b538SAndroid Build Coastguard Worker "text/html",
932*6777b538SAndroid Build Coastguard Worker "utf-8",
933*6777b538SAndroid Build Coastguard Worker true,
934*6777b538SAndroid Build Coastguard Worker ""
935*6777b538SAndroid Build Coastguard Worker },
936*6777b538SAndroid Build Coastguard Worker { "text/html; charset=utf-8; charset=; charset",
937*6777b538SAndroid Build Coastguard Worker "text/html",
938*6777b538SAndroid Build Coastguard Worker "utf-8",
939*6777b538SAndroid Build Coastguard Worker true,
940*6777b538SAndroid Build Coastguard Worker ""
941*6777b538SAndroid Build Coastguard Worker },
942*6777b538SAndroid Build Coastguard Worker { "text/html; boundary=foo; boundary=bar",
943*6777b538SAndroid Build Coastguard Worker "text/html",
944*6777b538SAndroid Build Coastguard Worker "",
945*6777b538SAndroid Build Coastguard Worker false,
946*6777b538SAndroid Build Coastguard Worker "foo"
947*6777b538SAndroid Build Coastguard Worker },
948*6777b538SAndroid Build Coastguard Worker
949*6777b538SAndroid Build Coastguard Worker // Stray quotes ignored.
950*6777b538SAndroid Build Coastguard Worker { "text/html; \"; \"\"; charset=utf-8",
951*6777b538SAndroid Build Coastguard Worker "text/html",
952*6777b538SAndroid Build Coastguard Worker "utf-8",
953*6777b538SAndroid Build Coastguard Worker true,
954*6777b538SAndroid Build Coastguard Worker ""
955*6777b538SAndroid Build Coastguard Worker },
956*6777b538SAndroid Build Coastguard Worker // Non-leading quotes kept as-is.
957*6777b538SAndroid Build Coastguard Worker { "text/html; charset=u\"tf-8\"",
958*6777b538SAndroid Build Coastguard Worker "text/html",
959*6777b538SAndroid Build Coastguard Worker "u\"tf-8\"",
960*6777b538SAndroid Build Coastguard Worker true,
961*6777b538SAndroid Build Coastguard Worker ""
962*6777b538SAndroid Build Coastguard Worker },
963*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\"utf-8\"",
964*6777b538SAndroid Build Coastguard Worker "text/html",
965*6777b538SAndroid Build Coastguard Worker "utf-8",
966*6777b538SAndroid Build Coastguard Worker true,
967*6777b538SAndroid Build Coastguard Worker ""
968*6777b538SAndroid Build Coastguard Worker },
969*6777b538SAndroid Build Coastguard Worker // No closing quote.
970*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\"utf-8",
971*6777b538SAndroid Build Coastguard Worker "text/html",
972*6777b538SAndroid Build Coastguard Worker "utf-8",
973*6777b538SAndroid Build Coastguard Worker true,
974*6777b538SAndroid Build Coastguard Worker ""
975*6777b538SAndroid Build Coastguard Worker },
976*6777b538SAndroid Build Coastguard Worker // Check that \ is treated as an escape character.
977*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\"\\utf\\-\\8\"",
978*6777b538SAndroid Build Coastguard Worker "text/html",
979*6777b538SAndroid Build Coastguard Worker "utf-8",
980*6777b538SAndroid Build Coastguard Worker true,
981*6777b538SAndroid Build Coastguard Worker ""
982*6777b538SAndroid Build Coastguard Worker },
983*6777b538SAndroid Build Coastguard Worker // More interseting escape character test - test escaped backslash, escaped
984*6777b538SAndroid Build Coastguard Worker // quote, and backslash at end of input in unterminated quoted string.
985*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\"\\\\\\\"\\",
986*6777b538SAndroid Build Coastguard Worker "text/html",
987*6777b538SAndroid Build Coastguard Worker "\\\"\\",
988*6777b538SAndroid Build Coastguard Worker true,
989*6777b538SAndroid Build Coastguard Worker ""
990*6777b538SAndroid Build Coastguard Worker },
991*6777b538SAndroid Build Coastguard Worker // Check quoted semicolon.
992*6777b538SAndroid Build Coastguard Worker { "text/html; charset=\";charset=utf-8;\"",
993*6777b538SAndroid Build Coastguard Worker "text/html",
994*6777b538SAndroid Build Coastguard Worker ";charset=utf-8;",
995*6777b538SAndroid Build Coastguard Worker true,
996*6777b538SAndroid Build Coastguard Worker ""
997*6777b538SAndroid Build Coastguard Worker },
998*6777b538SAndroid Build Coastguard Worker // Unclear if this one should just return utf-8 or not.
999*6777b538SAndroid Build Coastguard Worker { "text/html; charset= \"utf-8\"",
1000*6777b538SAndroid Build Coastguard Worker "text/html",
1001*6777b538SAndroid Build Coastguard Worker "utf-8",
1002*6777b538SAndroid Build Coastguard Worker true,
1003*6777b538SAndroid Build Coastguard Worker ""
1004*6777b538SAndroid Build Coastguard Worker },
1005*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/772350:
1006*6777b538SAndroid Build Coastguard Worker // Single quotes are not delimiters but must be treated as part of charset.
1007*6777b538SAndroid Build Coastguard Worker { "text/html; charset='utf-8'",
1008*6777b538SAndroid Build Coastguard Worker "text/html",
1009*6777b538SAndroid Build Coastguard Worker "'utf-8'",
1010*6777b538SAndroid Build Coastguard Worker true,
1011*6777b538SAndroid Build Coastguard Worker ""
1012*6777b538SAndroid Build Coastguard Worker },
1013*6777b538SAndroid Build Coastguard Worker // Empty subtype should be accepted.
1014*6777b538SAndroid Build Coastguard Worker { "text/",
1015*6777b538SAndroid Build Coastguard Worker "text/",
1016*6777b538SAndroid Build Coastguard Worker "",
1017*6777b538SAndroid Build Coastguard Worker false,
1018*6777b538SAndroid Build Coastguard Worker ""
1019*6777b538SAndroid Build Coastguard Worker },
1020*6777b538SAndroid Build Coastguard Worker // "*/*" is ignored unless it has params, or is not an exact match.
1021*6777b538SAndroid Build Coastguard Worker { "*/*", "", "", false, "" },
1022*6777b538SAndroid Build Coastguard Worker { "*/*; charset=utf-8", "*/*", "utf-8", true, "" },
1023*6777b538SAndroid Build Coastguard Worker { "*/* ", "*/*", "", false, "" },
1024*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/1326529
1025*6777b538SAndroid Build Coastguard Worker { "teXT/html", "text/html", "", false, ""},
1026*6777b538SAndroid Build Coastguard Worker // TODO(abarth): Add more interesting test cases.
1027*6777b538SAndroid Build Coastguard Worker };
1028*6777b538SAndroid Build Coastguard Worker // clang-format on
1029*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
1030*6777b538SAndroid Build Coastguard Worker std::string mime_type;
1031*6777b538SAndroid Build Coastguard Worker std::string charset;
1032*6777b538SAndroid Build Coastguard Worker bool had_charset = false;
1033*6777b538SAndroid Build Coastguard Worker std::string boundary;
1034*6777b538SAndroid Build Coastguard Worker HttpUtil::ParseContentType(test.content_type, &mime_type, &charset,
1035*6777b538SAndroid Build Coastguard Worker &had_charset, &boundary);
1036*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_mime_type, mime_type)
1037*6777b538SAndroid Build Coastguard Worker << "content_type=" << test.content_type;
1038*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_charset, charset)
1039*6777b538SAndroid Build Coastguard Worker << "content_type=" << test.content_type;
1040*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_had_charset, had_charset)
1041*6777b538SAndroid Build Coastguard Worker << "content_type=" << test.content_type;
1042*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_boundary, boundary)
1043*6777b538SAndroid Build Coastguard Worker << "content_type=" << test.content_type;
1044*6777b538SAndroid Build Coastguard Worker }
1045*6777b538SAndroid Build Coastguard Worker }
1046*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ParseContentResetCharset)1047*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ParseContentResetCharset) {
1048*6777b538SAndroid Build Coastguard Worker std::string mime_type;
1049*6777b538SAndroid Build Coastguard Worker std::string charset;
1050*6777b538SAndroid Build Coastguard Worker bool had_charset = false;
1051*6777b538SAndroid Build Coastguard Worker std::string boundary;
1052*6777b538SAndroid Build Coastguard Worker
1053*6777b538SAndroid Build Coastguard Worker // Set mime (capitalization should be ignored), but not charset.
1054*6777b538SAndroid Build Coastguard Worker HttpUtil::ParseContentType("Text/Html", &mime_type, &charset, &had_charset,
1055*6777b538SAndroid Build Coastguard Worker &boundary);
1056*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("text/html", mime_type);
1057*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", charset);
1058*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(had_charset);
1059*6777b538SAndroid Build Coastguard Worker
1060*6777b538SAndroid Build Coastguard Worker // The same mime, add charset.
1061*6777b538SAndroid Build Coastguard Worker HttpUtil::ParseContentType("tExt/hTml;charset=utf-8", &mime_type, &charset,
1062*6777b538SAndroid Build Coastguard Worker &had_charset, &boundary);
1063*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("text/html", mime_type);
1064*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("utf-8", charset);
1065*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(had_charset);
1066*6777b538SAndroid Build Coastguard Worker
1067*6777b538SAndroid Build Coastguard Worker // The same mime (different capitalization), but no charset - should not clear
1068*6777b538SAndroid Build Coastguard Worker // charset.
1069*6777b538SAndroid Build Coastguard Worker HttpUtil::ParseContentType("teXt/htMl", &mime_type, &charset, &had_charset,
1070*6777b538SAndroid Build Coastguard Worker &boundary);
1071*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("text/html", mime_type);
1072*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("utf-8", charset);
1073*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(had_charset);
1074*6777b538SAndroid Build Coastguard Worker
1075*6777b538SAndroid Build Coastguard Worker // A different mime will clear charset.
1076*6777b538SAndroid Build Coastguard Worker HttpUtil::ParseContentType("texT/plaiN", &mime_type, &charset, &had_charset,
1077*6777b538SAndroid Build Coastguard Worker &boundary);
1078*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("text/plain", mime_type);
1079*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", charset);
1080*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(had_charset);
1081*6777b538SAndroid Build Coastguard Worker }
1082*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ParseContentRangeHeader)1083*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ParseContentRangeHeader) {
1084*6777b538SAndroid Build Coastguard Worker const struct {
1085*6777b538SAndroid Build Coastguard Worker const char* const content_range_header_spec;
1086*6777b538SAndroid Build Coastguard Worker bool expected_return_value;
1087*6777b538SAndroid Build Coastguard Worker int64_t expected_first_byte_position;
1088*6777b538SAndroid Build Coastguard Worker int64_t expected_last_byte_position;
1089*6777b538SAndroid Build Coastguard Worker int64_t expected_instance_length;
1090*6777b538SAndroid Build Coastguard Worker } tests[] = {
1091*6777b538SAndroid Build Coastguard Worker {"", false, -1, -1, -1},
1092*6777b538SAndroid Build Coastguard Worker {"megabytes 0-10/50", false, -1, -1, -1},
1093*6777b538SAndroid Build Coastguard Worker {"0-10/50", false, -1, -1, -1},
1094*6777b538SAndroid Build Coastguard Worker {"Bytes 0-50/51", true, 0, 50, 51},
1095*6777b538SAndroid Build Coastguard Worker {"bytes 0-50/51", true, 0, 50, 51},
1096*6777b538SAndroid Build Coastguard Worker {"bytes\t0-50/51", false, -1, -1, -1},
1097*6777b538SAndroid Build Coastguard Worker {" bytes 0-50/51", true, 0, 50, 51},
1098*6777b538SAndroid Build Coastguard Worker {" bytes 0 - 50 \t / \t51", true, 0, 50, 51},
1099*6777b538SAndroid Build Coastguard Worker {"bytes 0\t-\t50\t/\t51\t", true, 0, 50, 51},
1100*6777b538SAndroid Build Coastguard Worker {" \tbytes\t\t\t 0\t-\t50\t/\t51\t", true, 0, 50, 51},
1101*6777b538SAndroid Build Coastguard Worker {"\t bytes \t 0 - 50 / 5 1", false, -1, -1, -1},
1102*6777b538SAndroid Build Coastguard Worker {"\t bytes \t 0 - 5 0 / 51", false, -1, -1, -1},
1103*6777b538SAndroid Build Coastguard Worker {"bytes 50-0/51", false, -1, -1, -1},
1104*6777b538SAndroid Build Coastguard Worker {"bytes * /*", false, -1, -1, -1},
1105*6777b538SAndroid Build Coastguard Worker {"bytes * / * ", false, -1, -1, -1},
1106*6777b538SAndroid Build Coastguard Worker {"bytes 0-50/*", false, -1, -1, -1},
1107*6777b538SAndroid Build Coastguard Worker {"bytes 0-50 / * ", false, -1, -1, -1},
1108*6777b538SAndroid Build Coastguard Worker {"bytes 0-10000000000/10000000001", true, 0, 10000000000ll,
1109*6777b538SAndroid Build Coastguard Worker 10000000001ll},
1110*6777b538SAndroid Build Coastguard Worker {"bytes 0-10000000000/10000000000", false, -1, -1, -1},
1111*6777b538SAndroid Build Coastguard Worker // 64 bit wraparound.
1112*6777b538SAndroid Build Coastguard Worker {"bytes 0 - 9223372036854775807 / 100", false, -1, -1, -1},
1113*6777b538SAndroid Build Coastguard Worker // 64 bit wraparound.
1114*6777b538SAndroid Build Coastguard Worker {"bytes 0 - 100 / -9223372036854775808", false, -1, -1, -1},
1115*6777b538SAndroid Build Coastguard Worker {"bytes */50", false, -1, -1, -1},
1116*6777b538SAndroid Build Coastguard Worker {"bytes 0-50/10", false, -1, -1, -1},
1117*6777b538SAndroid Build Coastguard Worker {"bytes 40-50/45", false, -1, -1, -1},
1118*6777b538SAndroid Build Coastguard Worker {"bytes 0-50/-10", false, -1, -1, -1},
1119*6777b538SAndroid Build Coastguard Worker {"bytes 0-0/1", true, 0, 0, 1},
1120*6777b538SAndroid Build Coastguard Worker {"bytes 0-40000000000000000000/40000000000000000001", false, -1, -1, -1},
1121*6777b538SAndroid Build Coastguard Worker {"bytes 1-/100", false, -1, -1, -1},
1122*6777b538SAndroid Build Coastguard Worker {"bytes -/100", false, -1, -1, -1},
1123*6777b538SAndroid Build Coastguard Worker {"bytes -1/100", false, -1, -1, -1},
1124*6777b538SAndroid Build Coastguard Worker {"bytes 0-1233/*", false, -1, -1, -1},
1125*6777b538SAndroid Build Coastguard Worker {"bytes -123 - -1/100", false, -1, -1, -1},
1126*6777b538SAndroid Build Coastguard Worker };
1127*6777b538SAndroid Build Coastguard Worker
1128*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
1129*6777b538SAndroid Build Coastguard Worker int64_t first_byte_position, last_byte_position, instance_length;
1130*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_return_value,
1131*6777b538SAndroid Build Coastguard Worker HttpUtil::ParseContentRangeHeaderFor206(
1132*6777b538SAndroid Build Coastguard Worker test.content_range_header_spec, &first_byte_position,
1133*6777b538SAndroid Build Coastguard Worker &last_byte_position, &instance_length))
1134*6777b538SAndroid Build Coastguard Worker << test.content_range_header_spec;
1135*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_first_byte_position, first_byte_position)
1136*6777b538SAndroid Build Coastguard Worker << test.content_range_header_spec;
1137*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_last_byte_position, last_byte_position)
1138*6777b538SAndroid Build Coastguard Worker << test.content_range_header_spec;
1139*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(test.expected_instance_length, instance_length)
1140*6777b538SAndroid Build Coastguard Worker << test.content_range_header_spec;
1141*6777b538SAndroid Build Coastguard Worker }
1142*6777b538SAndroid Build Coastguard Worker }
1143*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ParseRetryAfterHeader)1144*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ParseRetryAfterHeader) {
1145*6777b538SAndroid Build Coastguard Worker base::Time::Exploded now_exploded = {2014, 11, 4, 5, 22, 39, 30, 0};
1146*6777b538SAndroid Build Coastguard Worker base::Time now;
1147*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::Time::FromUTCExploded(now_exploded, &now));
1148*6777b538SAndroid Build Coastguard Worker
1149*6777b538SAndroid Build Coastguard Worker base::Time::Exploded later_exploded = {2015, 1, 5, 1, 12, 34, 56, 0};
1150*6777b538SAndroid Build Coastguard Worker base::Time later;
1151*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::Time::FromUTCExploded(later_exploded, &later));
1152*6777b538SAndroid Build Coastguard Worker
1153*6777b538SAndroid Build Coastguard Worker const struct {
1154*6777b538SAndroid Build Coastguard Worker const char* retry_after_string;
1155*6777b538SAndroid Build Coastguard Worker bool expected_return_value;
1156*6777b538SAndroid Build Coastguard Worker base::TimeDelta expected_retry_after;
1157*6777b538SAndroid Build Coastguard Worker } tests[] = {{"", false, base::TimeDelta()},
1158*6777b538SAndroid Build Coastguard Worker {"-3", false, base::TimeDelta()},
1159*6777b538SAndroid Build Coastguard Worker {"-2", false, base::TimeDelta()},
1160*6777b538SAndroid Build Coastguard Worker {"-1", false, base::TimeDelta()},
1161*6777b538SAndroid Build Coastguard Worker {"+0", false, base::TimeDelta()},
1162*6777b538SAndroid Build Coastguard Worker {"+1", false, base::TimeDelta()},
1163*6777b538SAndroid Build Coastguard Worker {"0", true, base::Seconds(0)},
1164*6777b538SAndroid Build Coastguard Worker {"1", true, base::Seconds(1)},
1165*6777b538SAndroid Build Coastguard Worker {"2", true, base::Seconds(2)},
1166*6777b538SAndroid Build Coastguard Worker {"3", true, base::Seconds(3)},
1167*6777b538SAndroid Build Coastguard Worker {"60", true, base::Seconds(60)},
1168*6777b538SAndroid Build Coastguard Worker {"3600", true, base::Seconds(3600)},
1169*6777b538SAndroid Build Coastguard Worker {"86400", true, base::Seconds(86400)},
1170*6777b538SAndroid Build Coastguard Worker {"Thu, 1 Jan 2015 12:34:56 GMT", true, later - now},
1171*6777b538SAndroid Build Coastguard Worker {"Mon, 1 Jan 1900 12:34:56 GMT", false, base::TimeDelta()}};
1172*6777b538SAndroid Build Coastguard Worker
1173*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(tests); ++i) {
1174*6777b538SAndroid Build Coastguard Worker base::TimeDelta retry_after;
1175*6777b538SAndroid Build Coastguard Worker bool return_value = HttpUtil::ParseRetryAfterHeader(
1176*6777b538SAndroid Build Coastguard Worker tests[i].retry_after_string, now, &retry_after);
1177*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected_return_value, return_value)
1178*6777b538SAndroid Build Coastguard Worker << "Test case " << i << ": expected " << tests[i].expected_return_value
1179*6777b538SAndroid Build Coastguard Worker << " but got " << return_value << ".";
1180*6777b538SAndroid Build Coastguard Worker if (tests[i].expected_return_value && return_value) {
1181*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected_retry_after, retry_after)
1182*6777b538SAndroid Build Coastguard Worker << "Test case " << i << ": expected "
1183*6777b538SAndroid Build Coastguard Worker << tests[i].expected_retry_after.InSeconds() << "s but got "
1184*6777b538SAndroid Build Coastguard Worker << retry_after.InSeconds() << "s.";
1185*6777b538SAndroid Build Coastguard Worker }
1186*6777b538SAndroid Build Coastguard Worker }
1187*6777b538SAndroid Build Coastguard Worker }
1188*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,TimeFormatHTTP)1189*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, TimeFormatHTTP) {
1190*6777b538SAndroid Build Coastguard Worker constexpr base::Time::Exploded kTime = {.year = 2011,
1191*6777b538SAndroid Build Coastguard Worker .month = 4,
1192*6777b538SAndroid Build Coastguard Worker .day_of_week = 6,
1193*6777b538SAndroid Build Coastguard Worker .day_of_month = 30,
1194*6777b538SAndroid Build Coastguard Worker .hour = 22,
1195*6777b538SAndroid Build Coastguard Worker .minute = 42,
1196*6777b538SAndroid Build Coastguard Worker .second = 7};
1197*6777b538SAndroid Build Coastguard Worker base::Time time;
1198*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::Time::FromUTCExploded(kTime, &time));
1199*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Sat, 30 Apr 2011 22:42:07 GMT", HttpUtil::TimeFormatHTTP(time));
1200*6777b538SAndroid Build Coastguard Worker }
1201*6777b538SAndroid Build Coastguard Worker
1202*6777b538SAndroid Build Coastguard Worker namespace {
CheckCurrentNameValuePair(HttpUtil::NameValuePairsIterator * parser,bool expect_valid,std::string expected_name,std::string expected_value)1203*6777b538SAndroid Build Coastguard Worker void CheckCurrentNameValuePair(HttpUtil::NameValuePairsIterator* parser,
1204*6777b538SAndroid Build Coastguard Worker bool expect_valid,
1205*6777b538SAndroid Build Coastguard Worker std::string expected_name,
1206*6777b538SAndroid Build Coastguard Worker std::string expected_value) {
1207*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expect_valid, parser->valid());
1208*6777b538SAndroid Build Coastguard Worker if (!expect_valid) {
1209*6777b538SAndroid Build Coastguard Worker return;
1210*6777b538SAndroid Build Coastguard Worker }
1211*6777b538SAndroid Build Coastguard Worker
1212*6777b538SAndroid Build Coastguard Worker // Let's make sure that these never change (i.e., when a quoted value is
1213*6777b538SAndroid Build Coastguard Worker // unquoted, it should be cached on the first calls and not regenerated
1214*6777b538SAndroid Build Coastguard Worker // later).
1215*6777b538SAndroid Build Coastguard Worker std::string::const_iterator first_value_begin = parser->value_begin();
1216*6777b538SAndroid Build Coastguard Worker std::string::const_iterator first_value_end = parser->value_end();
1217*6777b538SAndroid Build Coastguard Worker
1218*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_name, std::string(parser->name_begin(),
1219*6777b538SAndroid Build Coastguard Worker parser->name_end()));
1220*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_name, parser->name());
1221*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_value, std::string(parser->value_begin(),
1222*6777b538SAndroid Build Coastguard Worker parser->value_end()));
1223*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_value, parser->value());
1224*6777b538SAndroid Build Coastguard Worker
1225*6777b538SAndroid Build Coastguard Worker // Make sure they didn't/don't change.
1226*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(first_value_begin == parser->value_begin());
1227*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(first_value_end == parser->value_end());
1228*6777b538SAndroid Build Coastguard Worker }
1229*6777b538SAndroid Build Coastguard Worker
CheckNextNameValuePair(HttpUtil::NameValuePairsIterator * parser,bool expect_next,bool expect_valid,std::string expected_name,std::string expected_value)1230*6777b538SAndroid Build Coastguard Worker void CheckNextNameValuePair(HttpUtil::NameValuePairsIterator* parser,
1231*6777b538SAndroid Build Coastguard Worker bool expect_next,
1232*6777b538SAndroid Build Coastguard Worker bool expect_valid,
1233*6777b538SAndroid Build Coastguard Worker std::string expected_name,
1234*6777b538SAndroid Build Coastguard Worker std::string expected_value) {
1235*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expect_next, parser->GetNext());
1236*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expect_valid, parser->valid());
1237*6777b538SAndroid Build Coastguard Worker if (!expect_next || !expect_valid) {
1238*6777b538SAndroid Build Coastguard Worker return;
1239*6777b538SAndroid Build Coastguard Worker }
1240*6777b538SAndroid Build Coastguard Worker
1241*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(parser,
1242*6777b538SAndroid Build Coastguard Worker expect_valid,
1243*6777b538SAndroid Build Coastguard Worker expected_name,
1244*6777b538SAndroid Build Coastguard Worker expected_value);
1245*6777b538SAndroid Build Coastguard Worker }
1246*6777b538SAndroid Build Coastguard Worker
CheckInvalidNameValuePair(std::string valid_part,std::string invalid_part)1247*6777b538SAndroid Build Coastguard Worker void CheckInvalidNameValuePair(std::string valid_part,
1248*6777b538SAndroid Build Coastguard Worker std::string invalid_part) {
1249*6777b538SAndroid Build Coastguard Worker std::string whole_string = valid_part + invalid_part;
1250*6777b538SAndroid Build Coastguard Worker
1251*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator valid_parser(valid_part.begin(),
1252*6777b538SAndroid Build Coastguard Worker valid_part.end(),
1253*6777b538SAndroid Build Coastguard Worker ';');
1254*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator invalid_parser(whole_string.begin(),
1255*6777b538SAndroid Build Coastguard Worker whole_string.end(),
1256*6777b538SAndroid Build Coastguard Worker ';');
1257*6777b538SAndroid Build Coastguard Worker
1258*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(valid_parser.valid());
1259*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(invalid_parser.valid());
1260*6777b538SAndroid Build Coastguard Worker
1261*6777b538SAndroid Build Coastguard Worker // Both parsers should return all the same values until "valid_parser" is
1262*6777b538SAndroid Build Coastguard Worker // exhausted.
1263*6777b538SAndroid Build Coastguard Worker while (valid_parser.GetNext()) {
1264*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(invalid_parser.GetNext());
1265*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(valid_parser.valid());
1266*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(invalid_parser.valid());
1267*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(valid_parser.name(), invalid_parser.name());
1268*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(valid_parser.value(), invalid_parser.value());
1269*6777b538SAndroid Build Coastguard Worker }
1270*6777b538SAndroid Build Coastguard Worker
1271*6777b538SAndroid Build Coastguard Worker // valid_parser is exhausted and remains 'valid'
1272*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(valid_parser.valid());
1273*6777b538SAndroid Build Coastguard Worker
1274*6777b538SAndroid Build Coastguard Worker // invalid_parser's corresponding call to GetNext also returns false...
1275*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(invalid_parser.GetNext());
1276*6777b538SAndroid Build Coastguard Worker // ...but the parser is in an invalid state.
1277*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(invalid_parser.valid());
1278*6777b538SAndroid Build Coastguard Worker }
1279*6777b538SAndroid Build Coastguard Worker
1280*6777b538SAndroid Build Coastguard Worker } // namespace
1281*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorCopyAndAssign)1282*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorCopyAndAssign) {
1283*6777b538SAndroid Build Coastguard Worker std::string data =
1284*6777b538SAndroid Build Coastguard Worker "alpha=\"\\\"a\\\"\"; beta=\" b \"; cappa=\"c;\"; delta=\"d\"";
1285*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser_a(data.begin(), data.end(), ';');
1286*6777b538SAndroid Build Coastguard Worker
1287*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser_a.valid());
1288*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1289*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser_a, true, true, "alpha", "\"a\""));
1290*6777b538SAndroid Build Coastguard Worker
1291*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser_b(parser_a);
1292*6777b538SAndroid Build Coastguard Worker // a and b now point to same location
1293*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1294*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(&parser_b, true, "alpha", "\"a\""));
1295*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1296*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(&parser_a, true, "alpha", "\"a\""));
1297*6777b538SAndroid Build Coastguard Worker
1298*6777b538SAndroid Build Coastguard Worker // advance a, no effect on b
1299*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1300*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser_a, true, true, "beta", " b "));
1301*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1302*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(&parser_b, true, "alpha", "\"a\""));
1303*6777b538SAndroid Build Coastguard Worker
1304*6777b538SAndroid Build Coastguard Worker // assign b the current state of a, no effect on a
1305*6777b538SAndroid Build Coastguard Worker parser_b = parser_a;
1306*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1307*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(&parser_b, true, "beta", " b "));
1308*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1309*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(&parser_a, true, "beta", " b "));
1310*6777b538SAndroid Build Coastguard Worker
1311*6777b538SAndroid Build Coastguard Worker // advance b, no effect on a
1312*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1313*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser_b, true, true, "cappa", "c;"));
1314*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1315*6777b538SAndroid Build Coastguard Worker CheckCurrentNameValuePair(&parser_a, true, "beta", " b "));
1316*6777b538SAndroid Build Coastguard Worker }
1317*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorEmptyInput)1318*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorEmptyInput) {
1319*6777b538SAndroid Build Coastguard Worker std::string data;
1320*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(data.begin(), data.end(), ';');
1321*6777b538SAndroid Build Coastguard Worker
1322*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1323*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(
1324*6777b538SAndroid Build Coastguard Worker &parser, false, true, std::string(), std::string()));
1325*6777b538SAndroid Build Coastguard Worker }
1326*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIterator)1327*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIterator) {
1328*6777b538SAndroid Build Coastguard Worker std::string data =
1329*6777b538SAndroid Build Coastguard Worker "alpha=1; beta= 2 ;"
1330*6777b538SAndroid Build Coastguard Worker "cappa =' 3; foo=';"
1331*6777b538SAndroid Build Coastguard Worker "cappa =\" 3; foo=\";"
1332*6777b538SAndroid Build Coastguard Worker "delta= \" \\\"4\\\" \"; e= \" '5'\"; e=6;"
1333*6777b538SAndroid Build Coastguard Worker "f=\"\\\"\\h\\e\\l\\l\\o\\ \\w\\o\\r\\l\\d\\\"\";"
1334*6777b538SAndroid Build Coastguard Worker "g=\"\"; h=\"hello\"";
1335*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(data.begin(), data.end(), ';');
1336*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1337*6777b538SAndroid Build Coastguard Worker
1338*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1339*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "alpha", "1"));
1340*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1341*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "beta", "2"));
1342*6777b538SAndroid Build Coastguard Worker
1343*6777b538SAndroid Build Coastguard Worker // Single quotes shouldn't be treated as quotes.
1344*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1345*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "cappa", "' 3"));
1346*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1347*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "foo", "'"));
1348*6777b538SAndroid Build Coastguard Worker
1349*6777b538SAndroid Build Coastguard Worker // But double quotes should be, and can contain semi-colons and equal signs.
1350*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1351*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "cappa", " 3; foo="));
1352*6777b538SAndroid Build Coastguard Worker
1353*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1354*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "delta", " \"4\" "));
1355*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1356*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "e", " '5'"));
1357*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1358*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "e", "6"));
1359*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1360*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "f", "\"hello world\""));
1361*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1362*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "g", std::string()));
1363*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1364*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "h", "hello"));
1365*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(
1366*6777b538SAndroid Build Coastguard Worker &parser, false, true, std::string(), std::string()));
1367*6777b538SAndroid Build Coastguard Worker }
1368*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorOptionalValues)1369*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorOptionalValues) {
1370*6777b538SAndroid Build Coastguard Worker std::string data = "alpha=1; beta;cappa ; delta; e ; f=1";
1371*6777b538SAndroid Build Coastguard Worker // Test that the default parser requires values.
1372*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator default_parser(data.begin(), data.end(),
1373*6777b538SAndroid Build Coastguard Worker ';');
1374*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(default_parser.valid());
1375*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1376*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&default_parser, true, true, "alpha", "1"));
1377*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&default_parser, false, false,
1378*6777b538SAndroid Build Coastguard Worker std::string(), std::string()));
1379*6777b538SAndroid Build Coastguard Worker
1380*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator values_required_parser(
1381*6777b538SAndroid Build Coastguard Worker data.begin(), data.end(), ';',
1382*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Values::REQUIRED,
1383*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Quotes::NOT_STRICT);
1384*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(values_required_parser.valid());
1385*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&values_required_parser, true,
1386*6777b538SAndroid Build Coastguard Worker true, "alpha", "1"));
1387*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(
1388*6777b538SAndroid Build Coastguard Worker &values_required_parser, false, false, std::string(), std::string()));
1389*6777b538SAndroid Build Coastguard Worker
1390*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(
1391*6777b538SAndroid Build Coastguard Worker data.begin(), data.end(), ';',
1392*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED,
1393*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Quotes::NOT_STRICT);
1394*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1395*6777b538SAndroid Build Coastguard Worker
1396*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1397*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "alpha", "1"));
1398*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1399*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "beta", std::string()));
1400*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1401*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "cappa", std::string()));
1402*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1403*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "delta", std::string()));
1404*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1405*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "e", std::string()));
1406*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1407*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "f", "1"));
1408*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&parser, false, true,
1409*6777b538SAndroid Build Coastguard Worker std::string(), std::string()));
1410*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1411*6777b538SAndroid Build Coastguard Worker }
1412*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorIllegalInputs)1413*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorIllegalInputs) {
1414*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair("alpha=1", "; beta"));
1415*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair(std::string(), "beta"));
1416*6777b538SAndroid Build Coastguard Worker
1417*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair("alpha=1", "; \"beta\"=2"));
1418*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1419*6777b538SAndroid Build Coastguard Worker CheckInvalidNameValuePair(std::string(), "\"beta\"=2"));
1420*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair("alpha=1", ";beta="));
1421*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair("alpha=1",
1422*6777b538SAndroid Build Coastguard Worker ";beta=;cappa=2"));
1423*6777b538SAndroid Build Coastguard Worker
1424*6777b538SAndroid Build Coastguard Worker // According to the spec this is an error, but it doesn't seem appropriate to
1425*6777b538SAndroid Build Coastguard Worker // change our behaviour to be less permissive at this time.
1426*6777b538SAndroid Build Coastguard Worker // See NameValuePairsIteratorExtraSeparators test
1427*6777b538SAndroid Build Coastguard Worker // ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair("alpha=1", ";; beta=2"));
1428*6777b538SAndroid Build Coastguard Worker }
1429*6777b538SAndroid Build Coastguard Worker
1430*6777b538SAndroid Build Coastguard Worker // If we are going to support extra separators against the spec, let's just make
1431*6777b538SAndroid Build Coastguard Worker // sure they work rationally.
TEST(HttpUtilTest,NameValuePairsIteratorExtraSeparators)1432*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorExtraSeparators) {
1433*6777b538SAndroid Build Coastguard Worker std::string data = " ; ;;alpha=1; ;; ; beta= 2;cappa=3;;; ; ";
1434*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(data.begin(), data.end(), ';');
1435*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1436*6777b538SAndroid Build Coastguard Worker
1437*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1438*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "alpha", "1"));
1439*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1440*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "beta", "2"));
1441*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1442*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "cappa", "3"));
1443*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(
1444*6777b538SAndroid Build Coastguard Worker &parser, false, true, std::string(), std::string()));
1445*6777b538SAndroid Build Coastguard Worker }
1446*6777b538SAndroid Build Coastguard Worker
1447*6777b538SAndroid Build Coastguard Worker // See comments on the implementation of NameValuePairsIterator::GetNext
1448*6777b538SAndroid Build Coastguard Worker // regarding this derogation from the spec.
TEST(HttpUtilTest,NameValuePairsIteratorMissingEndQuote)1449*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorMissingEndQuote) {
1450*6777b538SAndroid Build Coastguard Worker std::string data = "name=\"value";
1451*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(data.begin(), data.end(), ';');
1452*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1453*6777b538SAndroid Build Coastguard Worker
1454*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1455*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "name", "value"));
1456*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(
1457*6777b538SAndroid Build Coastguard Worker &parser, false, true, std::string(), std::string()));
1458*6777b538SAndroid Build Coastguard Worker }
1459*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorStrictQuotesEscapedEndQuote)1460*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorStrictQuotesEscapedEndQuote) {
1461*6777b538SAndroid Build Coastguard Worker std::string data = "foo=bar; name=\"value\\\"";
1462*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(
1463*6777b538SAndroid Build Coastguard Worker data.begin(), data.end(), ';',
1464*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Values::REQUIRED,
1465*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
1466*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1467*6777b538SAndroid Build Coastguard Worker
1468*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1469*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "foo", "bar"));
1470*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&parser, false, false,
1471*6777b538SAndroid Build Coastguard Worker std::string(), std::string()));
1472*6777b538SAndroid Build Coastguard Worker }
1473*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorStrictQuotesQuoteInValue)1474*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorStrictQuotesQuoteInValue) {
1475*6777b538SAndroid Build Coastguard Worker std::string data = "foo=\"bar\"; name=\"va\"lue\"";
1476*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(
1477*6777b538SAndroid Build Coastguard Worker data.begin(), data.end(), ';',
1478*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Values::REQUIRED,
1479*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
1480*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1481*6777b538SAndroid Build Coastguard Worker
1482*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1483*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "foo", "bar"));
1484*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&parser, false, false,
1485*6777b538SAndroid Build Coastguard Worker std::string(), std::string()));
1486*6777b538SAndroid Build Coastguard Worker }
1487*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorStrictQuotesMissingEndQuote)1488*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorStrictQuotesMissingEndQuote) {
1489*6777b538SAndroid Build Coastguard Worker std::string data = "foo=\"bar\"; name=\"value";
1490*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(
1491*6777b538SAndroid Build Coastguard Worker data.begin(), data.end(), ';',
1492*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Values::REQUIRED,
1493*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
1494*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1495*6777b538SAndroid Build Coastguard Worker
1496*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1497*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "foo", "bar"));
1498*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&parser, false, false,
1499*6777b538SAndroid Build Coastguard Worker std::string(), std::string()));
1500*6777b538SAndroid Build Coastguard Worker }
1501*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,NameValuePairsIteratorStrictQuotesSingleQuotes)1502*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, NameValuePairsIteratorStrictQuotesSingleQuotes) {
1503*6777b538SAndroid Build Coastguard Worker std::string data = "foo=\"bar\"; name='value; ok=it'";
1504*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator parser(
1505*6777b538SAndroid Build Coastguard Worker data.begin(), data.end(), ';',
1506*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Values::REQUIRED,
1507*6777b538SAndroid Build Coastguard Worker HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
1508*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(parser.valid());
1509*6777b538SAndroid Build Coastguard Worker
1510*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1511*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "foo", "bar"));
1512*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1513*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "name", "'value"));
1514*6777b538SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(
1515*6777b538SAndroid Build Coastguard Worker CheckNextNameValuePair(&parser, true, true, "ok", "it'"));
1516*6777b538SAndroid Build Coastguard Worker }
1517*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,HasValidators)1518*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, HasValidators) {
1519*6777b538SAndroid Build Coastguard Worker const char* const kMissing = "";
1520*6777b538SAndroid Build Coastguard Worker const char* const kEtagEmpty = "\"\"";
1521*6777b538SAndroid Build Coastguard Worker const char* const kEtagStrong = "\"strong\"";
1522*6777b538SAndroid Build Coastguard Worker const char* const kEtagWeak = "W/\"weak\"";
1523*6777b538SAndroid Build Coastguard Worker const char* const kLastModified = "Tue, 15 Nov 1994 12:45:26 GMT";
1524*6777b538SAndroid Build Coastguard Worker const char* const kLastModifiedInvalid = "invalid";
1525*6777b538SAndroid Build Coastguard Worker
1526*6777b538SAndroid Build Coastguard Worker const HttpVersion v0_9 = HttpVersion(0, 9);
1527*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kMissing, kMissing));
1528*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagStrong, kMissing));
1529*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagWeak, kMissing));
1530*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagEmpty, kMissing));
1531*6777b538SAndroid Build Coastguard Worker
1532*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kMissing, kLastModified));
1533*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagStrong, kLastModified));
1534*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagWeak, kLastModified));
1535*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagEmpty, kLastModified));
1536*6777b538SAndroid Build Coastguard Worker
1537*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kMissing, kLastModifiedInvalid));
1538*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(
1539*6777b538SAndroid Build Coastguard Worker HttpUtil::HasValidators(v0_9, kEtagStrong, kLastModifiedInvalid));
1540*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagWeak, kLastModifiedInvalid));
1541*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v0_9, kEtagEmpty, kLastModifiedInvalid));
1542*6777b538SAndroid Build Coastguard Worker
1543*6777b538SAndroid Build Coastguard Worker const HttpVersion v1_0 = HttpVersion(1, 0);
1544*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kMissing, kMissing));
1545*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kEtagStrong, kMissing));
1546*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kEtagWeak, kMissing));
1547*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kEtagEmpty, kMissing));
1548*6777b538SAndroid Build Coastguard Worker
1549*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_0, kMissing, kLastModified));
1550*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_0, kEtagStrong, kLastModified));
1551*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_0, kEtagWeak, kLastModified));
1552*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_0, kEtagEmpty, kLastModified));
1553*6777b538SAndroid Build Coastguard Worker
1554*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kMissing, kLastModifiedInvalid));
1555*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(
1556*6777b538SAndroid Build Coastguard Worker HttpUtil::HasValidators(v1_0, kEtagStrong, kLastModifiedInvalid));
1557*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kEtagWeak, kLastModifiedInvalid));
1558*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_0, kEtagEmpty, kLastModifiedInvalid));
1559*6777b538SAndroid Build Coastguard Worker
1560*6777b538SAndroid Build Coastguard Worker const HttpVersion v1_1 = HttpVersion(1, 1);
1561*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_1, kMissing, kMissing));
1562*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagStrong, kMissing));
1563*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagWeak, kMissing));
1564*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagEmpty, kMissing));
1565*6777b538SAndroid Build Coastguard Worker
1566*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kMissing, kLastModified));
1567*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagStrong, kLastModified));
1568*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagWeak, kLastModified));
1569*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagEmpty, kLastModified));
1570*6777b538SAndroid Build Coastguard Worker
1571*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::HasValidators(v1_1, kMissing, kLastModifiedInvalid));
1572*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagStrong, kLastModifiedInvalid));
1573*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagWeak, kLastModifiedInvalid));
1574*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::HasValidators(v1_1, kEtagEmpty, kLastModifiedInvalid));
1575*6777b538SAndroid Build Coastguard Worker }
1576*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,IsValidHeaderValue)1577*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, IsValidHeaderValue) {
1578*6777b538SAndroid Build Coastguard Worker const char* const invalid_values[] = {
1579*6777b538SAndroid Build Coastguard Worker "X-Requested-With: chrome${NUL}Sec-Unsafe: injected",
1580*6777b538SAndroid Build Coastguard Worker "X-Requested-With: chrome\r\nSec-Unsafe: injected",
1581*6777b538SAndroid Build Coastguard Worker "X-Requested-With: chrome\nSec-Unsafe: injected",
1582*6777b538SAndroid Build Coastguard Worker "X-Requested-With: chrome\rSec-Unsafe: injected",
1583*6777b538SAndroid Build Coastguard Worker };
1584*6777b538SAndroid Build Coastguard Worker for (const std::string& value : invalid_values) {
1585*6777b538SAndroid Build Coastguard Worker std::string replaced = value;
1586*6777b538SAndroid Build Coastguard Worker base::ReplaceSubstringsAfterOffset(&replaced, 0, "${NUL}",
1587*6777b538SAndroid Build Coastguard Worker std::string(1, '\0'));
1588*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsValidHeaderValue(replaced)) << replaced;
1589*6777b538SAndroid Build Coastguard Worker }
1590*6777b538SAndroid Build Coastguard Worker
1591*6777b538SAndroid Build Coastguard Worker // Check that all characters permitted by RFC7230 3.2.6 are allowed.
1592*6777b538SAndroid Build Coastguard Worker std::string allowed = "\t";
1593*6777b538SAndroid Build Coastguard Worker for (char c = '\x20'; c < '\x7F'; ++c) {
1594*6777b538SAndroid Build Coastguard Worker allowed.append(1, c);
1595*6777b538SAndroid Build Coastguard Worker }
1596*6777b538SAndroid Build Coastguard Worker for (int c = 0x80; c <= 0xFF; ++c) {
1597*6777b538SAndroid Build Coastguard Worker allowed.append(1, static_cast<char>(c));
1598*6777b538SAndroid Build Coastguard Worker }
1599*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsValidHeaderValue(allowed));
1600*6777b538SAndroid Build Coastguard Worker }
1601*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,IsToken)1602*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, IsToken) {
1603*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsToken("valid"));
1604*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsToken("!"));
1605*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsToken("~"));
1606*6777b538SAndroid Build Coastguard Worker
1607*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken(""));
1608*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken(std::string_view()));
1609*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken("hello, world"));
1610*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken(" "));
1611*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken(std::string_view("\0", 1)));
1612*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken("\x01"));
1613*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken("\x7F"));
1614*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken("\x80"));
1615*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsToken("\xff"));
1616*6777b538SAndroid Build Coastguard Worker }
1617*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,IsLWS)1618*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, IsLWS) {
1619*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('\v'));
1620*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('\0'));
1621*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('1'));
1622*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('a'));
1623*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('.'));
1624*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('\n'));
1625*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsLWS('\r'));
1626*6777b538SAndroid Build Coastguard Worker
1627*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsLWS('\t'));
1628*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsLWS(' '));
1629*6777b538SAndroid Build Coastguard Worker }
1630*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,IsControlChar)1631*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, IsControlChar) {
1632*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('1'));
1633*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('a'));
1634*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('.'));
1635*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('$'));
1636*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('\x7E'));
1637*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('\x80'));
1638*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HttpUtil::IsControlChar('\xFF'));
1639*6777b538SAndroid Build Coastguard Worker
1640*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\0'));
1641*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\v'));
1642*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\n'));
1643*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\r'));
1644*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\t'));
1645*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\x01'));
1646*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HttpUtil::IsControlChar('\x7F'));
1647*6777b538SAndroid Build Coastguard Worker }
1648*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ParseAcceptEncoding)1649*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ParseAcceptEncoding) {
1650*6777b538SAndroid Build Coastguard Worker const struct {
1651*6777b538SAndroid Build Coastguard Worker const char* const value;
1652*6777b538SAndroid Build Coastguard Worker const char* const expected;
1653*6777b538SAndroid Build Coastguard Worker } tests[] = {
1654*6777b538SAndroid Build Coastguard Worker {"", "*"},
1655*6777b538SAndroid Build Coastguard Worker {"identity;q=1, *;q=0", "identity"},
1656*6777b538SAndroid Build Coastguard Worker {"identity", "identity"},
1657*6777b538SAndroid Build Coastguard Worker {"FOO, Bar", "bar|foo|identity"},
1658*6777b538SAndroid Build Coastguard Worker {"foo; q=1", "foo|identity"},
1659*6777b538SAndroid Build Coastguard Worker {"abc, foo; Q=1.0", "abc|foo|identity"},
1660*6777b538SAndroid Build Coastguard Worker {"abc, foo;q= 1.00 , bar", "abc|bar|foo|identity"},
1661*6777b538SAndroid Build Coastguard Worker {"abc, foo; q=1.000, bar", "abc|bar|foo|identity"},
1662*6777b538SAndroid Build Coastguard Worker {"abc, foo ; q = 0 , bar", "abc|bar|identity"},
1663*6777b538SAndroid Build Coastguard Worker {"abc, foo; q=0.0, bar", "abc|bar|identity"},
1664*6777b538SAndroid Build Coastguard Worker {"abc, foo; q=0.00, bar", "abc|bar|identity"},
1665*6777b538SAndroid Build Coastguard Worker {"abc, foo; q=0.000, bar", "abc|bar|identity"},
1666*6777b538SAndroid Build Coastguard Worker {"abc, foo; q=0.001, bar", "abc|bar|foo|identity"},
1667*6777b538SAndroid Build Coastguard Worker {"gzip", "gzip|identity|x-gzip"},
1668*6777b538SAndroid Build Coastguard Worker {"x-gzip", "gzip|identity|x-gzip"},
1669*6777b538SAndroid Build Coastguard Worker {"compress", "compress|identity|x-compress"},
1670*6777b538SAndroid Build Coastguard Worker {"x-compress", "compress|identity|x-compress"},
1671*6777b538SAndroid Build Coastguard Worker {"x-compress", "compress|identity|x-compress"},
1672*6777b538SAndroid Build Coastguard Worker {"foo bar", "INVALID"},
1673*6777b538SAndroid Build Coastguard Worker {"foo;", "INVALID"},
1674*6777b538SAndroid Build Coastguard Worker {"foo;w=1", "INVALID"},
1675*6777b538SAndroid Build Coastguard Worker {"foo;q+1", "INVALID"},
1676*6777b538SAndroid Build Coastguard Worker {"foo;q=2", "INVALID"},
1677*6777b538SAndroid Build Coastguard Worker {"foo;q=1.001", "INVALID"},
1678*6777b538SAndroid Build Coastguard Worker {"foo;q=0.", "INVALID"},
1679*6777b538SAndroid Build Coastguard Worker {"foo,\"bar\"", "INVALID"},
1680*6777b538SAndroid Build Coastguard Worker };
1681*6777b538SAndroid Build Coastguard Worker
1682*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
1683*6777b538SAndroid Build Coastguard Worker std::string value(test.value);
1684*6777b538SAndroid Build Coastguard Worker std::string reformatted;
1685*6777b538SAndroid Build Coastguard Worker std::set<std::string> allowed_encodings;
1686*6777b538SAndroid Build Coastguard Worker if (!HttpUtil::ParseAcceptEncoding(value, &allowed_encodings)) {
1687*6777b538SAndroid Build Coastguard Worker reformatted = "INVALID";
1688*6777b538SAndroid Build Coastguard Worker } else {
1689*6777b538SAndroid Build Coastguard Worker std::vector<std::string> encodings_list;
1690*6777b538SAndroid Build Coastguard Worker for (auto const& encoding : allowed_encodings)
1691*6777b538SAndroid Build Coastguard Worker encodings_list.push_back(encoding);
1692*6777b538SAndroid Build Coastguard Worker reformatted = base::JoinString(encodings_list, "|");
1693*6777b538SAndroid Build Coastguard Worker }
1694*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ(test.expected, reformatted.c_str())
1695*6777b538SAndroid Build Coastguard Worker << "value=\"" << value << "\"";
1696*6777b538SAndroid Build Coastguard Worker }
1697*6777b538SAndroid Build Coastguard Worker }
1698*6777b538SAndroid Build Coastguard Worker
TEST(HttpUtilTest,ParseContentEncoding)1699*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ParseContentEncoding) {
1700*6777b538SAndroid Build Coastguard Worker const struct {
1701*6777b538SAndroid Build Coastguard Worker const char* const value;
1702*6777b538SAndroid Build Coastguard Worker const char* const expected;
1703*6777b538SAndroid Build Coastguard Worker } tests[] = {
1704*6777b538SAndroid Build Coastguard Worker {"", ""},
1705*6777b538SAndroid Build Coastguard Worker {"identity;q=1, *;q=0", "INVALID"},
1706*6777b538SAndroid Build Coastguard Worker {"identity", "identity"},
1707*6777b538SAndroid Build Coastguard Worker {"FOO, zergli , Bar", "bar|foo|zergli"},
1708*6777b538SAndroid Build Coastguard Worker {"foo, *", "INVALID"},
1709*6777b538SAndroid Build Coastguard Worker {"foo,\"bar\"", "INVALID"},
1710*6777b538SAndroid Build Coastguard Worker };
1711*6777b538SAndroid Build Coastguard Worker
1712*6777b538SAndroid Build Coastguard Worker for (const auto& test : tests) {
1713*6777b538SAndroid Build Coastguard Worker std::string value(test.value);
1714*6777b538SAndroid Build Coastguard Worker std::string reformatted;
1715*6777b538SAndroid Build Coastguard Worker std::set<std::string> used_encodings;
1716*6777b538SAndroid Build Coastguard Worker if (!HttpUtil::ParseContentEncoding(value, &used_encodings)) {
1717*6777b538SAndroid Build Coastguard Worker reformatted = "INVALID";
1718*6777b538SAndroid Build Coastguard Worker } else {
1719*6777b538SAndroid Build Coastguard Worker std::vector<std::string> encodings_list;
1720*6777b538SAndroid Build Coastguard Worker for (auto const& encoding : used_encodings)
1721*6777b538SAndroid Build Coastguard Worker encodings_list.push_back(encoding);
1722*6777b538SAndroid Build Coastguard Worker reformatted = base::JoinString(encodings_list, "|");
1723*6777b538SAndroid Build Coastguard Worker }
1724*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ(test.expected, reformatted.c_str())
1725*6777b538SAndroid Build Coastguard Worker << "value=\"" << value << "\"";
1726*6777b538SAndroid Build Coastguard Worker }
1727*6777b538SAndroid Build Coastguard Worker }
1728*6777b538SAndroid Build Coastguard Worker
1729*6777b538SAndroid Build Coastguard Worker // Test the expansion of the Language List.
TEST(HttpUtilTest,ExpandLanguageList)1730*6777b538SAndroid Build Coastguard Worker TEST(HttpUtilTest, ExpandLanguageList) {
1731*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", HttpUtil::ExpandLanguageList(""));
1732*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en", HttpUtil::ExpandLanguageList("en-US"));
1733*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("fr", HttpUtil::ExpandLanguageList("fr"));
1734*6777b538SAndroid Build Coastguard Worker
1735*6777b538SAndroid Build Coastguard Worker // The base language is added after all regional codes...
1736*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en-CA,en", HttpUtil::ExpandLanguageList("en-US,en-CA"));
1737*6777b538SAndroid Build Coastguard Worker
1738*6777b538SAndroid Build Coastguard Worker // ... but before other language families.
1739*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en-CA,en,fr",
1740*6777b538SAndroid Build Coastguard Worker HttpUtil::ExpandLanguageList("en-US,en-CA,fr"));
1741*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en-CA,en,fr,en-AU",
1742*6777b538SAndroid Build Coastguard Worker HttpUtil::ExpandLanguageList("en-US,en-CA,fr,en-AU"));
1743*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en-CA,en,fr-CA,fr",
1744*6777b538SAndroid Build Coastguard Worker HttpUtil::ExpandLanguageList("en-US,en-CA,fr-CA"));
1745*6777b538SAndroid Build Coastguard Worker
1746*6777b538SAndroid Build Coastguard Worker // Add a base language even if it's already in the list.
1747*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en,fr-CA,fr,it,es-AR,es,it-IT",
1748*6777b538SAndroid Build Coastguard Worker HttpUtil::ExpandLanguageList("en-US,fr-CA,it,fr,es-AR,it-IT"));
1749*6777b538SAndroid Build Coastguard Worker // Trims a whitespace.
1750*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("en-US,en,fr", HttpUtil::ExpandLanguageList("en-US, fr"));
1751*6777b538SAndroid Build Coastguard Worker
1752*6777b538SAndroid Build Coastguard Worker // Do not expand the single character subtag 'x' as a language.
1753*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("x-private-agreement-subtags",
1754*6777b538SAndroid Build Coastguard Worker HttpUtil::ExpandLanguageList("x-private-agreement-subtags"));
1755*6777b538SAndroid Build Coastguard Worker // Do not expand the single character subtag 'i' as a language.
1756*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("i-klingon", HttpUtil::ExpandLanguageList("i-klingon"));
1757*6777b538SAndroid Build Coastguard Worker }
1758*6777b538SAndroid Build Coastguard Worker
1759*6777b538SAndroid Build Coastguard Worker } // namespace net
1760