OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/pickle.h" | 9 #include "base/pickle.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 struct ContentTypeTestData { | 30 struct ContentTypeTestData { |
31 const std::string raw_headers; | 31 const std::string raw_headers; |
32 const std::string mime_type; | 32 const std::string mime_type; |
33 const bool has_mimetype; | 33 const bool has_mimetype; |
34 const std::string charset; | 34 const std::string charset; |
35 const bool has_charset; | 35 const bool has_charset; |
36 const std::string all_content_type; | 36 const std::string all_content_type; |
37 }; | 37 }; |
38 | 38 |
39 class HttpResponseHeadersTest : public testing::Test { | 39 class HttpResponseHeadersTest : public testing::Test {}; |
40 }; | |
41 | 40 |
42 // Transform "normal"-looking headers (\n-separated) to the appropriate | 41 // Transform "normal"-looking headers (\n-separated) to the appropriate |
43 // input format for ParseRawHeaders (\0-separated). | 42 // input format for ParseRawHeaders (\0-separated). |
44 void HeadersToRaw(std::string* headers) { | 43 void HeadersToRaw(std::string* headers) { |
45 std::replace(headers->begin(), headers->end(), '\n', '\0'); | 44 std::replace(headers->begin(), headers->end(), '\n', '\0'); |
46 if (!headers->empty()) | 45 if (!headers->empty()) |
47 *headers += '\0'; | 46 *headers += '\0'; |
48 } | 47 } |
49 | 48 |
50 void TestCommon(const TestData& test) { | 49 void TestCommon(const TestData& test) { |
(...skipping 13 matching lines...) Expand all Loading... |
64 std::replace(expected_headers.begin(), expected_headers.end(), '\n', '\\'); | 63 std::replace(expected_headers.begin(), expected_headers.end(), '\n', '\\'); |
65 | 64 |
66 EXPECT_EQ(expected_headers, headers); | 65 EXPECT_EQ(expected_headers, headers); |
67 | 66 |
68 EXPECT_EQ(test.expected_response_code, parsed->response_code()); | 67 EXPECT_EQ(test.expected_response_code, parsed->response_code()); |
69 | 68 |
70 EXPECT_TRUE(test.expected_parsed_version == parsed->GetParsedHttpVersion()); | 69 EXPECT_TRUE(test.expected_parsed_version == parsed->GetParsedHttpVersion()); |
71 EXPECT_TRUE(test.expected_version == parsed->GetHttpVersion()); | 70 EXPECT_TRUE(test.expected_version == parsed->GetHttpVersion()); |
72 } | 71 } |
73 | 72 |
74 } // end namespace | 73 } // end namespace |
75 | 74 |
76 // Check that we normalize headers properly. | 75 // Check that we normalize headers properly. |
77 TEST(HttpResponseHeadersTest, NormalizeHeadersWhitespace) { | 76 TEST(HttpResponseHeadersTest, NormalizeHeadersWhitespace) { |
78 TestData test = { | 77 TestData test = { |
79 "HTTP/1.1 202 Accepted \n" | 78 "HTTP/1.1 202 Accepted \n" |
80 "Content-TYPE : text/html; charset=utf-8 \n" | 79 "Content-TYPE : text/html; charset=utf-8 \n" |
81 "Set-Cookie: a \n" | 80 "Set-Cookie: a \n" |
82 "Set-Cookie: b \n", | 81 "Set-Cookie: b \n", |
83 | 82 "HTTP/1.1 202 Accepted\n" |
84 "HTTP/1.1 202 Accepted\n" | 83 "Content-TYPE: text/html; charset=utf-8\n" |
85 "Content-TYPE: text/html; charset=utf-8\n" | 84 "Set-Cookie: a, b\n", |
86 "Set-Cookie: a, b\n", | 85 202, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
87 | |
88 202, | |
89 net::HttpVersion(1,1), | |
90 net::HttpVersion(1,1) | |
91 }; | |
92 TestCommon(test); | 86 TestCommon(test); |
93 } | 87 } |
94 | 88 |
95 // Check that we normalize headers properly (header name is invalid if starts | 89 // Check that we normalize headers properly (header name is invalid if starts |
96 // with LWS). | 90 // with LWS). |
97 TEST(HttpResponseHeadersTest, NormalizeHeadersLeadingWhitespace) { | 91 TEST(HttpResponseHeadersTest, NormalizeHeadersLeadingWhitespace) { |
98 TestData test = { | 92 TestData test = { |
99 "HTTP/1.1 202 Accepted \n" | 93 "HTTP/1.1 202 Accepted \n" |
100 // Starts with space -- will be skipped as invalid. | 94 // Starts with space -- will be skipped as invalid. |
101 " Content-TYPE : text/html; charset=utf-8 \n" | 95 " Content-TYPE : text/html; charset=utf-8 \n" |
102 "Set-Cookie: a \n" | 96 "Set-Cookie: a \n" |
103 "Set-Cookie: b \n", | 97 "Set-Cookie: b \n", |
104 | 98 "HTTP/1.1 202 Accepted\n" |
105 "HTTP/1.1 202 Accepted\n" | 99 "Set-Cookie: a, b\n", |
106 "Set-Cookie: a, b\n", | 100 202, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
107 | |
108 202, | |
109 net::HttpVersion(1,1), | |
110 net::HttpVersion(1,1) | |
111 }; | |
112 TestCommon(test); | 101 TestCommon(test); |
113 } | 102 } |
114 | 103 |
115 TEST(HttpResponseHeadersTest, BlankHeaders) { | 104 TEST(HttpResponseHeadersTest, BlankHeaders) { |
116 TestData test = { | 105 TestData test = { |
117 "HTTP/1.1 200 OK\n" | 106 "HTTP/1.1 200 OK\n" |
118 "Header1 : \n" | 107 "Header1 : \n" |
119 "Header2: \n" | 108 "Header2: \n" |
120 "Header3:\n" | 109 "Header3:\n" |
121 "Header4\n" | 110 "Header4\n" |
122 "Header5 :\n", | 111 "Header5 :\n", |
123 | 112 "HTTP/1.1 200 OK\n" |
124 "HTTP/1.1 200 OK\n" | 113 "Header1: \n" |
125 "Header1: \n" | 114 "Header2: \n" |
126 "Header2: \n" | 115 "Header3: \n" |
127 "Header3: \n" | 116 "Header5: \n", |
128 "Header5: \n", | 117 200, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
129 | |
130 200, | |
131 net::HttpVersion(1,1), | |
132 net::HttpVersion(1,1) | |
133 }; | |
134 TestCommon(test); | 118 TestCommon(test); |
135 } | 119 } |
136 | 120 |
137 TEST(HttpResponseHeadersTest, NormalizeHeadersVersion) { | 121 TEST(HttpResponseHeadersTest, NormalizeHeadersVersion) { |
138 // Don't believe the http/0.9 version if there are headers! | 122 // Don't believe the http/0.9 version if there are headers! |
139 TestData test = { | 123 TestData test = { |
140 "hTtP/0.9 201\n" | 124 "hTtP/0.9 201\n" |
141 "Content-TYPE: text/html; charset=utf-8\n", | 125 "Content-TYPE: text/html; charset=utf-8\n", |
142 | 126 "HTTP/1.0 201 OK\n" |
143 "HTTP/1.0 201 OK\n" | 127 "Content-TYPE: text/html; charset=utf-8\n", |
144 "Content-TYPE: text/html; charset=utf-8\n", | 128 201, net::HttpVersion(0, 9), net::HttpVersion(1, 0)}; |
145 | |
146 201, | |
147 net::HttpVersion(0,9), | |
148 net::HttpVersion(1,0) | |
149 }; | |
150 TestCommon(test); | 129 TestCommon(test); |
151 } | 130 } |
152 | 131 |
153 TEST(HttpResponseHeadersTest, PreserveHttp09) { | 132 TEST(HttpResponseHeadersTest, PreserveHttp09) { |
154 // Accept the HTTP/0.9 version number if there are no headers. | 133 // Accept the HTTP/0.9 version number if there are no headers. |
155 // This is how HTTP/0.9 responses get constructed from HttpNetworkTransaction. | 134 // This is how HTTP/0.9 responses get constructed from HttpNetworkTransaction. |
156 TestData test = { | 135 TestData test = {"hTtP/0.9 200 OK\n", "HTTP/0.9 200 OK\n", 200, |
157 "hTtP/0.9 200 OK\n", | 136 net::HttpVersion(0, 9), net::HttpVersion(0, 9)}; |
158 | |
159 "HTTP/0.9 200 OK\n", | |
160 | |
161 200, | |
162 net::HttpVersion(0,9), | |
163 net::HttpVersion(0,9) | |
164 }; | |
165 TestCommon(test); | 137 TestCommon(test); |
166 } | 138 } |
167 | 139 |
168 TEST(HttpResponseHeadersTest, NormalizeHeadersMissingOK) { | 140 TEST(HttpResponseHeadersTest, NormalizeHeadersMissingOK) { |
169 TestData test = { | 141 TestData test = { |
170 "HTTP/1.1 201\n" | 142 "HTTP/1.1 201\n" |
171 "Content-TYPE: text/html; charset=utf-8\n", | 143 "Content-TYPE: text/html; charset=utf-8\n", |
172 | 144 "HTTP/1.1 201 OK\n" |
173 "HTTP/1.1 201 OK\n" | 145 "Content-TYPE: text/html; charset=utf-8\n", |
174 "Content-TYPE: text/html; charset=utf-8\n", | 146 201, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
175 | |
176 201, | |
177 net::HttpVersion(1,1), | |
178 net::HttpVersion(1,1) | |
179 }; | |
180 TestCommon(test); | 147 TestCommon(test); |
181 } | 148 } |
182 | 149 |
183 TEST(HttpResponseHeadersTest, NormalizeHeadersBadStatus) { | 150 TEST(HttpResponseHeadersTest, NormalizeHeadersBadStatus) { |
184 TestData test = { | 151 TestData test = { |
185 "SCREWED_UP_STATUS_LINE\n" | 152 "SCREWED_UP_STATUS_LINE\n" |
186 "Content-TYPE: text/html; charset=utf-8\n", | 153 "Content-TYPE: text/html; charset=utf-8\n", |
187 | 154 "HTTP/1.0 200 OK\n" |
188 "HTTP/1.0 200 OK\n" | 155 "Content-TYPE: text/html; charset=utf-8\n", |
189 "Content-TYPE: text/html; charset=utf-8\n", | 156 200, net::HttpVersion(0, 0), // Parse error |
190 | 157 net::HttpVersion(1, 0)}; |
191 200, | |
192 net::HttpVersion(0,0), // Parse error | |
193 net::HttpVersion(1,0) | |
194 }; | |
195 TestCommon(test); | 158 TestCommon(test); |
196 } | 159 } |
197 | 160 |
198 TEST(HttpResponseHeadersTest, NormalizeHeadersInvalidStatusCode) { | 161 TEST(HttpResponseHeadersTest, NormalizeHeadersInvalidStatusCode) { |
199 TestData test = { | 162 TestData test = {"HTTP/1.1 -1 Unknown\n", "HTTP/1.1 200 OK\n", 200, |
200 "HTTP/1.1 -1 Unknown\n", | 163 net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
201 | |
202 "HTTP/1.1 200 OK\n", | |
203 | |
204 200, | |
205 net::HttpVersion(1,1), | |
206 net::HttpVersion(1,1) | |
207 }; | |
208 TestCommon(test); | 164 TestCommon(test); |
209 } | 165 } |
210 | 166 |
211 TEST(HttpResponseHeadersTest, NormalizeHeadersEmpty) { | 167 TEST(HttpResponseHeadersTest, NormalizeHeadersEmpty) { |
212 TestData test = { | 168 TestData test = {"", "HTTP/1.0 200 OK\n", 200, |
213 "", | 169 net::HttpVersion(0, 0), // Parse Error |
214 | 170 net::HttpVersion(1, 0)}; |
215 "HTTP/1.0 200 OK\n", | |
216 | |
217 200, | |
218 net::HttpVersion(0,0), // Parse Error | |
219 net::HttpVersion(1,0) | |
220 }; | |
221 TestCommon(test); | 171 TestCommon(test); |
222 } | 172 } |
223 | 173 |
224 TEST(HttpResponseHeadersTest, NormalizeHeadersStartWithColon) { | 174 TEST(HttpResponseHeadersTest, NormalizeHeadersStartWithColon) { |
225 TestData test = { | 175 TestData test = { |
226 "HTTP/1.1 202 Accepted \n" | 176 "HTTP/1.1 202 Accepted \n" |
227 "foo: bar\n" | 177 "foo: bar\n" |
228 ": a \n" | 178 ": a \n" |
229 " : b\n" | 179 " : b\n" |
230 "baz: blat \n", | 180 "baz: blat \n", |
231 | 181 "HTTP/1.1 202 Accepted\n" |
232 "HTTP/1.1 202 Accepted\n" | 182 "foo: bar\n" |
233 "foo: bar\n" | 183 "baz: blat\n", |
234 "baz: blat\n", | 184 202, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
235 | |
236 202, | |
237 net::HttpVersion(1,1), | |
238 net::HttpVersion(1,1) | |
239 }; | |
240 TestCommon(test); | 185 TestCommon(test); |
241 } | 186 } |
242 | 187 |
243 TEST(HttpResponseHeadersTest, NormalizeHeadersStartWithColonAtEOL) { | 188 TEST(HttpResponseHeadersTest, NormalizeHeadersStartWithColonAtEOL) { |
244 TestData test = { | 189 TestData test = { |
245 "HTTP/1.1 202 Accepted \n" | 190 "HTTP/1.1 202 Accepted \n" |
246 "foo: \n" | 191 "foo: \n" |
247 "bar:\n" | 192 "bar:\n" |
248 "baz: blat \n" | 193 "baz: blat \n" |
249 "zip:\n", | 194 "zip:\n", |
250 | 195 "HTTP/1.1 202 Accepted\n" |
251 "HTTP/1.1 202 Accepted\n" | 196 "foo: \n" |
252 "foo: \n" | 197 "bar: \n" |
253 "bar: \n" | 198 "baz: blat\n" |
254 "baz: blat\n" | 199 "zip: \n", |
255 "zip: \n", | 200 202, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
256 | |
257 202, | |
258 net::HttpVersion(1,1), | |
259 net::HttpVersion(1,1) | |
260 }; | |
261 TestCommon(test); | 201 TestCommon(test); |
262 } | 202 } |
263 | 203 |
264 TEST(HttpResponseHeadersTest, NormalizeHeadersOfWhitepace) { | 204 TEST(HttpResponseHeadersTest, NormalizeHeadersOfWhitepace) { |
265 TestData test = { | 205 TestData test = {"\n \n", "HTTP/1.0 200 OK\n", 200, |
266 "\n \n", | 206 net::HttpVersion(0, 0), // Parse error |
267 | 207 net::HttpVersion(1, 0)}; |
268 "HTTP/1.0 200 OK\n", | |
269 | |
270 200, | |
271 net::HttpVersion(0,0), // Parse error | |
272 net::HttpVersion(1,0) | |
273 }; | |
274 TestCommon(test); | 208 TestCommon(test); |
275 } | 209 } |
276 | 210 |
277 TEST(HttpResponseHeadersTest, RepeatedSetCookie) { | 211 TEST(HttpResponseHeadersTest, RepeatedSetCookie) { |
278 TestData test = { | 212 TestData test = { |
279 "HTTP/1.1 200 OK\n" | 213 "HTTP/1.1 200 OK\n" |
280 "Set-Cookie: x=1\n" | 214 "Set-Cookie: x=1\n" |
281 "Set-Cookie: y=2\n", | 215 "Set-Cookie: y=2\n", |
282 | 216 "HTTP/1.1 200 OK\n" |
283 "HTTP/1.1 200 OK\n" | 217 "Set-Cookie: x=1, y=2\n", |
284 "Set-Cookie: x=1, y=2\n", | 218 200, net::HttpVersion(1, 1), net::HttpVersion(1, 1)}; |
285 | |
286 200, | |
287 net::HttpVersion(1,1), | |
288 net::HttpVersion(1,1) | |
289 }; | |
290 TestCommon(test); | 219 TestCommon(test); |
291 } | 220 } |
292 | 221 |
293 TEST(HttpResponseHeadersTest, GetNormalizedHeader) { | 222 TEST(HttpResponseHeadersTest, GetNormalizedHeader) { |
294 std::string headers = | 223 std::string headers = |
295 "HTTP/1.1 200 OK\n" | 224 "HTTP/1.1 200 OK\n" |
296 "Cache-control: private\n" | 225 "Cache-control: private\n" |
297 "cache-Control: no-store\n"; | 226 "cache-Control: no-store\n"; |
298 HeadersToRaw(&headers); | 227 HeadersToRaw(&headers); |
299 scoped_refptr<net::HttpResponseHeaders> parsed( | 228 scoped_refptr<net::HttpResponseHeaders> parsed( |
300 new net::HttpResponseHeaders(headers)); | 229 new net::HttpResponseHeaders(headers)); |
301 | 230 |
302 std::string value; | 231 std::string value; |
303 EXPECT_TRUE(parsed->GetNormalizedHeader("cache-control", &value)); | 232 EXPECT_TRUE(parsed->GetNormalizedHeader("cache-control", &value)); |
304 EXPECT_EQ("private, no-store", value); | 233 EXPECT_EQ("private, no-store", value); |
305 } | 234 } |
306 | 235 |
307 TEST(HttpResponseHeadersTest, Persist) { | 236 TEST(HttpResponseHeadersTest, Persist) { |
308 const struct { | 237 const struct { |
309 net::HttpResponseHeaders::PersistOptions options; | 238 net::HttpResponseHeaders::PersistOptions options; |
310 const char* raw_headers; | 239 const char* raw_headers; |
311 const char* expected_headers; | 240 const char* expected_headers; |
312 } tests[] = { | 241 } tests[] = { |
313 { net::HttpResponseHeaders::PERSIST_ALL, | 242 {net::HttpResponseHeaders::PERSIST_ALL, |
314 "HTTP/1.1 200 OK\n" | 243 "HTTP/1.1 200 OK\n" |
315 "Cache-control:private\n" | 244 "Cache-control:private\n" |
316 "cache-Control:no-store\n", | 245 "cache-Control:no-store\n", |
317 | 246 "HTTP/1.1 200 OK\n" |
318 "HTTP/1.1 200 OK\n" | 247 "Cache-control: private, no-store\n"}, |
319 "Cache-control: private, no-store\n" | 248 {net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP, |
320 }, | 249 "HTTP/1.1 200 OK\n" |
321 { net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP, | 250 "connection: keep-alive\n" |
322 "HTTP/1.1 200 OK\n" | 251 "server: blah\n", |
323 "connection: keep-alive\n" | 252 "HTTP/1.1 200 OK\n" |
324 "server: blah\n", | 253 "server: blah\n"}, |
325 | 254 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE | |
326 "HTTP/1.1 200 OK\n" | 255 net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP, |
327 "server: blah\n" | 256 "HTTP/1.1 200 OK\n" |
328 }, | 257 "fOo: 1\n" |
329 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE | | 258 "Foo: 2\n" |
330 net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP, | 259 "Transfer-Encoding: chunked\n" |
331 "HTTP/1.1 200 OK\n" | 260 "CoNnection: keep-alive\n" |
332 "fOo: 1\n" | 261 "cache-control: private, no-cache=\"foo\"\n", |
333 "Foo: 2\n" | 262 "HTTP/1.1 200 OK\n" |
334 "Transfer-Encoding: chunked\n" | 263 "cache-control: private, no-cache=\"foo\"\n"}, |
335 "CoNnection: keep-alive\n" | 264 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
336 "cache-control: private, no-cache=\"foo\"\n", | 265 "HTTP/1.1 200 OK\n" |
337 | 266 "Foo: 2\n" |
338 "HTTP/1.1 200 OK\n" | 267 "Cache-Control: private,no-cache=\"foo, bar\"\n" |
339 "cache-control: private, no-cache=\"foo\"\n" | 268 "bar", |
340 }, | 269 "HTTP/1.1 200 OK\n" |
341 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 270 "Cache-Control: private,no-cache=\"foo, bar\"\n"}, |
342 "HTTP/1.1 200 OK\n" | 271 // ignore bogus no-cache value |
343 "Foo: 2\n" | 272 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
344 "Cache-Control: private,no-cache=\"foo, bar\"\n" | 273 "HTTP/1.1 200 OK\n" |
345 "bar", | 274 "Foo: 2\n" |
346 | 275 "Cache-Control: private,no-cache=foo\n", |
347 "HTTP/1.1 200 OK\n" | 276 "HTTP/1.1 200 OK\n" |
348 "Cache-Control: private,no-cache=\"foo, bar\"\n" | 277 "Foo: 2\n" |
349 }, | 278 "Cache-Control: private,no-cache=foo\n"}, |
350 // ignore bogus no-cache value | 279 // ignore bogus no-cache value |
351 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 280 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
352 "HTTP/1.1 200 OK\n" | 281 "HTTP/1.1 200 OK\n" |
353 "Foo: 2\n" | 282 "Foo: 2\n" |
354 "Cache-Control: private,no-cache=foo\n", | 283 "Cache-Control: private, no-cache=\n", |
355 | 284 "HTTP/1.1 200 OK\n" |
356 "HTTP/1.1 200 OK\n" | 285 "Foo: 2\n" |
357 "Foo: 2\n" | 286 "Cache-Control: private, no-cache=\n"}, |
358 "Cache-Control: private,no-cache=foo\n" | 287 // ignore empty no-cache value |
359 }, | 288 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
360 // ignore bogus no-cache value | 289 "HTTP/1.1 200 OK\n" |
361 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 290 "Foo: 2\n" |
362 "HTTP/1.1 200 OK\n" | 291 "Cache-Control: private, no-cache=\"\"\n", |
363 "Foo: 2\n" | 292 "HTTP/1.1 200 OK\n" |
364 "Cache-Control: private, no-cache=\n", | 293 "Foo: 2\n" |
365 | 294 "Cache-Control: private, no-cache=\"\"\n"}, |
366 "HTTP/1.1 200 OK\n" | 295 // ignore wrong quotes no-cache value |
367 "Foo: 2\n" | 296 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
368 "Cache-Control: private, no-cache=\n" | 297 "HTTP/1.1 200 OK\n" |
369 }, | 298 "Foo: 2\n" |
370 // ignore empty no-cache value | 299 "Cache-Control: private, no-cache=\'foo\'\n", |
371 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 300 "HTTP/1.1 200 OK\n" |
372 "HTTP/1.1 200 OK\n" | 301 "Foo: 2\n" |
373 "Foo: 2\n" | 302 "Cache-Control: private, no-cache=\'foo\'\n"}, |
374 "Cache-Control: private, no-cache=\"\"\n", | 303 // ignore unterminated quotes no-cache value |
375 | 304 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
376 "HTTP/1.1 200 OK\n" | 305 "HTTP/1.1 200 OK\n" |
377 "Foo: 2\n" | 306 "Foo: 2\n" |
378 "Cache-Control: private, no-cache=\"\"\n" | 307 "Cache-Control: private, no-cache=\"foo\n", |
379 }, | 308 "HTTP/1.1 200 OK\n" |
380 // ignore wrong quotes no-cache value | 309 "Foo: 2\n" |
381 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 310 "Cache-Control: private, no-cache=\"foo\n"}, |
382 "HTTP/1.1 200 OK\n" | 311 // accept sloppy LWS |
383 "Foo: 2\n" | 312 {net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, |
384 "Cache-Control: private, no-cache=\'foo\'\n", | 313 "HTTP/1.1 200 OK\n" |
385 | 314 "Foo: 2\n" |
386 "HTTP/1.1 200 OK\n" | 315 "Cache-Control: private, no-cache=\" foo\t, bar\"\n", |
387 "Foo: 2\n" | 316 "HTTP/1.1 200 OK\n" |
388 "Cache-Control: private, no-cache=\'foo\'\n" | 317 "Cache-Control: private, no-cache=\" foo\t, bar\"\n"}, |
389 }, | 318 // header name appears twice, separated by another header |
390 // ignore unterminated quotes no-cache value | 319 {net::HttpResponseHeaders::PERSIST_ALL, |
391 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 320 "HTTP/1.1 200 OK\n" |
392 "HTTP/1.1 200 OK\n" | 321 "Foo: 1\n" |
393 "Foo: 2\n" | 322 "Bar: 2\n" |
394 "Cache-Control: private, no-cache=\"foo\n", | 323 "Foo: 3\n", |
395 | 324 "HTTP/1.1 200 OK\n" |
396 "HTTP/1.1 200 OK\n" | 325 "Foo: 1, 3\n" |
397 "Foo: 2\n" | 326 "Bar: 2\n"}, |
398 "Cache-Control: private, no-cache=\"foo\n" | 327 // header name appears twice, separated by another header (type 2) |
399 }, | 328 {net::HttpResponseHeaders::PERSIST_ALL, |
400 // accept sloppy LWS | 329 "HTTP/1.1 200 OK\n" |
401 { net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE, | 330 "Foo: 1, 3\n" |
402 "HTTP/1.1 200 OK\n" | 331 "Bar: 2\n" |
403 "Foo: 2\n" | 332 "Foo: 4\n", |
404 "Cache-Control: private, no-cache=\" foo\t, bar\"\n", | 333 "HTTP/1.1 200 OK\n" |
405 | 334 "Foo: 1, 3, 4\n" |
406 "HTTP/1.1 200 OK\n" | 335 "Bar: 2\n"}, |
407 "Cache-Control: private, no-cache=\" foo\t, bar\"\n" | 336 // Test filtering of cookie headers. |
408 }, | 337 {net::HttpResponseHeaders::PERSIST_SANS_COOKIES, |
409 // header name appears twice, separated by another header | 338 "HTTP/1.1 200 OK\n" |
410 { net::HttpResponseHeaders::PERSIST_ALL, | 339 "Set-Cookie: foo=bar; httponly\n" |
411 "HTTP/1.1 200 OK\n" | 340 "Set-Cookie: bar=foo\n" |
412 "Foo: 1\n" | 341 "Bar: 1\n" |
413 "Bar: 2\n" | 342 "Set-Cookie2: bar2=foo2\n", |
414 "Foo: 3\n", | 343 "HTTP/1.1 200 OK\n" |
415 | 344 "Bar: 1\n"}, |
416 "HTTP/1.1 200 OK\n" | 345 // Test LWS at the end of a header. |
417 "Foo: 1, 3\n" | 346 {net::HttpResponseHeaders::PERSIST_ALL, |
418 "Bar: 2\n" | 347 "HTTP/1.1 200 OK\n" |
419 }, | 348 "Content-Length: 450 \n" |
420 // header name appears twice, separated by another header (type 2) | 349 "Content-Encoding: gzip\n", |
421 { net::HttpResponseHeaders::PERSIST_ALL, | 350 "HTTP/1.1 200 OK\n" |
422 "HTTP/1.1 200 OK\n" | 351 "Content-Length: 450\n" |
423 "Foo: 1, 3\n" | 352 "Content-Encoding: gzip\n"}, |
424 "Bar: 2\n" | 353 // Test LWS at the end of a header. |
425 "Foo: 4\n", | 354 {net::HttpResponseHeaders::PERSIST_RAW, |
426 | 355 "HTTP/1.1 200 OK\n" |
427 "HTTP/1.1 200 OK\n" | 356 "Content-Length: 450 \n" |
428 "Foo: 1, 3, 4\n" | 357 "Content-Encoding: gzip\n", |
429 "Bar: 2\n" | 358 "HTTP/1.1 200 OK\n" |
430 }, | 359 "Content-Length: 450\n" |
431 // Test filtering of cookie headers. | 360 "Content-Encoding: gzip\n"}, |
432 { net::HttpResponseHeaders::PERSIST_SANS_COOKIES, | 361 // Test filtering of transport security state headers. |
433 "HTTP/1.1 200 OK\n" | 362 {net::HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE, |
434 "Set-Cookie: foo=bar; httponly\n" | 363 "HTTP/1.1 200 OK\n" |
435 "Set-Cookie: bar=foo\n" | 364 "Strict-Transport-Security: max-age=1576800\n" |
436 "Bar: 1\n" | 365 "Bar: 1\n" |
437 "Set-Cookie2: bar2=foo2\n", | 366 "Public-Key-Pins: max-age=100000; " |
438 | 367 "pin-sha1=\"ObT42aoSpAqWdY9WfRfL7i0HsVk=\";" |
439 "HTTP/1.1 200 OK\n" | 368 "pin-sha1=\"7kW49EVwZG0hSNx41ZO/fUPN0ek=\"", |
440 "Bar: 1\n" | 369 "HTTP/1.1 200 OK\n" |
441 }, | 370 "Bar: 1\n"}, |
442 // Test LWS at the end of a header. | 371 }; |
443 { net::HttpResponseHeaders::PERSIST_ALL, | |
444 "HTTP/1.1 200 OK\n" | |
445 "Content-Length: 450 \n" | |
446 "Content-Encoding: gzip\n", | |
447 | |
448 "HTTP/1.1 200 OK\n" | |
449 "Content-Length: 450\n" | |
450 "Content-Encoding: gzip\n" | |
451 }, | |
452 // Test LWS at the end of a header. | |
453 { net::HttpResponseHeaders::PERSIST_RAW, | |
454 "HTTP/1.1 200 OK\n" | |
455 "Content-Length: 450 \n" | |
456 "Content-Encoding: gzip\n", | |
457 | |
458 "HTTP/1.1 200 OK\n" | |
459 "Content-Length: 450\n" | |
460 "Content-Encoding: gzip\n" | |
461 }, | |
462 // Test filtering of transport security state headers. | |
463 { net::HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE, | |
464 "HTTP/1.1 200 OK\n" | |
465 "Strict-Transport-Security: max-age=1576800\n" | |
466 "Bar: 1\n" | |
467 "Public-Key-Pins: max-age=100000; " | |
468 "pin-sha1=\"ObT42aoSpAqWdY9WfRfL7i0HsVk=\";" | |
469 "pin-sha1=\"7kW49EVwZG0hSNx41ZO/fUPN0ek=\"", | |
470 | |
471 "HTTP/1.1 200 OK\n" | |
472 "Bar: 1\n" | |
473 }, | |
474 }; | |
475 | 372 |
476 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 373 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
477 std::string headers = tests[i].raw_headers; | 374 std::string headers = tests[i].raw_headers; |
478 HeadersToRaw(&headers); | 375 HeadersToRaw(&headers); |
479 scoped_refptr<net::HttpResponseHeaders> parsed1( | 376 scoped_refptr<net::HttpResponseHeaders> parsed1( |
480 new net::HttpResponseHeaders(headers)); | 377 new net::HttpResponseHeaders(headers)); |
481 | 378 |
482 Pickle pickle; | 379 Pickle pickle; |
483 parsed1->Persist(&pickle, tests[i].options); | 380 parsed1->Persist(&pickle, tests[i].options); |
484 | 381 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 // do not end in "GMT" as RFC2616 requires. | 454 // do not end in "GMT" as RFC2616 requires. |
558 std::string headers = | 455 std::string headers = |
559 "HTTP/1.1 200 OK\n" | 456 "HTTP/1.1 200 OK\n" |
560 "Date: Tue, 07 Aug 2007 23:10:55\n" | 457 "Date: Tue, 07 Aug 2007 23:10:55\n" |
561 "Last-Modified: Tue, 07 Aug 2007 19:10:55 EDT\n" | 458 "Last-Modified: Tue, 07 Aug 2007 19:10:55 EDT\n" |
562 "Expires: Tue, 07 Aug 2007 23:10:55 UTC\n"; | 459 "Expires: Tue, 07 Aug 2007 23:10:55 UTC\n"; |
563 HeadersToRaw(&headers); | 460 HeadersToRaw(&headers); |
564 scoped_refptr<net::HttpResponseHeaders> parsed( | 461 scoped_refptr<net::HttpResponseHeaders> parsed( |
565 new net::HttpResponseHeaders(headers)); | 462 new net::HttpResponseHeaders(headers)); |
566 base::Time expected_value; | 463 base::Time expected_value; |
567 ASSERT_TRUE(base::Time::FromString("Tue, 07 Aug 2007 23:10:55 GMT", | 464 ASSERT_TRUE( |
568 &expected_value)); | 465 base::Time::FromString("Tue, 07 Aug 2007 23:10:55 GMT", &expected_value)); |
569 | 466 |
570 base::Time value; | 467 base::Time value; |
571 // When the timezone is missing, GMT is a good guess as its what RFC2616 | 468 // When the timezone is missing, GMT is a good guess as its what RFC2616 |
572 // requires. | 469 // requires. |
573 EXPECT_TRUE(parsed->GetDateValue(&value)); | 470 EXPECT_TRUE(parsed->GetDateValue(&value)); |
574 EXPECT_EQ(expected_value, value); | 471 EXPECT_EQ(expected_value, value); |
575 // If GMT is missing but an RFC822-conforming one is present, use that. | 472 // If GMT is missing but an RFC822-conforming one is present, use that. |
576 EXPECT_TRUE(parsed->GetLastModifiedValue(&value)); | 473 EXPECT_TRUE(parsed->GetLastModifiedValue(&value)); |
577 EXPECT_EQ(expected_value, value); | 474 EXPECT_EQ(expected_value, value); |
578 // If an unknown timezone is present, treat like a missing timezone and | 475 // If an unknown timezone is present, treat like a missing timezone and |
579 // default to GMT. The only example of a web server not specifying "GMT" | 476 // default to GMT. The only example of a web server not specifying "GMT" |
580 // used "UTC" which is equivalent to GMT. | 477 // used "UTC" which is equivalent to GMT. |
581 if (parsed->GetExpiresValue(&value)) | 478 if (parsed->GetExpiresValue(&value)) |
582 EXPECT_EQ(expected_value, value); | 479 EXPECT_EQ(expected_value, value); |
583 } | 480 } |
584 | 481 |
585 TEST(HttpResponseHeadersTest, GetMimeType) { | 482 TEST(HttpResponseHeadersTest, GetMimeType) { |
586 const ContentTypeTestData tests[] = { | 483 const ContentTypeTestData tests[] = { |
587 { "HTTP/1.1 200 OK\n" | 484 {"HTTP/1.1 200 OK\n" |
588 "Content-type: text/html\n", | 485 "Content-type: text/html\n", |
589 "text/html", true, | 486 "text/html", true, "", false, "text/html"}, |
590 "", false, | 487 // Multiple content-type headers should give us the last one. |
591 "text/html" }, | 488 {"HTTP/1.1 200 OK\n" |
592 // Multiple content-type headers should give us the last one. | 489 "Content-type: text/html\n" |
593 { "HTTP/1.1 200 OK\n" | 490 "Content-type: text/html\n", |
594 "Content-type: text/html\n" | 491 "text/html", true, "", false, "text/html, text/html"}, |
595 "Content-type: text/html\n", | 492 {"HTTP/1.1 200 OK\n" |
596 "text/html", true, | 493 "Content-type: text/plain\n" |
597 "", false, | 494 "Content-type: text/html\n" |
598 "text/html, text/html" }, | 495 "Content-type: text/plain\n" |
599 { "HTTP/1.1 200 OK\n" | 496 "Content-type: text/html\n", |
600 "Content-type: text/plain\n" | 497 "text/html", true, "", false, |
601 "Content-type: text/html\n" | 498 "text/plain, text/html, text/plain, text/html"}, |
602 "Content-type: text/plain\n" | 499 // Test charset parsing. |
603 "Content-type: text/html\n", | 500 {"HTTP/1.1 200 OK\n" |
604 "text/html", true, | 501 "Content-type: text/html\n" |
605 "", false, | 502 "Content-type: text/html; charset=ISO-8859-1\n", |
606 "text/plain, text/html, text/plain, text/html" }, | 503 "text/html", true, "iso-8859-1", true, |
607 // Test charset parsing. | 504 "text/html, text/html; charset=ISO-8859-1"}, |
608 { "HTTP/1.1 200 OK\n" | 505 // Test charset in double quotes. |
609 "Content-type: text/html\n" | 506 {"HTTP/1.1 200 OK\n" |
610 "Content-type: text/html; charset=ISO-8859-1\n", | 507 "Content-type: text/html\n" |
611 "text/html", true, | 508 "Content-type: text/html; charset=\"ISO-8859-1\"\n", |
612 "iso-8859-1", true, | 509 "text/html", true, "iso-8859-1", true, |
613 "text/html, text/html; charset=ISO-8859-1" }, | 510 "text/html, text/html; charset=\"ISO-8859-1\""}, |
614 // Test charset in double quotes. | 511 // If there are multiple matching content-type headers, we carry |
615 { "HTTP/1.1 200 OK\n" | 512 // over the charset value. |
616 "Content-type: text/html\n" | 513 {"HTTP/1.1 200 OK\n" |
617 "Content-type: text/html; charset=\"ISO-8859-1\"\n", | 514 "Content-type: text/html;charset=utf-8\n" |
618 "text/html", true, | 515 "Content-type: text/html\n", |
619 "iso-8859-1", true, | 516 "text/html", true, "utf-8", true, "text/html;charset=utf-8, text/html"}, |
620 "text/html, text/html; charset=\"ISO-8859-1\"" }, | 517 // Test single quotes. |
621 // If there are multiple matching content-type headers, we carry | 518 {"HTTP/1.1 200 OK\n" |
622 // over the charset value. | 519 "Content-type: text/html;charset='utf-8'\n" |
623 { "HTTP/1.1 200 OK\n" | 520 "Content-type: text/html\n", |
624 "Content-type: text/html;charset=utf-8\n" | 521 "text/html", true, "utf-8", true, |
625 "Content-type: text/html\n", | 522 "text/html;charset='utf-8', text/html"}, |
626 "text/html", true, | 523 // Last charset wins if matching content-type. |
627 "utf-8", true, | 524 {"HTTP/1.1 200 OK\n" |
628 "text/html;charset=utf-8, text/html" }, | 525 "Content-type: text/html;charset=utf-8\n" |
629 // Test single quotes. | 526 "Content-type: text/html;charset=iso-8859-1\n", |
630 { "HTTP/1.1 200 OK\n" | 527 "text/html", true, "iso-8859-1", true, |
631 "Content-type: text/html;charset='utf-8'\n" | 528 "text/html;charset=utf-8, text/html;charset=iso-8859-1"}, |
632 "Content-type: text/html\n", | 529 // Charset is ignored if the content types change. |
633 "text/html", true, | 530 {"HTTP/1.1 200 OK\n" |
634 "utf-8", true, | 531 "Content-type: text/plain;charset=utf-8\n" |
635 "text/html;charset='utf-8', text/html" }, | 532 "Content-type: text/html\n", |
636 // Last charset wins if matching content-type. | 533 "text/html", true, "", false, "text/plain;charset=utf-8, text/html"}, |
637 { "HTTP/1.1 200 OK\n" | 534 // Empty content-type |
638 "Content-type: text/html;charset=utf-8\n" | 535 {"HTTP/1.1 200 OK\n" |
639 "Content-type: text/html;charset=iso-8859-1\n", | 536 "Content-type: \n", |
640 "text/html", true, | 537 "", false, "", false, ""}, |
641 "iso-8859-1", true, | 538 // Emtpy charset |
642 "text/html;charset=utf-8, text/html;charset=iso-8859-1" }, | 539 {"HTTP/1.1 200 OK\n" |
643 // Charset is ignored if the content types change. | 540 "Content-type: text/html;charset=\n", |
644 { "HTTP/1.1 200 OK\n" | 541 "text/html", true, "", false, "text/html;charset="}, |
645 "Content-type: text/plain;charset=utf-8\n" | 542 // Multiple charsets, last one wins. |
646 "Content-type: text/html\n", | 543 {"HTTP/1.1 200 OK\n" |
647 "text/html", true, | 544 "Content-type: text/html;charset=utf-8; charset=iso-8859-1\n", |
648 "", false, | 545 "text/html", true, "iso-8859-1", true, |
649 "text/plain;charset=utf-8, text/html" }, | 546 "text/html;charset=utf-8; charset=iso-8859-1"}, |
650 // Empty content-type | 547 // Multiple params. |
651 { "HTTP/1.1 200 OK\n" | 548 {"HTTP/1.1 200 OK\n" |
652 "Content-type: \n", | 549 "Content-type: text/html; foo=utf-8; charset=iso-8859-1\n", |
653 "", false, | 550 "text/html", true, "iso-8859-1", true, |
654 "", false, | 551 "text/html; foo=utf-8; charset=iso-8859-1"}, |
655 "" }, | 552 {"HTTP/1.1 200 OK\n" |
656 // Emtpy charset | 553 "Content-type: text/html ; charset=utf-8 ; bar=iso-8859-1\n", |
657 { "HTTP/1.1 200 OK\n" | 554 "text/html", true, "utf-8", true, |
658 "Content-type: text/html;charset=\n", | 555 "text/html ; charset=utf-8 ; bar=iso-8859-1"}, |
659 "text/html", true, | 556 // Comma embeded in quotes. |
660 "", false, | 557 {"HTTP/1.1 200 OK\n" |
661 "text/html;charset=" }, | 558 "Content-type: text/html ; charset='utf-8,text/plain' ;\n", |
662 // Multiple charsets, last one wins. | 559 "text/html", true, "utf-8,text/plain", true, |
663 { "HTTP/1.1 200 OK\n" | 560 "text/html ; charset='utf-8,text/plain' ;"}, |
664 "Content-type: text/html;charset=utf-8; charset=iso-8859-1\n", | 561 // Charset with leading spaces. |
665 "text/html", true, | 562 {"HTTP/1.1 200 OK\n" |
666 "iso-8859-1", true, | 563 "Content-type: text/html ; charset= 'utf-8' ;\n", |
667 "text/html;charset=utf-8; charset=iso-8859-1" }, | 564 "text/html", true, "utf-8", true, "text/html ; charset= 'utf-8' ;"}, |
668 // Multiple params. | 565 // Media type comments in mime-type. |
669 { "HTTP/1.1 200 OK\n" | 566 {"HTTP/1.1 200 OK\n" |
670 "Content-type: text/html; foo=utf-8; charset=iso-8859-1\n", | 567 "Content-type: text/html (html)\n", |
671 "text/html", true, | 568 "text/html", true, "", false, "text/html (html)"}, |
672 "iso-8859-1", true, | 569 // Incomplete charset= param |
673 "text/html; foo=utf-8; charset=iso-8859-1" }, | 570 {"HTTP/1.1 200 OK\n" |
674 { "HTTP/1.1 200 OK\n" | 571 "Content-type: text/html; char=\n", |
675 "Content-type: text/html ; charset=utf-8 ; bar=iso-8859-1\n", | 572 "text/html", true, "", false, "text/html; char="}, |
676 "text/html", true, | 573 // Invalid media type: no slash |
677 "utf-8", true, | 574 {"HTTP/1.1 200 OK\n" |
678 "text/html ; charset=utf-8 ; bar=iso-8859-1" }, | 575 "Content-type: texthtml\n", |
679 // Comma embeded in quotes. | 576 "", false, "", false, "texthtml"}, |
680 { "HTTP/1.1 200 OK\n" | 577 // Invalid media type: */* |
681 "Content-type: text/html ; charset='utf-8,text/plain' ;\n", | 578 {"HTTP/1.1 200 OK\n" |
682 "text/html", true, | 579 "Content-type: */*\n", |
683 "utf-8,text/plain", true, | 580 "", false, "", false, "*/*"}, |
684 "text/html ; charset='utf-8,text/plain' ;" }, | |
685 // Charset with leading spaces. | |
686 { "HTTP/1.1 200 OK\n" | |
687 "Content-type: text/html ; charset= 'utf-8' ;\n", | |
688 "text/html", true, | |
689 "utf-8", true, | |
690 "text/html ; charset= 'utf-8' ;" }, | |
691 // Media type comments in mime-type. | |
692 { "HTTP/1.1 200 OK\n" | |
693 "Content-type: text/html (html)\n", | |
694 "text/html", true, | |
695 "", false, | |
696 "text/html (html)" }, | |
697 // Incomplete charset= param | |
698 { "HTTP/1.1 200 OK\n" | |
699 "Content-type: text/html; char=\n", | |
700 "text/html", true, | |
701 "", false, | |
702 "text/html; char=" }, | |
703 // Invalid media type: no slash | |
704 { "HTTP/1.1 200 OK\n" | |
705 "Content-type: texthtml\n", | |
706 "", false, | |
707 "", false, | |
708 "texthtml" }, | |
709 // Invalid media type: */* | |
710 { "HTTP/1.1 200 OK\n" | |
711 "Content-type: */*\n", | |
712 "", false, | |
713 "", false, | |
714 "*/*" }, | |
715 }; | 581 }; |
716 | 582 |
717 for (size_t i = 0; i < arraysize(tests); ++i) { | 583 for (size_t i = 0; i < arraysize(tests); ++i) { |
718 std::string headers(tests[i].raw_headers); | 584 std::string headers(tests[i].raw_headers); |
719 HeadersToRaw(&headers); | 585 HeadersToRaw(&headers); |
720 scoped_refptr<net::HttpResponseHeaders> parsed( | 586 scoped_refptr<net::HttpResponseHeaders> parsed( |
721 new net::HttpResponseHeaders(headers)); | 587 new net::HttpResponseHeaders(headers)); |
722 | 588 |
723 std::string value; | 589 std::string value; |
724 EXPECT_EQ(tests[i].has_mimetype, parsed->GetMimeType(&value)); | 590 EXPECT_EQ(tests[i].has_mimetype, parsed->GetMimeType(&value)); |
725 EXPECT_EQ(tests[i].mime_type, value); | 591 EXPECT_EQ(tests[i].mime_type, value); |
726 value.clear(); | 592 value.clear(); |
727 EXPECT_EQ(tests[i].has_charset, parsed->GetCharset(&value)); | 593 EXPECT_EQ(tests[i].has_charset, parsed->GetCharset(&value)); |
728 EXPECT_EQ(tests[i].charset, value); | 594 EXPECT_EQ(tests[i].charset, value); |
729 EXPECT_TRUE(parsed->GetNormalizedHeader("content-type", &value)); | 595 EXPECT_TRUE(parsed->GetNormalizedHeader("content-type", &value)); |
730 EXPECT_EQ(tests[i].all_content_type, value); | 596 EXPECT_EQ(tests[i].all_content_type, value); |
731 } | 597 } |
732 } | 598 } |
733 | 599 |
734 TEST(HttpResponseHeadersTest, RequiresValidation) { | 600 TEST(HttpResponseHeadersTest, RequiresValidation) { |
735 const struct { | 601 const struct { |
736 const char* headers; | 602 const char* headers; |
737 bool requires_validation; | 603 bool requires_validation; |
738 } tests[] = { | 604 } tests[] = { |
739 // no expiry info: expires immediately | 605 // no expiry info: expires immediately |
740 { "HTTP/1.1 200 OK\n" | 606 {"HTTP/1.1 200 OK\n" |
741 "\n", | 607 "\n", |
742 true | 608 true}, |
743 }, | 609 // valid for a little while |
744 // valid for a little while | 610 {"HTTP/1.1 200 OK\n" |
745 { "HTTP/1.1 200 OK\n" | 611 "cache-control: max-age=10000\n" |
746 "cache-control: max-age=10000\n" | 612 "\n", |
747 "\n", | 613 false}, |
748 false | 614 // expires in the future |
749 }, | 615 {"HTTP/1.1 200 OK\n" |
750 // expires in the future | 616 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
751 { "HTTP/1.1 200 OK\n" | 617 "expires: Wed, 28 Nov 2007 01:00:00 GMT\n" |
752 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 618 "\n", |
753 "expires: Wed, 28 Nov 2007 01:00:00 GMT\n" | 619 false}, |
754 "\n", | 620 // expired already |
755 false | 621 {"HTTP/1.1 200 OK\n" |
756 }, | 622 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
757 // expired already | 623 "expires: Wed, 28 Nov 2007 00:00:00 GMT\n" |
758 { "HTTP/1.1 200 OK\n" | 624 "\n", |
759 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 625 true}, |
760 "expires: Wed, 28 Nov 2007 00:00:00 GMT\n" | 626 // max-age trumps expires |
761 "\n", | 627 {"HTTP/1.1 200 OK\n" |
762 true | 628 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
763 }, | 629 "expires: Wed, 28 Nov 2007 00:00:00 GMT\n" |
764 // max-age trumps expires | 630 "cache-control: max-age=10000\n" |
765 { "HTTP/1.1 200 OK\n" | 631 "\n", |
766 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 632 false}, |
767 "expires: Wed, 28 Nov 2007 00:00:00 GMT\n" | 633 // last-modified heuristic: modified a while ago |
768 "cache-control: max-age=10000\n" | 634 {"HTTP/1.1 200 OK\n" |
769 "\n", | 635 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
770 false | 636 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" |
771 }, | 637 "\n", |
772 // last-modified heuristic: modified a while ago | 638 false}, |
773 { "HTTP/1.1 200 OK\n" | 639 {"HTTP/1.1 203 Non-Authoritative Information\n" |
774 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 640 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
775 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" | 641 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" |
776 "\n", | 642 "\n", |
777 false | 643 false}, |
778 }, | 644 {"HTTP/1.1 206 Partial Content\n" |
779 { "HTTP/1.1 203 Non-Authoritative Information\n" | 645 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
780 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 646 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" |
781 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" | 647 "\n", |
782 "\n", | 648 false}, |
783 false | 649 // last-modified heuristic: modified recently |
784 }, | 650 {"HTTP/1.1 200 OK\n" |
785 { "HTTP/1.1 206 Partial Content\n" | 651 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
786 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 652 "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n" |
787 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" | 653 "\n", |
788 "\n", | 654 true}, |
789 false | 655 {"HTTP/1.1 203 Non-Authoritative Information\n" |
790 }, | 656 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
791 // last-modified heuristic: modified recently | 657 "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n" |
792 { "HTTP/1.1 200 OK\n" | 658 "\n", |
793 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 659 true}, |
794 "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n" | 660 {"HTTP/1.1 206 Partial Content\n" |
795 "\n", | 661 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
796 true | 662 "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n" |
797 }, | 663 "\n", |
798 { "HTTP/1.1 203 Non-Authoritative Information\n" | 664 true}, |
799 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 665 // cached permanent redirect |
800 "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n" | 666 {"HTTP/1.1 301 Moved Permanently\n" |
801 "\n", | 667 "\n", |
802 true | 668 false}, |
803 }, | 669 // another cached permanent redirect |
804 { "HTTP/1.1 206 Partial Content\n" | 670 {"HTTP/1.1 308 Permanent Redirect\n" |
805 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 671 "\n", |
806 "last-modified: Wed, 28 Nov 2007 00:40:10 GMT\n" | 672 false}, |
807 "\n", | 673 // cached redirect: not reusable even though by default it would be |
808 true | 674 {"HTTP/1.1 300 Multiple Choices\n" |
809 }, | 675 "Cache-Control: no-cache\n" |
810 // cached permanent redirect | 676 "\n", |
811 { "HTTP/1.1 301 Moved Permanently\n" | 677 true}, |
812 "\n", | 678 // cached forever by default |
813 false | 679 {"HTTP/1.1 410 Gone\n" |
814 }, | 680 "\n", |
815 // another cached permanent redirect | 681 false}, |
816 { "HTTP/1.1 308 Permanent Redirect\n" | 682 // cached temporary redirect: not reusable |
817 "\n", | 683 {"HTTP/1.1 302 Found\n" |
818 false | 684 "\n", |
819 }, | 685 true}, |
820 // cached redirect: not reusable even though by default it would be | 686 // cached temporary redirect: reusable |
821 { "HTTP/1.1 300 Multiple Choices\n" | 687 {"HTTP/1.1 302 Found\n" |
822 "Cache-Control: no-cache\n" | 688 "cache-control: max-age=10000\n" |
823 "\n", | 689 "\n", |
824 true | 690 false}, |
825 }, | 691 // cache-control: max-age=N overrides expires: date in the past |
826 // cached forever by default | 692 {"HTTP/1.1 200 OK\n" |
827 { "HTTP/1.1 410 Gone\n" | 693 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
828 "\n", | 694 "expires: Wed, 28 Nov 2007 00:20:11 GMT\n" |
829 false | 695 "cache-control: max-age=10000\n" |
830 }, | 696 "\n", |
831 // cached temporary redirect: not reusable | 697 false}, |
832 { "HTTP/1.1 302 Found\n" | 698 // cache-control: no-store overrides expires: in the future |
833 "\n", | 699 {"HTTP/1.1 200 OK\n" |
834 true | 700 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
835 }, | 701 "expires: Wed, 29 Nov 2007 00:40:11 GMT\n" |
836 // cached temporary redirect: reusable | 702 "cache-control: no-store,private,no-cache=\"foo\"\n" |
837 { "HTTP/1.1 302 Found\n" | 703 "\n", |
838 "cache-control: max-age=10000\n" | 704 true}, |
839 "\n", | 705 // pragma: no-cache overrides last-modified heuristic |
840 false | 706 {"HTTP/1.1 200 OK\n" |
841 }, | 707 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" |
842 // cache-control: max-age=N overrides expires: date in the past | 708 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" |
843 { "HTTP/1.1 200 OK\n" | 709 "pragma: no-cache\n" |
844 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | 710 "\n", |
845 "expires: Wed, 28 Nov 2007 00:20:11 GMT\n" | 711 true}, |
846 "cache-control: max-age=10000\n" | 712 // TODO(darin): add many many more tests here |
847 "\n", | 713 }; |
848 false | |
849 }, | |
850 // cache-control: no-store overrides expires: in the future | |
851 { "HTTP/1.1 200 OK\n" | |
852 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | |
853 "expires: Wed, 29 Nov 2007 00:40:11 GMT\n" | |
854 "cache-control: no-store,private,no-cache=\"foo\"\n" | |
855 "\n", | |
856 true | |
857 }, | |
858 // pragma: no-cache overrides last-modified heuristic | |
859 { "HTTP/1.1 200 OK\n" | |
860 "date: Wed, 28 Nov 2007 00:40:11 GMT\n" | |
861 "last-modified: Wed, 27 Nov 2007 08:00:00 GMT\n" | |
862 "pragma: no-cache\n" | |
863 "\n", | |
864 true | |
865 }, | |
866 // TODO(darin): add many many more tests here | |
867 }; | |
868 base::Time request_time, response_time, current_time; | 714 base::Time request_time, response_time, current_time; |
869 base::Time::FromString("Wed, 28 Nov 2007 00:40:09 GMT", &request_time); | 715 base::Time::FromString("Wed, 28 Nov 2007 00:40:09 GMT", &request_time); |
870 base::Time::FromString("Wed, 28 Nov 2007 00:40:12 GMT", &response_time); | 716 base::Time::FromString("Wed, 28 Nov 2007 00:40:12 GMT", &response_time); |
871 base::Time::FromString("Wed, 28 Nov 2007 00:45:20 GMT", ¤t_time); | 717 base::Time::FromString("Wed, 28 Nov 2007 00:45:20 GMT", ¤t_time); |
872 | 718 |
873 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 719 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
874 std::string headers(tests[i].headers); | 720 std::string headers(tests[i].headers); |
875 HeadersToRaw(&headers); | 721 HeadersToRaw(&headers); |
876 scoped_refptr<net::HttpResponseHeaders> parsed( | 722 scoped_refptr<net::HttpResponseHeaders> parsed( |
877 new net::HttpResponseHeaders(headers)); | 723 new net::HttpResponseHeaders(headers)); |
878 | 724 |
879 bool requires_validation = | 725 bool requires_validation = |
880 parsed->RequiresValidation(request_time, response_time, current_time); | 726 parsed->RequiresValidation(request_time, response_time, current_time); |
881 EXPECT_EQ(tests[i].requires_validation, requires_validation); | 727 EXPECT_EQ(tests[i].requires_validation, requires_validation); |
882 } | 728 } |
883 } | 729 } |
884 | 730 |
885 TEST(HttpResponseHeadersTest, Update) { | 731 TEST(HttpResponseHeadersTest, Update) { |
886 const struct { | 732 const struct { |
887 const char* orig_headers; | 733 const char* orig_headers; |
888 const char* new_headers; | 734 const char* new_headers; |
889 const char* expected_headers; | 735 const char* expected_headers; |
890 } tests[] = { | 736 } tests[] = { |
891 { "HTTP/1.1 200 OK\n", | 737 {"HTTP/1.1 200 OK\n", |
892 | 738 "HTTP/1/1 304 Not Modified\n" |
893 "HTTP/1/1 304 Not Modified\n" | 739 "connection: keep-alive\n" |
894 "connection: keep-alive\n" | 740 "Cache-control: max-age=10000\n", |
895 "Cache-control: max-age=10000\n", | 741 "HTTP/1.1 200 OK\n" |
896 | 742 "Cache-control: max-age=10000\n"}, |
897 "HTTP/1.1 200 OK\n" | 743 {"HTTP/1.1 200 OK\n" |
898 "Cache-control: max-age=10000\n" | 744 "Foo: 1\n" |
899 }, | 745 "Cache-control: private\n", |
900 { "HTTP/1.1 200 OK\n" | 746 "HTTP/1/1 304 Not Modified\n" |
901 "Foo: 1\n" | 747 "connection: keep-alive\n" |
902 "Cache-control: private\n", | 748 "Cache-control: max-age=10000\n", |
903 | 749 "HTTP/1.1 200 OK\n" |
904 "HTTP/1/1 304 Not Modified\n" | 750 "Cache-control: max-age=10000\n" |
905 "connection: keep-alive\n" | 751 "Foo: 1\n"}, |
906 "Cache-control: max-age=10000\n", | 752 {"HTTP/1.1 200 OK\n" |
907 | 753 "Foo: 1\n" |
908 "HTTP/1.1 200 OK\n" | 754 "Cache-control: private\n", |
909 "Cache-control: max-age=10000\n" | 755 "HTTP/1/1 304 Not Modified\n" |
910 "Foo: 1\n" | 756 "connection: keep-alive\n" |
911 }, | 757 "Cache-CONTROL: max-age=10000\n", |
912 { "HTTP/1.1 200 OK\n" | 758 "HTTP/1.1 200 OK\n" |
913 "Foo: 1\n" | 759 "Cache-CONTROL: max-age=10000\n" |
914 "Cache-control: private\n", | 760 "Foo: 1\n"}, |
915 | 761 {"HTTP/1.1 200 OK\n" |
916 "HTTP/1/1 304 Not Modified\n" | 762 "Content-Length: 450\n", |
917 "connection: keep-alive\n" | 763 "HTTP/1/1 304 Not Modified\n" |
918 "Cache-CONTROL: max-age=10000\n", | 764 "connection: keep-alive\n" |
919 | 765 "Cache-control: max-age=10001 \n", |
920 "HTTP/1.1 200 OK\n" | 766 "HTTP/1.1 200 OK\n" |
921 "Cache-CONTROL: max-age=10000\n" | 767 "Cache-control: max-age=10001\n" |
922 "Foo: 1\n" | 768 "Content-Length: 450\n"}, |
923 }, | 769 { |
924 { "HTTP/1.1 200 OK\n" | 770 "HTTP/1.1 200 OK\n" |
925 "Content-Length: 450\n", | 771 "X-Frame-Options: DENY\n", |
926 | 772 "HTTP/1/1 304 Not Modified\n" |
927 "HTTP/1/1 304 Not Modified\n" | 773 "X-Frame-Options: ALLOW\n", |
928 "connection: keep-alive\n" | 774 "HTTP/1.1 200 OK\n" |
929 "Cache-control: max-age=10001 \n", | 775 "X-Frame-Options: DENY\n", |
930 | 776 }, |
931 "HTTP/1.1 200 OK\n" | 777 { |
932 "Cache-control: max-age=10001\n" | 778 "HTTP/1.1 200 OK\n" |
933 "Content-Length: 450\n" | 779 "X-WebKit-CSP: default-src 'none'\n", |
934 }, | 780 "HTTP/1/1 304 Not Modified\n" |
935 { "HTTP/1.1 200 OK\n" | 781 "X-WebKit-CSP: default-src *\n", |
936 "X-Frame-Options: DENY\n", | 782 "HTTP/1.1 200 OK\n" |
937 | 783 "X-WebKit-CSP: default-src 'none'\n", |
938 "HTTP/1/1 304 Not Modified\n" | 784 }, |
939 "X-Frame-Options: ALLOW\n", | 785 { |
940 | 786 "HTTP/1.1 200 OK\n" |
941 "HTTP/1.1 200 OK\n" | 787 "X-XSS-Protection: 1\n", |
942 "X-Frame-Options: DENY\n", | 788 "HTTP/1/1 304 Not Modified\n" |
943 }, | 789 "X-XSS-Protection: 0\n", |
944 { "HTTP/1.1 200 OK\n" | 790 "HTTP/1.1 200 OK\n" |
945 "X-WebKit-CSP: default-src 'none'\n", | 791 "X-XSS-Protection: 1\n", |
946 | 792 }, |
947 "HTTP/1/1 304 Not Modified\n" | 793 {"HTTP/1.1 200 OK\n", |
948 "X-WebKit-CSP: default-src *\n", | 794 "HTTP/1/1 304 Not Modified\n" |
949 | 795 "X-Content-Type-Options: nosniff\n", |
950 "HTTP/1.1 200 OK\n" | 796 "HTTP/1.1 200 OK\n"}, |
951 "X-WebKit-CSP: default-src 'none'\n", | 797 }; |
952 }, | |
953 { "HTTP/1.1 200 OK\n" | |
954 "X-XSS-Protection: 1\n", | |
955 | |
956 "HTTP/1/1 304 Not Modified\n" | |
957 "X-XSS-Protection: 0\n", | |
958 | |
959 "HTTP/1.1 200 OK\n" | |
960 "X-XSS-Protection: 1\n", | |
961 }, | |
962 { "HTTP/1.1 200 OK\n", | |
963 | |
964 "HTTP/1/1 304 Not Modified\n" | |
965 "X-Content-Type-Options: nosniff\n", | |
966 | |
967 "HTTP/1.1 200 OK\n" | |
968 }, | |
969 }; | |
970 | 798 |
971 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 799 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
972 std::string orig_headers(tests[i].orig_headers); | 800 std::string orig_headers(tests[i].orig_headers); |
973 HeadersToRaw(&orig_headers); | 801 HeadersToRaw(&orig_headers); |
974 scoped_refptr<net::HttpResponseHeaders> parsed( | 802 scoped_refptr<net::HttpResponseHeaders> parsed( |
975 new net::HttpResponseHeaders(orig_headers)); | 803 new net::HttpResponseHeaders(orig_headers)); |
976 | 804 |
977 std::string new_headers(tests[i].new_headers); | 805 std::string new_headers(tests[i].new_headers); |
978 HeadersToRaw(&new_headers); | 806 HeadersToRaw(&new_headers); |
979 scoped_refptr<net::HttpResponseHeaders> new_parsed( | 807 scoped_refptr<net::HttpResponseHeaders> new_parsed( |
980 new net::HttpResponseHeaders(new_headers)); | 808 new net::HttpResponseHeaders(new_headers)); |
981 | 809 |
982 parsed->Update(*new_parsed.get()); | 810 parsed->Update(*new_parsed.get()); |
983 | 811 |
984 std::string resulting_headers; | 812 std::string resulting_headers; |
985 parsed->GetNormalizedHeaders(&resulting_headers); | 813 parsed->GetNormalizedHeaders(&resulting_headers); |
986 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); | 814 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); |
987 } | 815 } |
988 } | 816 } |
989 | 817 |
990 TEST(HttpResponseHeadersTest, EnumerateHeaderLines) { | 818 TEST(HttpResponseHeadersTest, EnumerateHeaderLines) { |
991 const struct { | 819 const struct { |
992 const char* headers; | 820 const char* headers; |
993 const char* expected_lines; | 821 const char* expected_lines; |
994 } tests[] = { | 822 } tests[] = { |
995 { "HTTP/1.1 200 OK\n", | 823 {"HTTP/1.1 200 OK\n", ""}, |
996 | 824 {"HTTP/1.1 200 OK\n" |
997 "" | 825 "Foo: 1\n", |
998 }, | 826 "Foo: 1\n"}, |
999 { "HTTP/1.1 200 OK\n" | 827 {"HTTP/1.1 200 OK\n" |
1000 "Foo: 1\n", | 828 "Foo: 1\n" |
1001 | 829 "Bar: 2\n" |
1002 "Foo: 1\n" | 830 "Foo: 3\n", |
1003 }, | 831 "Foo: 1\nBar: 2\nFoo: 3\n"}, |
1004 { "HTTP/1.1 200 OK\n" | 832 {"HTTP/1.1 200 OK\n" |
1005 "Foo: 1\n" | 833 "Foo: 1, 2, 3\n", |
1006 "Bar: 2\n" | 834 "Foo: 1, 2, 3\n"}, |
1007 "Foo: 3\n", | 835 }; |
1008 | |
1009 "Foo: 1\nBar: 2\nFoo: 3\n" | |
1010 }, | |
1011 { "HTTP/1.1 200 OK\n" | |
1012 "Foo: 1, 2, 3\n", | |
1013 | |
1014 "Foo: 1, 2, 3\n" | |
1015 }, | |
1016 }; | |
1017 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 836 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1018 std::string headers(tests[i].headers); | 837 std::string headers(tests[i].headers); |
1019 HeadersToRaw(&headers); | 838 HeadersToRaw(&headers); |
1020 scoped_refptr<net::HttpResponseHeaders> parsed( | 839 scoped_refptr<net::HttpResponseHeaders> parsed( |
1021 new net::HttpResponseHeaders(headers)); | 840 new net::HttpResponseHeaders(headers)); |
1022 | 841 |
1023 std::string name, value, lines; | 842 std::string name, value, lines; |
1024 | 843 |
1025 void* iter = NULL; | 844 void* iter = NULL; |
1026 while (parsed->EnumerateHeaderLines(&iter, &name, &value)) { | 845 while (parsed->EnumerateHeaderLines(&iter, &name, &value)) { |
1027 lines.append(name); | 846 lines.append(name); |
1028 lines.append(": "); | 847 lines.append(": "); |
1029 lines.append(value); | 848 lines.append(value); |
1030 lines.append("\n"); | 849 lines.append("\n"); |
1031 } | 850 } |
1032 | 851 |
1033 EXPECT_EQ(std::string(tests[i].expected_lines), lines); | 852 EXPECT_EQ(std::string(tests[i].expected_lines), lines); |
1034 } | 853 } |
1035 } | 854 } |
1036 | 855 |
1037 TEST(HttpResponseHeadersTest, IsRedirect) { | 856 TEST(HttpResponseHeadersTest, IsRedirect) { |
1038 const struct { | 857 const struct { |
1039 const char* headers; | 858 const char* headers; |
1040 const char* location; | 859 const char* location; |
1041 bool is_redirect; | 860 bool is_redirect; |
1042 } tests[] = { | 861 } tests[] = { |
1043 { "HTTP/1.1 200 OK\n", | 862 {"HTTP/1.1 200 OK\n", "", false}, |
1044 "", | 863 {"HTTP/1.1 301 Moved\n" |
1045 false | 864 "Location: http://foopy/\n", |
1046 }, | 865 "http://foopy/", true}, |
1047 { "HTTP/1.1 301 Moved\n" | 866 {"HTTP/1.1 301 Moved\n" |
1048 "Location: http://foopy/\n", | 867 "Location: \t \n", |
1049 "http://foopy/", | 868 "", false}, |
1050 true | 869 // we use the first location header as the target of the redirect |
1051 }, | 870 {"HTTP/1.1 301 Moved\n" |
1052 { "HTTP/1.1 301 Moved\n" | 871 "Location: http://foo/\n" |
1053 "Location: \t \n", | 872 "Location: http://bar/\n", |
1054 "", | 873 "http://foo/", true}, |
1055 false | 874 // we use the first _valid_ location header as the target of the |
1056 }, | 875 // redirect |
1057 // we use the first location header as the target of the redirect | 876 {"HTTP/1.1 301 Moved\n" |
1058 { "HTTP/1.1 301 Moved\n" | 877 "Location: \n" |
1059 "Location: http://foo/\n" | 878 "Location: http://bar/\n", |
1060 "Location: http://bar/\n", | 879 "http://bar/", true}, |
1061 "http://foo/", | 880 // bug 1050541 (location header w/ an unescaped comma) |
1062 true | 881 {"HTTP/1.1 301 Moved\n" |
1063 }, | 882 "Location: http://foo/bar,baz.html\n", |
1064 // we use the first _valid_ location header as the target of the redirect | 883 "http://foo/bar,baz.html", true}, |
1065 { "HTTP/1.1 301 Moved\n" | 884 // bug 1224617 (location header w/ non-ASCII bytes) |
1066 "Location: \n" | 885 {"HTTP/1.1 301 Moved\n" |
1067 "Location: http://bar/\n", | 886 "Location: http://foo/bar?key=\xE4\xF6\xFC\n", |
1068 "http://bar/", | 887 "http://foo/bar?key=%E4%F6%FC", true}, |
1069 true | 888 // Shift_JIS, Big5, and GBK contain multibyte characters with the |
1070 }, | 889 // trailing |
1071 // bug 1050541 (location header w/ an unescaped comma) | 890 // byte falling in the ASCII range. |
1072 { "HTTP/1.1 301 Moved\n" | 891 {"HTTP/1.1 301 Moved\n" |
1073 "Location: http://foo/bar,baz.html\n", | 892 "Location: http://foo/bar?key=\x81\x5E\xD8\xBF\n", |
1074 "http://foo/bar,baz.html", | 893 "http://foo/bar?key=%81^%D8%BF", true}, |
1075 true | 894 {"HTTP/1.1 301 Moved\n" |
1076 }, | 895 "Location: http://foo/bar?key=\x82\x40\xBD\xC4\n", |
1077 // bug 1224617 (location header w/ non-ASCII bytes) | 896 "http://foo/bar?key=%82@%BD%C4", true}, |
1078 { "HTTP/1.1 301 Moved\n" | 897 {"HTTP/1.1 301 Moved\n" |
1079 "Location: http://foo/bar?key=\xE4\xF6\xFC\n", | 898 "Location: http://foo/bar?key=\x83\x5C\x82\x5D\xCB\xD7\n", |
1080 "http://foo/bar?key=%E4%F6%FC", | 899 "http://foo/bar?key=%83\\%82]%CB%D7", true}, |
1081 true | 900 }; |
1082 }, | |
1083 // Shift_JIS, Big5, and GBK contain multibyte characters with the trailing | |
1084 // byte falling in the ASCII range. | |
1085 { "HTTP/1.1 301 Moved\n" | |
1086 "Location: http://foo/bar?key=\x81\x5E\xD8\xBF\n", | |
1087 "http://foo/bar?key=%81^%D8%BF", | |
1088 true | |
1089 }, | |
1090 { "HTTP/1.1 301 Moved\n" | |
1091 "Location: http://foo/bar?key=\x82\x40\xBD\xC4\n", | |
1092 "http://foo/bar?key=%82@%BD%C4", | |
1093 true | |
1094 }, | |
1095 { "HTTP/1.1 301 Moved\n" | |
1096 "Location: http://foo/bar?key=\x83\x5C\x82\x5D\xCB\xD7\n", | |
1097 "http://foo/bar?key=%83\\%82]%CB%D7", | |
1098 true | |
1099 }, | |
1100 }; | |
1101 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 901 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1102 std::string headers(tests[i].headers); | 902 std::string headers(tests[i].headers); |
1103 HeadersToRaw(&headers); | 903 HeadersToRaw(&headers); |
1104 scoped_refptr<net::HttpResponseHeaders> parsed( | 904 scoped_refptr<net::HttpResponseHeaders> parsed( |
1105 new net::HttpResponseHeaders(headers)); | 905 new net::HttpResponseHeaders(headers)); |
1106 | 906 |
1107 std::string location; | 907 std::string location; |
1108 EXPECT_EQ(parsed->IsRedirect(&location), tests[i].is_redirect); | 908 EXPECT_EQ(parsed->IsRedirect(&location), tests[i].is_redirect); |
1109 EXPECT_EQ(location, tests[i].location); | 909 EXPECT_EQ(location, tests[i].location); |
1110 } | 910 } |
1111 } | 911 } |
1112 | 912 |
1113 TEST(HttpResponseHeadersTest, GetContentLength) { | 913 TEST(HttpResponseHeadersTest, GetContentLength) { |
1114 const struct { | 914 const struct { |
1115 const char* headers; | 915 const char* headers; |
1116 int64 expected_len; | 916 int64 expected_len; |
1117 } tests[] = { | 917 } tests[] = { |
1118 { "HTTP/1.1 200 OK\n", | 918 {"HTTP/1.1 200 OK\n", -1}, |
1119 -1 | 919 {"HTTP/1.1 200 OK\n" |
1120 }, | 920 "Content-Length: 10\n", |
1121 { "HTTP/1.1 200 OK\n" | 921 10}, |
1122 "Content-Length: 10\n", | 922 {"HTTP/1.1 200 OK\n" |
1123 10 | 923 "Content-Length: \n", |
1124 }, | 924 -1}, |
1125 { "HTTP/1.1 200 OK\n" | 925 {"HTTP/1.1 200 OK\n" |
1126 "Content-Length: \n", | 926 "Content-Length: abc\n", |
1127 -1 | 927 -1}, |
1128 }, | 928 {"HTTP/1.1 200 OK\n" |
1129 { "HTTP/1.1 200 OK\n" | 929 "Content-Length: -10\n", |
1130 "Content-Length: abc\n", | 930 -1}, |
1131 -1 | 931 {"HTTP/1.1 200 OK\n" |
1132 }, | 932 "Content-Length: +10\n", |
1133 { "HTTP/1.1 200 OK\n" | 933 -1}, |
1134 "Content-Length: -10\n", | 934 {"HTTP/1.1 200 OK\n" |
1135 -1 | 935 "Content-Length: 23xb5\n", |
1136 }, | 936 -1}, |
1137 { "HTTP/1.1 200 OK\n" | 937 {"HTTP/1.1 200 OK\n" |
1138 "Content-Length: +10\n", | 938 "Content-Length: 0xA\n", |
1139 -1 | 939 -1}, |
1140 }, | 940 {"HTTP/1.1 200 OK\n" |
1141 { "HTTP/1.1 200 OK\n" | 941 "Content-Length: 010\n", |
1142 "Content-Length: 23xb5\n", | 942 10}, |
1143 -1 | 943 // Content-Length too big, will overflow an int64 |
1144 }, | 944 {"HTTP/1.1 200 OK\n" |
1145 { "HTTP/1.1 200 OK\n" | 945 "Content-Length: 40000000000000000000\n", |
1146 "Content-Length: 0xA\n", | 946 -1}, |
1147 -1 | 947 {"HTTP/1.1 200 OK\n" |
1148 }, | 948 "Content-Length: 10\n", |
1149 { "HTTP/1.1 200 OK\n" | 949 10}, |
1150 "Content-Length: 010\n", | 950 {"HTTP/1.1 200 OK\n" |
1151 10 | 951 "Content-Length: 10 \n", |
1152 }, | 952 10}, |
1153 // Content-Length too big, will overflow an int64 | 953 {"HTTP/1.1 200 OK\n" |
1154 { "HTTP/1.1 200 OK\n" | 954 "Content-Length: \t10\n", |
1155 "Content-Length: 40000000000000000000\n", | 955 10}, |
1156 -1 | 956 {"HTTP/1.1 200 OK\n" |
1157 }, | 957 "Content-Length: \v10\n", |
1158 { "HTTP/1.1 200 OK\n" | 958 -1}, |
1159 "Content-Length: 10\n", | 959 {"HTTP/1.1 200 OK\n" |
1160 10 | 960 "Content-Length: \f10\n", |
1161 }, | 961 -1}, |
1162 { "HTTP/1.1 200 OK\n" | 962 {"HTTP/1.1 200 OK\n" |
1163 "Content-Length: 10 \n", | 963 "cOnTeNt-LENgth: 33\n", |
1164 10 | 964 33}, |
1165 }, | 965 {"HTTP/1.1 200 OK\n" |
1166 { "HTTP/1.1 200 OK\n" | 966 "Content-Length: 34\r\n", |
1167 "Content-Length: \t10\n", | 967 -1}, |
1168 10 | 968 }; |
1169 }, | |
1170 { "HTTP/1.1 200 OK\n" | |
1171 "Content-Length: \v10\n", | |
1172 -1 | |
1173 }, | |
1174 { "HTTP/1.1 200 OK\n" | |
1175 "Content-Length: \f10\n", | |
1176 -1 | |
1177 }, | |
1178 { "HTTP/1.1 200 OK\n" | |
1179 "cOnTeNt-LENgth: 33\n", | |
1180 33 | |
1181 }, | |
1182 { "HTTP/1.1 200 OK\n" | |
1183 "Content-Length: 34\r\n", | |
1184 -1 | |
1185 }, | |
1186 }; | |
1187 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 969 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1188 std::string headers(tests[i].headers); | 970 std::string headers(tests[i].headers); |
1189 HeadersToRaw(&headers); | 971 HeadersToRaw(&headers); |
1190 scoped_refptr<net::HttpResponseHeaders> parsed( | 972 scoped_refptr<net::HttpResponseHeaders> parsed( |
1191 new net::HttpResponseHeaders(headers)); | 973 new net::HttpResponseHeaders(headers)); |
1192 | 974 |
1193 EXPECT_EQ(tests[i].expected_len, parsed->GetContentLength()); | 975 EXPECT_EQ(tests[i].expected_len, parsed->GetContentLength()); |
1194 } | 976 } |
1195 } | 977 } |
1196 | 978 |
1197 TEST(HttpResponseHeaders, GetContentRange) { | 979 TEST(HttpResponseHeaders, GetContentRange) { |
1198 const struct { | 980 const struct { |
1199 const char* headers; | 981 const char* headers; |
1200 bool expected_return_value; | 982 bool expected_return_value; |
1201 int64 expected_first_byte_position; | 983 int64 expected_first_byte_position; |
1202 int64 expected_last_byte_position; | 984 int64 expected_last_byte_position; |
1203 int64 expected_instance_size; | 985 int64 expected_instance_size; |
1204 } tests[] = { | 986 } tests[] = { |
1205 { "HTTP/1.1 206 Partial Content", | 987 {"HTTP/1.1 206 Partial Content", false, -1, -1, -1}, |
1206 false, | 988 {"HTTP/1.1 206 Partial Content\n" |
1207 -1, | 989 "Content-Range:", |
1208 -1, | 990 false, -1, -1, -1}, |
1209 -1 | 991 {"HTTP/1.1 206 Partial Content\n" |
1210 }, | 992 "Content-Range: megabytes 0-10/50", |
1211 { "HTTP/1.1 206 Partial Content\n" | 993 false, -1, -1, -1}, |
1212 "Content-Range:", | 994 {"HTTP/1.1 206 Partial Content\n" |
1213 false, | 995 "Content-Range: 0-10/50", |
1214 -1, | 996 false, -1, -1, -1}, |
1215 -1, | 997 {"HTTP/1.1 206 Partial Content\n" |
1216 -1 | 998 "Content-Range: Bytes 0-50/51", |
1217 }, | 999 true, 0, 50, 51}, |
1218 { "HTTP/1.1 206 Partial Content\n" | 1000 {"HTTP/1.1 206 Partial Content\n" |
1219 "Content-Range: megabytes 0-10/50", | 1001 "Content-Range: bytes 0-50/51", |
1220 false, | 1002 true, 0, 50, 51}, |
1221 -1, | 1003 {"HTTP/1.1 206 Partial Content\n" |
1222 -1, | 1004 "Content-Range: bytes\t0-50/51", |
1223 -1 | 1005 false, -1, -1, -1}, |
1224 }, | 1006 {"HTTP/1.1 206 Partial Content\n" |
1225 { "HTTP/1.1 206 Partial Content\n" | 1007 "Content-Range: bytes 0-50/51", |
1226 "Content-Range: 0-10/50", | 1008 true, 0, 50, 51}, |
1227 false, | 1009 {"HTTP/1.1 206 Partial Content\n" |
1228 -1, | 1010 "Content-Range: bytes 0 - 50 \t / \t51", |
1229 -1, | 1011 true, 0, 50, 51}, |
1230 -1 | 1012 {"HTTP/1.1 206 Partial Content\n" |
1231 }, | 1013 "Content-Range: bytes 0\t-\t50\t/\t51\t", |
1232 { "HTTP/1.1 206 Partial Content\n" | 1014 true, 0, 50, 51}, |
1233 "Content-Range: Bytes 0-50/51", | 1015 {"HTTP/1.1 206 Partial Content\n" |
1234 true, | 1016 "Content-Range: \tbytes\t\t\t 0\t-\t50\t/\t51\t", |
1235 0, | 1017 true, 0, 50, 51}, |
1236 50, | 1018 {"HTTP/1.1 206 Partial Content\n" |
1237 51 | 1019 "Content-Range: \t bytes \t 0 - 50 / 5 1", |
1238 }, | 1020 false, 0, 50, -1}, |
1239 { "HTTP/1.1 206 Partial Content\n" | 1021 {"HTTP/1.1 206 Partial Content\n" |
1240 "Content-Range: bytes 0-50/51", | 1022 "Content-Range: \t bytes \t 0 - 5 0 / 51", |
1241 true, | 1023 false, -1, -1, -1}, |
1242 0, | 1024 {"HTTP/1.1 206 Partial Content\n" |
1243 50, | 1025 "Content-Range: bytes 50-0/51", |
1244 51 | 1026 false, 50, 0, -1}, |
1245 }, | 1027 {"HTTP/1.1 416 Requested range not satisfiable\n" |
1246 { "HTTP/1.1 206 Partial Content\n" | 1028 "Content-Range: bytes * /*", |
1247 "Content-Range: bytes\t0-50/51", | 1029 false, -1, -1, -1}, |
1248 false, | 1030 {"HTTP/1.1 416 Requested range not satisfiable\n" |
1249 -1, | 1031 "Content-Range: bytes * / * ", |
1250 -1, | 1032 false, -1, -1, -1}, |
1251 -1 | 1033 {"HTTP/1.1 206 Partial Content\n" |
1252 }, | 1034 "Content-Range: bytes 0-50/*", |
1253 { "HTTP/1.1 206 Partial Content\n" | 1035 false, 0, 50, -1}, |
1254 "Content-Range: bytes 0-50/51", | 1036 {"HTTP/1.1 206 Partial Content\n" |
1255 true, | 1037 "Content-Range: bytes 0-50 / * ", |
1256 0, | 1038 false, 0, 50, -1}, |
1257 50, | 1039 {"HTTP/1.1 206 Partial Content\n" |
1258 51 | 1040 "Content-Range: bytes 0-10000000000/10000000001", |
1259 }, | 1041 true, 0, 10000000000ll, 10000000001ll}, |
1260 { "HTTP/1.1 206 Partial Content\n" | 1042 {"HTTP/1.1 206 Partial Content\n" |
1261 "Content-Range: bytes 0 - 50 \t / \t51", | 1043 "Content-Range: bytes 0-10000000000/10000000000", |
1262 true, | 1044 false, 0, 10000000000ll, 10000000000ll}, |
1263 0, | 1045 // 64 bits wraparound. |
1264 50, | 1046 {"HTTP/1.1 206 Partial Content\n" |
1265 51 | 1047 "Content-Range: bytes 0 - 9223372036854775807 / 100", |
1266 }, | 1048 false, 0, kint64max, 100}, |
1267 { "HTTP/1.1 206 Partial Content\n" | 1049 // 64 bits wraparound. |
1268 "Content-Range: bytes 0\t-\t50\t/\t51\t", | 1050 {"HTTP/1.1 206 Partial Content\n" |
1269 true, | 1051 "Content-Range: bytes 0 - 100 / -9223372036854775808", |
1270 0, | 1052 false, 0, 100, kint64min}, |
1271 50, | 1053 {"HTTP/1.1 206 Partial Content\n" |
1272 51 | 1054 "Content-Range: bytes */50", |
1273 }, | 1055 false, -1, -1, 50}, |
1274 { "HTTP/1.1 206 Partial Content\n" | 1056 {"HTTP/1.1 206 Partial Content\n" |
1275 "Content-Range: \tbytes\t\t\t 0\t-\t50\t/\t51\t", | 1057 "Content-Range: bytes 0-50/10", |
1276 true, | 1058 false, 0, 50, 10}, |
1277 0, | 1059 {"HTTP/1.1 206 Partial Content\n" |
1278 50, | 1060 "Content-Range: bytes 40-50/45", |
1279 51 | 1061 false, 40, 50, 45}, |
1280 }, | 1062 {"HTTP/1.1 206 Partial Content\n" |
1281 { "HTTP/1.1 206 Partial Content\n" | 1063 "Content-Range: bytes 0-50/-10", |
1282 "Content-Range: \t bytes \t 0 - 50 / 5 1", | 1064 false, 0, 50, -10}, |
1283 false, | 1065 {"HTTP/1.1 206 Partial Content\n" |
1284 0, | 1066 "Content-Range: bytes 0-0/1", |
1285 50, | 1067 true, 0, 0, 1}, |
1286 -1 | 1068 {"HTTP/1.1 206 Partial Content\n" |
1287 }, | 1069 "Content-Range: bytes 0-40000000000000000000/40000000000000000001", |
1288 { "HTTP/1.1 206 Partial Content\n" | 1070 false, -1, -1, -1}, |
1289 "Content-Range: \t bytes \t 0 - 5 0 / 51", | 1071 {"HTTP/1.1 206 Partial Content\n" |
1290 false, | 1072 "Content-Range: bytes 1-/100", |
1291 -1, | 1073 false, -1, -1, -1}, |
1292 -1, | 1074 {"HTTP/1.1 206 Partial Content\n" |
1293 -1 | 1075 "Content-Range: bytes -/100", |
1294 }, | 1076 false, -1, -1, -1}, |
1295 { "HTTP/1.1 206 Partial Content\n" | 1077 {"HTTP/1.1 206 Partial Content\n" |
1296 "Content-Range: bytes 50-0/51", | 1078 "Content-Range: bytes -1/100", |
1297 false, | 1079 false, -1, -1, -1}, |
1298 50, | 1080 {"HTTP/1.1 206 Partial Content\n" |
1299 0, | 1081 "Content-Range: bytes 0-1233/*", |
1300 -1 | 1082 false, 0, 1233, -1}, |
1301 }, | 1083 {"HTTP/1.1 206 Partial Content\n" |
1302 { "HTTP/1.1 416 Requested range not satisfiable\n" | 1084 "Content-Range: bytes -123 - -1/100", |
1303 "Content-Range: bytes * /*", | 1085 false, -1, -1, -1}, |
1304 false, | 1086 }; |
1305 -1, | |
1306 -1, | |
1307 -1 | |
1308 }, | |
1309 { "HTTP/1.1 416 Requested range not satisfiable\n" | |
1310 "Content-Range: bytes * / * ", | |
1311 false, | |
1312 -1, | |
1313 -1, | |
1314 -1 | |
1315 }, | |
1316 { "HTTP/1.1 206 Partial Content\n" | |
1317 "Content-Range: bytes 0-50/*", | |
1318 false, | |
1319 0, | |
1320 50, | |
1321 -1 | |
1322 }, | |
1323 { "HTTP/1.1 206 Partial Content\n" | |
1324 "Content-Range: bytes 0-50 / * ", | |
1325 false, | |
1326 0, | |
1327 50, | |
1328 -1 | |
1329 }, | |
1330 { "HTTP/1.1 206 Partial Content\n" | |
1331 "Content-Range: bytes 0-10000000000/10000000001", | |
1332 true, | |
1333 0, | |
1334 10000000000ll, | |
1335 10000000001ll | |
1336 }, | |
1337 { "HTTP/1.1 206 Partial Content\n" | |
1338 "Content-Range: bytes 0-10000000000/10000000000", | |
1339 false, | |
1340 0, | |
1341 10000000000ll, | |
1342 10000000000ll | |
1343 }, | |
1344 // 64 bits wraparound. | |
1345 { "HTTP/1.1 206 Partial Content\n" | |
1346 "Content-Range: bytes 0 - 9223372036854775807 / 100", | |
1347 false, | |
1348 0, | |
1349 kint64max, | |
1350 100 | |
1351 }, | |
1352 // 64 bits wraparound. | |
1353 { "HTTP/1.1 206 Partial Content\n" | |
1354 "Content-Range: bytes 0 - 100 / -9223372036854775808", | |
1355 false, | |
1356 0, | |
1357 100, | |
1358 kint64min | |
1359 }, | |
1360 { "HTTP/1.1 206 Partial Content\n" | |
1361 "Content-Range: bytes */50", | |
1362 false, | |
1363 -1, | |
1364 -1, | |
1365 50 | |
1366 }, | |
1367 { "HTTP/1.1 206 Partial Content\n" | |
1368 "Content-Range: bytes 0-50/10", | |
1369 false, | |
1370 0, | |
1371 50, | |
1372 10 | |
1373 }, | |
1374 { "HTTP/1.1 206 Partial Content\n" | |
1375 "Content-Range: bytes 40-50/45", | |
1376 false, | |
1377 40, | |
1378 50, | |
1379 45 | |
1380 }, | |
1381 { "HTTP/1.1 206 Partial Content\n" | |
1382 "Content-Range: bytes 0-50/-10", | |
1383 false, | |
1384 0, | |
1385 50, | |
1386 -10 | |
1387 }, | |
1388 { "HTTP/1.1 206 Partial Content\n" | |
1389 "Content-Range: bytes 0-0/1", | |
1390 true, | |
1391 0, | |
1392 0, | |
1393 1 | |
1394 }, | |
1395 { "HTTP/1.1 206 Partial Content\n" | |
1396 "Content-Range: bytes 0-40000000000000000000/40000000000000000001", | |
1397 false, | |
1398 -1, | |
1399 -1, | |
1400 -1 | |
1401 }, | |
1402 { "HTTP/1.1 206 Partial Content\n" | |
1403 "Content-Range: bytes 1-/100", | |
1404 false, | |
1405 -1, | |
1406 -1, | |
1407 -1 | |
1408 }, | |
1409 { "HTTP/1.1 206 Partial Content\n" | |
1410 "Content-Range: bytes -/100", | |
1411 false, | |
1412 -1, | |
1413 -1, | |
1414 -1 | |
1415 }, | |
1416 { "HTTP/1.1 206 Partial Content\n" | |
1417 "Content-Range: bytes -1/100", | |
1418 false, | |
1419 -1, | |
1420 -1, | |
1421 -1 | |
1422 }, | |
1423 { "HTTP/1.1 206 Partial Content\n" | |
1424 "Content-Range: bytes 0-1233/*", | |
1425 false, | |
1426 0, | |
1427 1233, | |
1428 -1 | |
1429 }, | |
1430 { "HTTP/1.1 206 Partial Content\n" | |
1431 "Content-Range: bytes -123 - -1/100", | |
1432 false, | |
1433 -1, | |
1434 -1, | |
1435 -1 | |
1436 }, | |
1437 }; | |
1438 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1087 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1439 std::string headers(tests[i].headers); | 1088 std::string headers(tests[i].headers); |
1440 HeadersToRaw(&headers); | 1089 HeadersToRaw(&headers); |
1441 scoped_refptr<net::HttpResponseHeaders> parsed( | 1090 scoped_refptr<net::HttpResponseHeaders> parsed( |
1442 new net::HttpResponseHeaders(headers)); | 1091 new net::HttpResponseHeaders(headers)); |
1443 | 1092 |
1444 int64 first_byte_position; | 1093 int64 first_byte_position; |
1445 int64 last_byte_position; | 1094 int64 last_byte_position; |
1446 int64 instance_size; | 1095 int64 instance_size; |
1447 bool return_value = parsed->GetContentRange(&first_byte_position, | 1096 bool return_value = parsed->GetContentRange( |
1448 &last_byte_position, | 1097 &first_byte_position, &last_byte_position, &instance_size); |
1449 &instance_size); | |
1450 EXPECT_EQ(tests[i].expected_return_value, return_value); | 1098 EXPECT_EQ(tests[i].expected_return_value, return_value); |
1451 EXPECT_EQ(tests[i].expected_first_byte_position, first_byte_position); | 1099 EXPECT_EQ(tests[i].expected_first_byte_position, first_byte_position); |
1452 EXPECT_EQ(tests[i].expected_last_byte_position, last_byte_position); | 1100 EXPECT_EQ(tests[i].expected_last_byte_position, last_byte_position); |
1453 EXPECT_EQ(tests[i].expected_instance_size, instance_size); | 1101 EXPECT_EQ(tests[i].expected_instance_size, instance_size); |
1454 } | 1102 } |
1455 } | 1103 } |
1456 | 1104 |
1457 TEST(HttpResponseHeadersTest, IsKeepAlive) { | 1105 TEST(HttpResponseHeadersTest, IsKeepAlive) { |
1458 const struct { | 1106 const struct { |
1459 const char* headers; | 1107 const char* headers; |
1460 bool expected_keep_alive; | 1108 bool expected_keep_alive; |
1461 } tests[] = { | 1109 } tests[] = {// The status line fabricated by HttpNetworkTransaction for a 0.9 |
1462 // The status line fabricated by HttpNetworkTransaction for a 0.9 response. | 1110 // response. |
1463 // Treated as 0.9. | 1111 // Treated as 0.9. |
1464 { "HTTP/0.9 200 OK", | 1112 {"HTTP/0.9 200 OK", false}, |
1465 false | 1113 // This could come from a broken server. Treated as 1.0 because |
1466 }, | 1114 // it has a |
1467 // This could come from a broken server. Treated as 1.0 because it has a | 1115 // header. |
1468 // header. | 1116 {"HTTP/0.9 200 OK\n" |
1469 { "HTTP/0.9 200 OK\n" | 1117 "connection: keep-alive\n", |
1470 "connection: keep-alive\n", | 1118 true}, |
1471 true | 1119 {"HTTP/1.1 200 OK\n", true}, |
1472 }, | 1120 {"HTTP/1.0 200 OK\n", false}, |
1473 { "HTTP/1.1 200 OK\n", | 1121 {"HTTP/1.0 200 OK\n" |
1474 true | 1122 "connection: close\n", |
1475 }, | 1123 false}, |
1476 { "HTTP/1.0 200 OK\n", | 1124 {"HTTP/1.0 200 OK\n" |
1477 false | 1125 "connection: keep-alive\n", |
1478 }, | 1126 true}, |
1479 { "HTTP/1.0 200 OK\n" | 1127 {"HTTP/1.0 200 OK\n" |
1480 "connection: close\n", | 1128 "connection: kEeP-AliVe\n", |
1481 false | 1129 true}, |
1482 }, | 1130 {"HTTP/1.0 200 OK\n" |
1483 { "HTTP/1.0 200 OK\n" | 1131 "connection: keep-aliveX\n", |
1484 "connection: keep-alive\n", | 1132 false}, |
1485 true | 1133 {"HTTP/1.1 200 OK\n" |
1486 }, | 1134 "connection: close\n", |
1487 { "HTTP/1.0 200 OK\n" | 1135 false}, |
1488 "connection: kEeP-AliVe\n", | 1136 {"HTTP/1.1 200 OK\n" |
1489 true | 1137 "connection: keep-alive\n", |
1490 }, | 1138 true}, |
1491 { "HTTP/1.0 200 OK\n" | 1139 {"HTTP/1.0 200 OK\n" |
1492 "connection: keep-aliveX\n", | 1140 "proxy-connection: close\n", |
1493 false | 1141 false}, |
1494 }, | 1142 {"HTTP/1.0 200 OK\n" |
1495 { "HTTP/1.1 200 OK\n" | 1143 "proxy-connection: keep-alive\n", |
1496 "connection: close\n", | 1144 true}, |
1497 false | 1145 {"HTTP/1.1 200 OK\n" |
1498 }, | 1146 "proxy-connection: close\n", |
1499 { "HTTP/1.1 200 OK\n" | 1147 false}, |
1500 "connection: keep-alive\n", | 1148 {"HTTP/1.1 200 OK\n" |
1501 true | 1149 "proxy-connection: keep-alive\n", |
1502 }, | 1150 true}, |
1503 { "HTTP/1.0 200 OK\n" | 1151 }; |
1504 "proxy-connection: close\n", | |
1505 false | |
1506 }, | |
1507 { "HTTP/1.0 200 OK\n" | |
1508 "proxy-connection: keep-alive\n", | |
1509 true | |
1510 }, | |
1511 { "HTTP/1.1 200 OK\n" | |
1512 "proxy-connection: close\n", | |
1513 false | |
1514 }, | |
1515 { "HTTP/1.1 200 OK\n" | |
1516 "proxy-connection: keep-alive\n", | |
1517 true | |
1518 }, | |
1519 }; | |
1520 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1152 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1521 std::string headers(tests[i].headers); | 1153 std::string headers(tests[i].headers); |
1522 HeadersToRaw(&headers); | 1154 HeadersToRaw(&headers); |
1523 scoped_refptr<net::HttpResponseHeaders> parsed( | 1155 scoped_refptr<net::HttpResponseHeaders> parsed( |
1524 new net::HttpResponseHeaders(headers)); | 1156 new net::HttpResponseHeaders(headers)); |
1525 | 1157 |
1526 EXPECT_EQ(tests[i].expected_keep_alive, parsed->IsKeepAlive()); | 1158 EXPECT_EQ(tests[i].expected_keep_alive, parsed->IsKeepAlive()); |
1527 } | 1159 } |
1528 } | 1160 } |
1529 | 1161 |
1530 TEST(HttpResponseHeadersTest, HasStrongValidators) { | 1162 TEST(HttpResponseHeadersTest, HasStrongValidators) { |
1531 const struct { | 1163 const struct { |
1532 const char* headers; | 1164 const char* headers; |
1533 bool expected_result; | 1165 bool expected_result; |
1534 } tests[] = { | 1166 } tests[] = {{"HTTP/0.9 200 OK", false}, |
1535 { "HTTP/0.9 200 OK", | 1167 {"HTTP/1.0 200 OK\n" |
1536 false | 1168 "Date: Wed, 28 Nov 2007 01:40:10 GMT\n" |
1537 }, | 1169 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n" |
1538 { "HTTP/1.0 200 OK\n" | 1170 "ETag: \"foo\"\n", |
1539 "Date: Wed, 28 Nov 2007 01:40:10 GMT\n" | 1171 false}, |
1540 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n" | 1172 {"HTTP/1.1 200 OK\n" |
1541 "ETag: \"foo\"\n", | 1173 "Date: Wed, 28 Nov 2007 01:40:10 GMT\n" |
1542 false | 1174 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n" |
1543 }, | 1175 "ETag: \"foo\"\n", |
1544 { "HTTP/1.1 200 OK\n" | 1176 true}, |
1545 "Date: Wed, 28 Nov 2007 01:40:10 GMT\n" | 1177 {"HTTP/1.1 200 OK\n" |
1546 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n" | 1178 "Date: Wed, 28 Nov 2007 00:41:10 GMT\n" |
1547 "ETag: \"foo\"\n", | 1179 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n", |
1548 true | 1180 true}, |
1549 }, | 1181 {"HTTP/1.1 200 OK\n" |
1550 { "HTTP/1.1 200 OK\n" | 1182 "Date: Wed, 28 Nov 2007 00:41:09 GMT\n" |
1551 "Date: Wed, 28 Nov 2007 00:41:10 GMT\n" | 1183 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n", |
1552 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n", | 1184 false}, |
1553 true | 1185 {"HTTP/1.1 200 OK\n" |
1554 }, | 1186 "ETag: \"foo\"\n", |
1555 { "HTTP/1.1 200 OK\n" | 1187 true}, |
1556 "Date: Wed, 28 Nov 2007 00:41:09 GMT\n" | 1188 // This is not really a weak etag: |
1557 "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT\n", | 1189 {"HTTP/1.1 200 OK\n" |
1558 false | 1190 "etag: \"w/foo\"\n", |
1559 }, | 1191 true}, |
1560 { "HTTP/1.1 200 OK\n" | 1192 // This is a weak etag: |
1561 "ETag: \"foo\"\n", | 1193 {"HTTP/1.1 200 OK\n" |
1562 true | 1194 "etag: w/\"foo\"\n", |
1563 }, | 1195 false}, |
1564 // This is not really a weak etag: | 1196 {"HTTP/1.1 200 OK\n" |
1565 { "HTTP/1.1 200 OK\n" | 1197 "etag: W / \"foo\"\n", |
1566 "etag: \"w/foo\"\n", | 1198 false}}; |
1567 true | |
1568 }, | |
1569 // This is a weak etag: | |
1570 { "HTTP/1.1 200 OK\n" | |
1571 "etag: w/\"foo\"\n", | |
1572 false | |
1573 }, | |
1574 { "HTTP/1.1 200 OK\n" | |
1575 "etag: W / \"foo\"\n", | |
1576 false | |
1577 } | |
1578 }; | |
1579 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1199 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1580 std::string headers(tests[i].headers); | 1200 std::string headers(tests[i].headers); |
1581 HeadersToRaw(&headers); | 1201 HeadersToRaw(&headers); |
1582 scoped_refptr<net::HttpResponseHeaders> parsed( | 1202 scoped_refptr<net::HttpResponseHeaders> parsed( |
1583 new net::HttpResponseHeaders(headers)); | 1203 new net::HttpResponseHeaders(headers)); |
1584 | 1204 |
1585 EXPECT_EQ(tests[i].expected_result, parsed->HasStrongValidators()) << | 1205 EXPECT_EQ(tests[i].expected_result, parsed->HasStrongValidators()) |
1586 "Failed test case " << i; | 1206 << "Failed test case " << i; |
1587 } | 1207 } |
1588 } | 1208 } |
1589 | 1209 |
1590 TEST(HttpResponseHeadersTest, GetStatusText) { | 1210 TEST(HttpResponseHeadersTest, GetStatusText) { |
1591 std::string headers("HTTP/1.1 404 Not Found"); | 1211 std::string headers("HTTP/1.1 404 Not Found"); |
1592 HeadersToRaw(&headers); | 1212 HeadersToRaw(&headers); |
1593 scoped_refptr<net::HttpResponseHeaders> parsed( | 1213 scoped_refptr<net::HttpResponseHeaders> parsed( |
1594 new net::HttpResponseHeaders(headers)); | 1214 new net::HttpResponseHeaders(headers)); |
1595 EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText()); | 1215 EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText()); |
1596 } | 1216 } |
1597 | 1217 |
1598 TEST(HttpResponseHeadersTest, GetStatusTextMissing) { | 1218 TEST(HttpResponseHeadersTest, GetStatusTextMissing) { |
1599 std::string headers("HTTP/1.1 404"); | 1219 std::string headers("HTTP/1.1 404"); |
1600 HeadersToRaw(&headers); | 1220 HeadersToRaw(&headers); |
1601 scoped_refptr<net::HttpResponseHeaders> parsed( | 1221 scoped_refptr<net::HttpResponseHeaders> parsed( |
1602 new net::HttpResponseHeaders(headers)); | 1222 new net::HttpResponseHeaders(headers)); |
1603 // Since the status line gets normalized, we have OK | 1223 // Since the status line gets normalized, we have OK |
1604 EXPECT_EQ(std::string("OK"), parsed->GetStatusText()); | 1224 EXPECT_EQ(std::string("OK"), parsed->GetStatusText()); |
1605 } | 1225 } |
1606 | 1226 |
1607 TEST(HttpResponseHeadersTest, GetStatusTextMultiSpace) { | 1227 TEST(HttpResponseHeadersTest, GetStatusTextMultiSpace) { |
1608 std::string headers("HTTP/1.0 404 Not Found"); | 1228 std::string headers("HTTP/1.0 404 Not Found"); |
1609 HeadersToRaw(&headers); | 1229 HeadersToRaw(&headers); |
1610 scoped_refptr<net::HttpResponseHeaders> parsed( | 1230 scoped_refptr<net::HttpResponseHeaders> parsed( |
1611 new net::HttpResponseHeaders(headers)); | 1231 new net::HttpResponseHeaders(headers)); |
1612 EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText()); | 1232 EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText()); |
1613 } | 1233 } |
1614 | 1234 |
1615 TEST(HttpResponseHeadersTest, GetStatusBadStatusLine) { | 1235 TEST(HttpResponseHeadersTest, GetStatusBadStatusLine) { |
1616 std::string headers("Foo bar."); | 1236 std::string headers("Foo bar."); |
1617 HeadersToRaw(&headers); | 1237 HeadersToRaw(&headers); |
1618 scoped_refptr<net::HttpResponseHeaders> parsed( | 1238 scoped_refptr<net::HttpResponseHeaders> parsed( |
1619 new net::HttpResponseHeaders(headers)); | 1239 new net::HttpResponseHeaders(headers)); |
1620 // The bad status line would have gotten rewritten as | 1240 // The bad status line would have gotten rewritten as |
1621 // HTTP/1.0 200 OK. | 1241 // HTTP/1.0 200 OK. |
1622 EXPECT_EQ(std::string("OK"), parsed->GetStatusText()); | 1242 EXPECT_EQ(std::string("OK"), parsed->GetStatusText()); |
1623 } | 1243 } |
1624 | 1244 |
1625 TEST(HttpResponseHeadersTest, AddHeader) { | 1245 TEST(HttpResponseHeadersTest, AddHeader) { |
1626 const struct { | 1246 const struct { |
1627 const char* orig_headers; | 1247 const char* orig_headers; |
1628 const char* new_header; | 1248 const char* new_header; |
1629 const char* expected_headers; | 1249 const char* expected_headers; |
1630 } tests[] = { | 1250 } tests[] = { |
1631 { "HTTP/1.1 200 OK\n" | 1251 {"HTTP/1.1 200 OK\n" |
1632 "connection: keep-alive\n" | 1252 "connection: keep-alive\n" |
1633 "Cache-control: max-age=10000\n", | 1253 "Cache-control: max-age=10000\n", |
1634 | 1254 "Content-Length: 450", |
1635 "Content-Length: 450", | 1255 "HTTP/1.1 200 OK\n" |
1636 | 1256 "connection: keep-alive\n" |
1637 "HTTP/1.1 200 OK\n" | 1257 "Cache-control: max-age=10000\n" |
1638 "connection: keep-alive\n" | 1258 "Content-Length: 450\n"}, |
1639 "Cache-control: max-age=10000\n" | 1259 {"HTTP/1.1 200 OK\n" |
1640 "Content-Length: 450\n" | 1260 "connection: keep-alive\n" |
1641 }, | 1261 "Cache-control: max-age=10000 \n", |
1642 { "HTTP/1.1 200 OK\n" | 1262 "Content-Length: 450 ", |
1643 "connection: keep-alive\n" | 1263 "HTTP/1.1 200 OK\n" |
1644 "Cache-control: max-age=10000 \n", | 1264 "connection: keep-alive\n" |
1645 | 1265 "Cache-control: max-age=10000\n" |
1646 "Content-Length: 450 ", | 1266 "Content-Length: 450\n"}, |
1647 | 1267 }; |
1648 "HTTP/1.1 200 OK\n" | |
1649 "connection: keep-alive\n" | |
1650 "Cache-control: max-age=10000\n" | |
1651 "Content-Length: 450\n" | |
1652 }, | |
1653 }; | |
1654 | 1268 |
1655 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1269 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1656 std::string orig_headers(tests[i].orig_headers); | 1270 std::string orig_headers(tests[i].orig_headers); |
1657 HeadersToRaw(&orig_headers); | 1271 HeadersToRaw(&orig_headers); |
1658 scoped_refptr<net::HttpResponseHeaders> parsed( | 1272 scoped_refptr<net::HttpResponseHeaders> parsed( |
1659 new net::HttpResponseHeaders(orig_headers)); | 1273 new net::HttpResponseHeaders(orig_headers)); |
1660 | 1274 |
1661 std::string new_header(tests[i].new_header); | 1275 std::string new_header(tests[i].new_header); |
1662 parsed->AddHeader(new_header); | 1276 parsed->AddHeader(new_header); |
1663 | 1277 |
1664 std::string resulting_headers; | 1278 std::string resulting_headers; |
1665 parsed->GetNormalizedHeaders(&resulting_headers); | 1279 parsed->GetNormalizedHeaders(&resulting_headers); |
1666 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); | 1280 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); |
1667 } | 1281 } |
1668 } | 1282 } |
1669 | 1283 |
1670 TEST(HttpResponseHeadersTest, RemoveHeader) { | 1284 TEST(HttpResponseHeadersTest, RemoveHeader) { |
1671 const struct { | 1285 const struct { |
1672 const char* orig_headers; | 1286 const char* orig_headers; |
1673 const char* to_remove; | 1287 const char* to_remove; |
1674 const char* expected_headers; | 1288 const char* expected_headers; |
1675 } tests[] = { | 1289 } tests[] = { |
1676 { "HTTP/1.1 200 OK\n" | 1290 {"HTTP/1.1 200 OK\n" |
1677 "connection: keep-alive\n" | 1291 "connection: keep-alive\n" |
1678 "Cache-control: max-age=10000\n" | 1292 "Cache-control: max-age=10000\n" |
1679 "Content-Length: 450\n", | 1293 "Content-Length: 450\n", |
1680 | 1294 "Content-Length", |
1681 "Content-Length", | 1295 "HTTP/1.1 200 OK\n" |
1682 | 1296 "connection: keep-alive\n" |
1683 "HTTP/1.1 200 OK\n" | 1297 "Cache-control: max-age=10000\n"}, |
1684 "connection: keep-alive\n" | 1298 {"HTTP/1.1 200 OK\n" |
1685 "Cache-control: max-age=10000\n" | 1299 "connection: keep-alive \n" |
1686 }, | 1300 "Content-Length : 450 \n" |
1687 { "HTTP/1.1 200 OK\n" | 1301 "Cache-control: max-age=10000\n", |
1688 "connection: keep-alive \n" | 1302 "Content-Length", |
1689 "Content-Length : 450 \n" | 1303 "HTTP/1.1 200 OK\n" |
1690 "Cache-control: max-age=10000\n", | 1304 "connection: keep-alive\n" |
1691 | 1305 "Cache-control: max-age=10000\n"}, |
1692 "Content-Length", | 1306 }; |
1693 | |
1694 "HTTP/1.1 200 OK\n" | |
1695 "connection: keep-alive\n" | |
1696 "Cache-control: max-age=10000\n" | |
1697 }, | |
1698 }; | |
1699 | 1307 |
1700 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1308 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1701 std::string orig_headers(tests[i].orig_headers); | 1309 std::string orig_headers(tests[i].orig_headers); |
1702 HeadersToRaw(&orig_headers); | 1310 HeadersToRaw(&orig_headers); |
1703 scoped_refptr<net::HttpResponseHeaders> parsed( | 1311 scoped_refptr<net::HttpResponseHeaders> parsed( |
1704 new net::HttpResponseHeaders(orig_headers)); | 1312 new net::HttpResponseHeaders(orig_headers)); |
1705 | 1313 |
1706 std::string name(tests[i].to_remove); | 1314 std::string name(tests[i].to_remove); |
1707 parsed->RemoveHeader(name); | 1315 parsed->RemoveHeader(name); |
1708 | 1316 |
1709 std::string resulting_headers; | 1317 std::string resulting_headers; |
1710 parsed->GetNormalizedHeaders(&resulting_headers); | 1318 parsed->GetNormalizedHeaders(&resulting_headers); |
1711 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); | 1319 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); |
1712 } | 1320 } |
1713 } | 1321 } |
1714 | 1322 |
1715 TEST(HttpResponseHeadersTest, RemoveIndividualHeader) { | 1323 TEST(HttpResponseHeadersTest, RemoveIndividualHeader) { |
1716 const struct { | 1324 const struct { |
1717 const char* orig_headers; | 1325 const char* orig_headers; |
1718 const char* to_remove_name; | 1326 const char* to_remove_name; |
1719 const char* to_remove_value; | 1327 const char* to_remove_value; |
1720 const char* expected_headers; | 1328 const char* expected_headers; |
1721 } tests[] = { | 1329 } tests[] = { |
1722 { "HTTP/1.1 200 OK\n" | 1330 {"HTTP/1.1 200 OK\n" |
1723 "connection: keep-alive\n" | 1331 "connection: keep-alive\n" |
1724 "Cache-control: max-age=10000\n" | 1332 "Cache-control: max-age=10000\n" |
1725 "Content-Length: 450\n", | 1333 "Content-Length: 450\n", |
1726 | 1334 "Content-Length", "450", |
1727 "Content-Length", | 1335 "HTTP/1.1 200 OK\n" |
1728 | 1336 "connection: keep-alive\n" |
1729 "450", | 1337 "Cache-control: max-age=10000\n"}, |
1730 | 1338 {"HTTP/1.1 200 OK\n" |
1731 "HTTP/1.1 200 OK\n" | 1339 "connection: keep-alive \n" |
1732 "connection: keep-alive\n" | 1340 "Content-Length : 450 \n" |
1733 "Cache-control: max-age=10000\n" | 1341 "Cache-control: max-age=10000\n", |
1734 }, | 1342 "Content-Length", "450", |
1735 { "HTTP/1.1 200 OK\n" | 1343 "HTTP/1.1 200 OK\n" |
1736 "connection: keep-alive \n" | 1344 "connection: keep-alive\n" |
1737 "Content-Length : 450 \n" | 1345 "Cache-control: max-age=10000\n"}, |
1738 "Cache-control: max-age=10000\n", | 1346 {"HTTP/1.1 200 OK\n" |
1739 | 1347 "connection: keep-alive \n" |
1740 "Content-Length", | 1348 "Content-Length: 450\n" |
1741 | 1349 "Cache-control: max-age=10000\n", |
1742 "450", | 1350 "Content-Length", // Matching name. |
1743 | 1351 "999", // Mismatching value. |
1744 "HTTP/1.1 200 OK\n" | 1352 "HTTP/1.1 200 OK\n" |
1745 "connection: keep-alive\n" | 1353 "connection: keep-alive\n" |
1746 "Cache-control: max-age=10000\n" | 1354 "Content-Length: 450\n" |
1747 }, | 1355 "Cache-control: max-age=10000\n"}, |
1748 { "HTTP/1.1 200 OK\n" | 1356 {"HTTP/1.1 200 OK\n" |
1749 "connection: keep-alive \n" | 1357 "connection: keep-alive \n" |
1750 "Content-Length: 450\n" | 1358 "Foo: bar, baz\n" |
1751 "Cache-control: max-age=10000\n", | 1359 "Foo: bar\n" |
1752 | 1360 "Cache-control: max-age=10000\n", |
1753 "Content-Length", // Matching name. | 1361 "Foo", |
1754 | 1362 "bar, baz", // Space in value. |
1755 "999", // Mismatching value. | 1363 "HTTP/1.1 200 OK\n" |
1756 | 1364 "connection: keep-alive\n" |
1757 "HTTP/1.1 200 OK\n" | 1365 "Foo: bar\n" |
1758 "connection: keep-alive\n" | 1366 "Cache-control: max-age=10000\n"}, |
1759 "Content-Length: 450\n" | 1367 {"HTTP/1.1 200 OK\n" |
1760 "Cache-control: max-age=10000\n" | 1368 "connection: keep-alive \n" |
1761 }, | 1369 "Foo: bar, baz\n" |
1762 { "HTTP/1.1 200 OK\n" | 1370 "Cache-control: max-age=10000\n", |
1763 "connection: keep-alive \n" | 1371 "Foo", |
1764 "Foo: bar, baz\n" | 1372 "baz", // Only partial match -> ignored. |
1765 "Foo: bar\n" | 1373 "HTTP/1.1 200 OK\n" |
1766 "Cache-control: max-age=10000\n", | 1374 "connection: keep-alive\n" |
1767 | 1375 "Foo: bar, baz\n" |
1768 "Foo", | 1376 "Cache-control: max-age=10000\n"}, |
1769 | 1377 }; |
1770 "bar, baz", // Space in value. | |
1771 | |
1772 "HTTP/1.1 200 OK\n" | |
1773 "connection: keep-alive\n" | |
1774 "Foo: bar\n" | |
1775 "Cache-control: max-age=10000\n" | |
1776 }, | |
1777 { "HTTP/1.1 200 OK\n" | |
1778 "connection: keep-alive \n" | |
1779 "Foo: bar, baz\n" | |
1780 "Cache-control: max-age=10000\n", | |
1781 | |
1782 "Foo", | |
1783 | |
1784 "baz", // Only partial match -> ignored. | |
1785 | |
1786 "HTTP/1.1 200 OK\n" | |
1787 "connection: keep-alive\n" | |
1788 "Foo: bar, baz\n" | |
1789 "Cache-control: max-age=10000\n" | |
1790 }, | |
1791 }; | |
1792 | 1378 |
1793 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1379 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1794 std::string orig_headers(tests[i].orig_headers); | 1380 std::string orig_headers(tests[i].orig_headers); |
1795 HeadersToRaw(&orig_headers); | 1381 HeadersToRaw(&orig_headers); |
1796 scoped_refptr<net::HttpResponseHeaders> parsed( | 1382 scoped_refptr<net::HttpResponseHeaders> parsed( |
1797 new net::HttpResponseHeaders(orig_headers)); | 1383 new net::HttpResponseHeaders(orig_headers)); |
1798 | 1384 |
1799 std::string name(tests[i].to_remove_name); | 1385 std::string name(tests[i].to_remove_name); |
1800 std::string value(tests[i].to_remove_value); | 1386 std::string value(tests[i].to_remove_value); |
1801 parsed->RemoveHeaderLine(name, value); | 1387 parsed->RemoveHeaderLine(name, value); |
1802 | 1388 |
1803 std::string resulting_headers; | 1389 std::string resulting_headers; |
1804 parsed->GetNormalizedHeaders(&resulting_headers); | 1390 parsed->GetNormalizedHeaders(&resulting_headers); |
1805 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); | 1391 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); |
1806 } | 1392 } |
1807 } | 1393 } |
1808 | 1394 |
1809 TEST(HttpResponseHeadersTest, ReplaceStatus) { | 1395 TEST(HttpResponseHeadersTest, ReplaceStatus) { |
1810 const struct { | 1396 const struct { |
1811 const char* orig_headers; | 1397 const char* orig_headers; |
1812 const char* new_status; | 1398 const char* new_status; |
1813 const char* expected_headers; | 1399 const char* expected_headers; |
1814 } tests[] = { | 1400 } tests[] = { |
1815 { "HTTP/1.1 206 Partial Content\n" | 1401 {"HTTP/1.1 206 Partial Content\n" |
1816 "connection: keep-alive\n" | 1402 "connection: keep-alive\n" |
1817 "Cache-control: max-age=10000\n" | 1403 "Cache-control: max-age=10000\n" |
1818 "Content-Length: 450\n", | 1404 "Content-Length: 450\n", |
1819 | 1405 "HTTP/1.1 200 OK", |
1820 "HTTP/1.1 200 OK", | 1406 "HTTP/1.1 200 OK\n" |
1821 | 1407 "connection: keep-alive\n" |
1822 "HTTP/1.1 200 OK\n" | 1408 "Cache-control: max-age=10000\n" |
1823 "connection: keep-alive\n" | 1409 "Content-Length: 450\n"}, |
1824 "Cache-control: max-age=10000\n" | 1410 {"HTTP/1.1 200 OK\n" |
1825 "Content-Length: 450\n" | 1411 "connection: keep-alive\n", |
1826 }, | 1412 "HTTP/1.1 304 Not Modified", |
1827 { "HTTP/1.1 200 OK\n" | 1413 "HTTP/1.1 304 Not Modified\n" |
1828 "connection: keep-alive\n", | 1414 "connection: keep-alive\n"}, |
1829 | 1415 {"HTTP/1.1 200 OK\n" |
1830 "HTTP/1.1 304 Not Modified", | 1416 "connection: keep-alive \n" |
1831 | 1417 "Content-Length : 450 \n" |
1832 "HTTP/1.1 304 Not Modified\n" | 1418 "Cache-control: max-age=10000\n", |
1833 "connection: keep-alive\n" | 1419 "HTTP/1//1 304 Not Modified", |
1834 }, | 1420 "HTTP/1.0 304 Not Modified\n" |
1835 { "HTTP/1.1 200 OK\n" | 1421 "connection: keep-alive\n" |
1836 "connection: keep-alive \n" | 1422 "Content-Length: 450\n" |
1837 "Content-Length : 450 \n" | 1423 "Cache-control: max-age=10000\n"}, |
1838 "Cache-control: max-age=10000\n", | 1424 }; |
1839 | |
1840 "HTTP/1//1 304 Not Modified", | |
1841 | |
1842 "HTTP/1.0 304 Not Modified\n" | |
1843 "connection: keep-alive\n" | |
1844 "Content-Length: 450\n" | |
1845 "Cache-control: max-age=10000\n" | |
1846 }, | |
1847 }; | |
1848 | 1425 |
1849 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1426 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1850 std::string orig_headers(tests[i].orig_headers); | 1427 std::string orig_headers(tests[i].orig_headers); |
1851 HeadersToRaw(&orig_headers); | 1428 HeadersToRaw(&orig_headers); |
1852 scoped_refptr<net::HttpResponseHeaders> parsed( | 1429 scoped_refptr<net::HttpResponseHeaders> parsed( |
1853 new net::HttpResponseHeaders(orig_headers)); | 1430 new net::HttpResponseHeaders(orig_headers)); |
1854 | 1431 |
1855 std::string name(tests[i].new_status); | 1432 std::string name(tests[i].new_status); |
1856 parsed->ReplaceStatusLine(name); | 1433 parsed->ReplaceStatusLine(name); |
1857 | 1434 |
1858 std::string resulting_headers; | 1435 std::string resulting_headers; |
1859 parsed->GetNormalizedHeaders(&resulting_headers); | 1436 parsed->GetNormalizedHeaders(&resulting_headers); |
1860 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); | 1437 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); |
1861 } | 1438 } |
1862 } | 1439 } |
1863 | 1440 |
1864 TEST(HttpResponseHeadersTest, UpdateWithNewRange) { | 1441 TEST(HttpResponseHeadersTest, UpdateWithNewRange) { |
1865 const struct { | 1442 const struct { |
1866 const char* orig_headers; | 1443 const char* orig_headers; |
1867 const char* expected_headers; | 1444 const char* expected_headers; |
1868 const char* expected_headers_with_replaced_status; | 1445 const char* expected_headers_with_replaced_status; |
1869 } tests[] = { | 1446 } tests[] = { |
1870 { "HTTP/1.1 200 OK\n" | 1447 { |
1871 "Content-Length: 450\n", | 1448 "HTTP/1.1 200 OK\n" |
1872 | 1449 "Content-Length: 450\n", |
1873 "HTTP/1.1 200 OK\n" | 1450 "HTTP/1.1 200 OK\n" |
1874 "Content-Range: bytes 3-5/450\n" | 1451 "Content-Range: bytes 3-5/450\n" |
1875 "Content-Length: 3\n", | 1452 "Content-Length: 3\n", |
1876 | 1453 "HTTP/1.1 206 Partial Content\n" |
1877 "HTTP/1.1 206 Partial Content\n" | 1454 "Content-Range: bytes 3-5/450\n" |
1878 "Content-Range: bytes 3-5/450\n" | 1455 "Content-Length: 3\n", |
1879 "Content-Length: 3\n", | 1456 }, |
1880 }, | 1457 { |
1881 { "HTTP/1.1 200 OK\n" | 1458 "HTTP/1.1 200 OK\n" |
1882 "Content-Length: 5\n", | 1459 "Content-Length: 5\n", |
1883 | 1460 "HTTP/1.1 200 OK\n" |
1884 "HTTP/1.1 200 OK\n" | 1461 "Content-Range: bytes 3-5/5\n" |
1885 "Content-Range: bytes 3-5/5\n" | 1462 "Content-Length: 3\n", |
1886 "Content-Length: 3\n", | 1463 "HTTP/1.1 206 Partial Content\n" |
1887 | 1464 "Content-Range: bytes 3-5/5\n" |
1888 "HTTP/1.1 206 Partial Content\n" | 1465 "Content-Length: 3\n", |
1889 "Content-Range: bytes 3-5/5\n" | 1466 }, |
1890 "Content-Length: 3\n", | 1467 }; |
1891 }, | |
1892 }; | |
1893 const net::HttpByteRange range = net::HttpByteRange::Bounded(3, 5); | 1468 const net::HttpByteRange range = net::HttpByteRange::Bounded(3, 5); |
1894 | 1469 |
1895 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1470 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
1896 std::string orig_headers(tests[i].orig_headers); | 1471 std::string orig_headers(tests[i].orig_headers); |
1897 std::replace(orig_headers.begin(), orig_headers.end(), '\n', '\0'); | 1472 std::replace(orig_headers.begin(), orig_headers.end(), '\n', '\0'); |
1898 scoped_refptr<net::HttpResponseHeaders> parsed( | 1473 scoped_refptr<net::HttpResponseHeaders> parsed( |
1899 new net::HttpResponseHeaders(orig_headers + '\0')); | 1474 new net::HttpResponseHeaders(orig_headers + '\0')); |
1900 int64 content_size = parsed->GetContentLength(); | 1475 int64 content_size = parsed->GetContentLength(); |
1901 std::string resulting_headers; | 1476 std::string resulting_headers; |
1902 | 1477 |
1903 // Update headers without replacing status line. | 1478 // Update headers without replacing status line. |
1904 parsed->UpdateWithNewRange(range, content_size, false); | 1479 parsed->UpdateWithNewRange(range, content_size, false); |
1905 parsed->GetNormalizedHeaders(&resulting_headers); | 1480 parsed->GetNormalizedHeaders(&resulting_headers); |
1906 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); | 1481 EXPECT_EQ(std::string(tests[i].expected_headers), resulting_headers); |
1907 | 1482 |
1908 // Replace status line too. | 1483 // Replace status line too. |
1909 parsed->UpdateWithNewRange(range, content_size, true); | 1484 parsed->UpdateWithNewRange(range, content_size, true); |
1910 parsed->GetNormalizedHeaders(&resulting_headers); | 1485 parsed->GetNormalizedHeaders(&resulting_headers); |
1911 EXPECT_EQ(std::string(tests[i].expected_headers_with_replaced_status), | 1486 EXPECT_EQ(std::string(tests[i].expected_headers_with_replaced_status), |
1912 resulting_headers); | 1487 resulting_headers); |
1913 } | 1488 } |
1914 } | 1489 } |
1915 | 1490 |
1916 TEST(HttpResponseHeadersTest, ToNetLogParamAndBackAgain) { | 1491 TEST(HttpResponseHeadersTest, ToNetLogParamAndBackAgain) { |
1917 std::string headers("HTTP/1.1 404\n" | 1492 std::string headers( |
1918 "Content-Length: 450\n" | 1493 "HTTP/1.1 404\n" |
1919 "Connection: keep-alive\n"); | 1494 "Content-Length: 450\n" |
| 1495 "Connection: keep-alive\n"); |
1920 HeadersToRaw(&headers); | 1496 HeadersToRaw(&headers); |
1921 scoped_refptr<net::HttpResponseHeaders> parsed( | 1497 scoped_refptr<net::HttpResponseHeaders> parsed( |
1922 new net::HttpResponseHeaders(headers)); | 1498 new net::HttpResponseHeaders(headers)); |
1923 | 1499 |
1924 scoped_ptr<base::Value> event_param( | 1500 scoped_ptr<base::Value> event_param( |
1925 parsed->NetLogCallback(net::NetLog::LOG_ALL_BUT_BYTES)); | 1501 parsed->NetLogCallback(net::NetLog::LOG_ALL_BUT_BYTES)); |
1926 scoped_refptr<net::HttpResponseHeaders> recreated; | 1502 scoped_refptr<net::HttpResponseHeaders> recreated; |
1927 | 1503 |
1928 ASSERT_TRUE(net::HttpResponseHeaders::FromNetLogParam(event_param.get(), | 1504 ASSERT_TRUE( |
1929 &recreated)); | 1505 net::HttpResponseHeaders::FromNetLogParam(event_param.get(), &recreated)); |
1930 ASSERT_TRUE(recreated.get()); | 1506 ASSERT_TRUE(recreated.get()); |
1931 EXPECT_EQ(parsed->GetHttpVersion(), recreated->GetHttpVersion()); | 1507 EXPECT_EQ(parsed->GetHttpVersion(), recreated->GetHttpVersion()); |
1932 EXPECT_EQ(parsed->response_code(), recreated->response_code()); | 1508 EXPECT_EQ(parsed->response_code(), recreated->response_code()); |
1933 EXPECT_EQ(parsed->GetContentLength(), recreated->GetContentLength()); | 1509 EXPECT_EQ(parsed->GetContentLength(), recreated->GetContentLength()); |
1934 EXPECT_EQ(parsed->IsKeepAlive(), recreated->IsKeepAlive()); | 1510 EXPECT_EQ(parsed->IsKeepAlive(), recreated->IsKeepAlive()); |
1935 | 1511 |
1936 std::string normalized_parsed; | 1512 std::string normalized_parsed; |
1937 parsed->GetNormalizedHeaders(&normalized_parsed); | 1513 parsed->GetNormalizedHeaders(&normalized_parsed); |
1938 std::string normalized_recreated; | 1514 std::string normalized_recreated; |
1939 parsed->GetNormalizedHeaders(&normalized_recreated); | 1515 parsed->GetNormalizedHeaders(&normalized_recreated); |
1940 EXPECT_EQ(normalized_parsed, normalized_recreated); | 1516 EXPECT_EQ(normalized_parsed, normalized_recreated); |
1941 } | 1517 } |
1942 | 1518 |
1943 #if defined(SPDY_PROXY_AUTH_ORIGIN) | 1519 #if defined(SPDY_PROXY_AUTH_ORIGIN) |
1944 TEST(HttpResponseHeadersTest, GetProxyBypassInfo) { | 1520 TEST(HttpResponseHeadersTest, GetProxyBypassInfo) { |
1945 const struct { | 1521 const struct { |
1946 const char* headers; | 1522 const char* headers; |
1947 bool expected_result; | 1523 bool expected_result; |
1948 int64 expected_retry_delay; | 1524 int64 expected_retry_delay; |
1949 bool expected_bypass_all; | 1525 bool expected_bypass_all; |
1950 } tests[] = { | 1526 } tests[] = { |
1951 { "HTTP/1.1 200 OK\n" | 1527 { |
1952 "Content-Length: 999\n", | 1528 "HTTP/1.1 200 OK\n" |
1953 false, | 1529 "Content-Length: 999\n", |
1954 0, | 1530 false, 0, false, |
1955 false, | 1531 }, |
1956 }, | 1532 { |
1957 { "HTTP/1.1 200 OK\n" | 1533 "HTTP/1.1 200 OK\n" |
1958 "connection: keep-alive\n" | 1534 "connection: keep-alive\n" |
1959 "Content-Length: 999\n", | 1535 "Content-Length: 999\n", |
1960 false, | 1536 false, 0, false, |
1961 0, | 1537 }, |
1962 false, | 1538 { |
1963 }, | 1539 "HTTP/1.1 200 OK\n" |
1964 { "HTTP/1.1 200 OK\n" | 1540 "connection: keep-alive\n" |
1965 "connection: keep-alive\n" | 1541 "Chrome-Proxy: bypass=86400\n" |
1966 "Chrome-Proxy: bypass=86400\n" | 1542 "Content-Length: 999\n", |
1967 "Content-Length: 999\n", | 1543 true, 86400, false, |
1968 true, | 1544 }, |
1969 86400, | 1545 { |
1970 false, | 1546 "HTTP/1.1 200 OK\n" |
1971 }, | 1547 "connection: keep-alive\n" |
1972 { "HTTP/1.1 200 OK\n" | 1548 "Chrome-Proxy: bypass=0\n" |
1973 "connection: keep-alive\n" | 1549 "Content-Length: 999\n", |
1974 "Chrome-Proxy: bypass=0\n" | 1550 true, 0, false, |
1975 "Content-Length: 999\n", | 1551 }, |
1976 true, | 1552 { |
1977 0, | 1553 "HTTP/1.1 200 OK\n" |
1978 false, | 1554 "connection: keep-alive\n" |
1979 }, | 1555 "Chrome-Proxy: bypass=-1\n" |
1980 { "HTTP/1.1 200 OK\n" | 1556 "Content-Length: 999\n", |
1981 "connection: keep-alive\n" | 1557 false, 0, false, |
1982 "Chrome-Proxy: bypass=-1\n" | 1558 }, |
1983 "Content-Length: 999\n", | 1559 { |
1984 false, | 1560 "HTTP/1.1 200 OK\n" |
1985 0, | 1561 "connection: keep-alive\n" |
1986 false, | 1562 "Chrome-Proxy: bypass=xyz\n" |
1987 }, | 1563 "Content-Length: 999\n", |
1988 { "HTTP/1.1 200 OK\n" | 1564 false, 0, false, |
1989 "connection: keep-alive\n" | 1565 }, |
1990 "Chrome-Proxy: bypass=xyz\n" | 1566 { |
1991 "Content-Length: 999\n", | 1567 "HTTP/1.1 200 OK\n" |
1992 false, | 1568 "connection: keep-alive\n" |
1993 0, | 1569 "Chrome-Proxy: bypass\n" |
1994 false, | 1570 "Content-Length: 999\n", |
1995 }, | 1571 false, 0, false, |
1996 { "HTTP/1.1 200 OK\n" | 1572 }, |
1997 "connection: keep-alive\n" | 1573 { |
1998 "Chrome-Proxy: bypass\n" | 1574 "HTTP/1.1 200 OK\n" |
1999 "Content-Length: 999\n", | 1575 "connection: keep-alive\n" |
2000 false, | 1576 "Chrome-Proxy: foo=abc, bypass=86400\n" |
2001 0, | 1577 "Content-Length: 999\n", |
2002 false, | 1578 true, 86400, false, |
2003 }, | 1579 }, |
2004 { "HTTP/1.1 200 OK\n" | 1580 { |
2005 "connection: keep-alive\n" | 1581 "HTTP/1.1 200 OK\n" |
2006 "Chrome-Proxy: foo=abc, bypass=86400\n" | 1582 "connection: keep-alive\n" |
2007 "Content-Length: 999\n", | 1583 "Chrome-Proxy: bypass=86400, bar=abc\n" |
2008 true, | 1584 "Content-Length: 999\n", |
2009 86400, | 1585 true, 86400, false, |
2010 false, | 1586 }, |
2011 }, | 1587 { |
2012 { "HTTP/1.1 200 OK\n" | 1588 "HTTP/1.1 200 OK\n" |
2013 "connection: keep-alive\n" | 1589 "connection: keep-alive\n" |
2014 "Chrome-Proxy: bypass=86400, bar=abc\n" | 1590 "Chrome-Proxy: bypass=3600\n" |
2015 "Content-Length: 999\n", | 1591 "Chrome-Proxy: bypass=86400\n" |
2016 true, | 1592 "Content-Length: 999\n", |
2017 86400, | 1593 true, 3600, false, |
2018 false, | 1594 }, |
2019 }, | 1595 { |
2020 { "HTTP/1.1 200 OK\n" | 1596 "HTTP/1.1 200 OK\n" |
2021 "connection: keep-alive\n" | 1597 "connection: keep-alive\n" |
2022 "Chrome-Proxy: bypass=3600\n" | 1598 "Chrome-Proxy: bypass=3600, bypass=86400\n" |
2023 "Chrome-Proxy: bypass=86400\n" | 1599 "Content-Length: 999\n", |
2024 "Content-Length: 999\n", | 1600 true, 3600, false, |
2025 true, | 1601 }, |
2026 3600, | 1602 { |
2027 false, | 1603 "HTTP/1.1 200 OK\n" |
2028 }, | 1604 "connection: keep-alive\n" |
2029 { "HTTP/1.1 200 OK\n" | 1605 "Chrome-Proxy: bypass=, bypass=86400\n" |
2030 "connection: keep-alive\n" | 1606 "Content-Length: 999\n", |
2031 "Chrome-Proxy: bypass=3600, bypass=86400\n" | 1607 true, 86400, false, |
2032 "Content-Length: 999\n", | 1608 }, |
2033 true, | 1609 { |
2034 3600, | 1610 "HTTP/1.1 200 OK\n" |
2035 false, | 1611 "connection: keep-alive\n" |
2036 }, | 1612 "Chrome-Proxy: bypass\n" |
2037 { "HTTP/1.1 200 OK\n" | 1613 "Chrome-Proxy: bypass=86400\n" |
2038 "connection: keep-alive\n" | 1614 "Content-Length: 999\n", |
2039 "Chrome-Proxy: bypass=, bypass=86400\n" | 1615 true, 86400, false, |
2040 "Content-Length: 999\n", | 1616 }, |
2041 true, | 1617 { |
2042 86400, | 1618 "HTTP/1.1 200 OK\n" |
2043 false, | 1619 "connection: keep-alive\n" |
2044 }, | 1620 "Chrome-Proxy: block=, block=3600\n" |
2045 { "HTTP/1.1 200 OK\n" | 1621 "Content-Length: 999\n", |
2046 "connection: keep-alive\n" | 1622 true, 3600, true, |
2047 "Chrome-Proxy: bypass\n" | 1623 }, |
2048 "Chrome-Proxy: bypass=86400\n" | 1624 { |
2049 "Content-Length: 999\n", | 1625 "HTTP/1.1 200 OK\n" |
2050 true, | 1626 "connection: keep-alive\n" |
2051 86400, | 1627 "Chrome-Proxy: bypass=86400, block=3600\n" |
2052 false, | 1628 "Content-Length: 999\n", |
2053 }, | 1629 true, 3600, true, |
2054 { "HTTP/1.1 200 OK\n" | 1630 }, |
2055 "connection: keep-alive\n" | 1631 { |
2056 "Chrome-Proxy: block=, block=3600\n" | 1632 "HTTP/1.1 200 OK\n" |
2057 "Content-Length: 999\n", | 1633 "connection: proxy-bypass\n" |
2058 true, | 1634 "Chrome-Proxy: block=, bypass=86400\n" |
2059 3600, | 1635 "Content-Length: 999\n", |
2060 true, | 1636 true, 86400, false, |
2061 }, | 1637 }, |
2062 { "HTTP/1.1 200 OK\n" | 1638 { |
2063 "connection: keep-alive\n" | 1639 "HTTP/1.1 200 OK\n" |
2064 "Chrome-Proxy: bypass=86400, block=3600\n" | 1640 "connection: proxy-bypass\n" |
2065 "Content-Length: 999\n", | 1641 "Chrome-Proxy: block=-1\n" |
2066 true, | 1642 "Content-Length: 999\n", |
2067 3600, | 1643 false, 0, false, |
2068 true, | 1644 }, |
2069 }, | 1645 { |
2070 { "HTTP/1.1 200 OK\n" | 1646 "HTTP/1.1 200 OK\n" |
2071 "connection: proxy-bypass\n" | 1647 "connection: proxy-bypass\n" |
2072 "Chrome-Proxy: block=, bypass=86400\n" | 1648 "Chrome-Proxy: block=99999999999999999999\n" |
2073 "Content-Length: 999\n", | 1649 "Content-Length: 999\n", |
2074 true, | 1650 false, 0, false, |
2075 86400, | 1651 }, |
2076 false, | 1652 }; |
2077 }, | |
2078 { "HTTP/1.1 200 OK\n" | |
2079 "connection: proxy-bypass\n" | |
2080 "Chrome-Proxy: block=-1\n" | |
2081 "Content-Length: 999\n", | |
2082 false, | |
2083 0, | |
2084 false, | |
2085 }, | |
2086 { "HTTP/1.1 200 OK\n" | |
2087 "connection: proxy-bypass\n" | |
2088 "Chrome-Proxy: block=99999999999999999999\n" | |
2089 "Content-Length: 999\n", | |
2090 false, | |
2091 0, | |
2092 false, | |
2093 }, | |
2094 }; | |
2095 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1653 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
2096 std::string headers(tests[i].headers); | 1654 std::string headers(tests[i].headers); |
2097 HeadersToRaw(&headers); | 1655 HeadersToRaw(&headers); |
2098 scoped_refptr<net::HttpResponseHeaders> parsed( | 1656 scoped_refptr<net::HttpResponseHeaders> parsed( |
2099 new net::HttpResponseHeaders(headers)); | 1657 new net::HttpResponseHeaders(headers)); |
2100 | 1658 |
2101 net::HttpResponseHeaders::DataReductionProxyInfo data_reduction_proxy_info; | 1659 net::HttpResponseHeaders::DataReductionProxyInfo data_reduction_proxy_info; |
2102 EXPECT_EQ(tests[i].expected_result, | 1660 EXPECT_EQ(tests[i].expected_result, |
2103 parsed->GetDataReductionProxyInfo(&data_reduction_proxy_info)); | 1661 parsed->GetDataReductionProxyInfo(&data_reduction_proxy_info)); |
2104 EXPECT_EQ(tests[i].expected_retry_delay, | 1662 EXPECT_EQ(tests[i].expected_retry_delay, |
2105 data_reduction_proxy_info.bypass_duration.InSeconds()); | 1663 data_reduction_proxy_info.bypass_duration.InSeconds()); |
2106 EXPECT_EQ(tests[i].expected_bypass_all, | 1664 EXPECT_EQ(tests[i].expected_bypass_all, |
2107 data_reduction_proxy_info.bypass_all); | 1665 data_reduction_proxy_info.bypass_all); |
2108 } | 1666 } |
2109 } | 1667 } |
2110 | 1668 |
2111 TEST(HttpResponseHeadersTest, IsDataReductionProxyResponse) { | 1669 TEST(HttpResponseHeadersTest, IsDataReductionProxyResponse) { |
2112 const struct { | 1670 const struct { |
2113 const char* headers; | 1671 const char* headers; |
2114 bool expected_result; | 1672 bool expected_result; |
2115 } tests[] = { | 1673 } tests[] = { |
2116 { "HTTP/1.1 200 OK\n" | 1674 { |
2117 "Via: 1.1 Chrome-Proxy\n", | 1675 "HTTP/1.1 200 OK\n" |
2118 false, | 1676 "Via: 1.1 Chrome-Proxy\n", |
2119 }, | 1677 false, |
2120 { "HTTP/1.1 200 OK\n" | 1678 }, |
2121 "Via: 1\n", | 1679 { |
2122 false, | 1680 "HTTP/1.1 200 OK\n" |
2123 }, | 1681 "Via: 1\n", |
2124 { "HTTP/1.1 200 OK\n" | 1682 false, |
2125 "Via: 1.1 Chrome-Compression-Proxy\n", | 1683 }, |
2126 true, | 1684 { |
2127 }, | 1685 "HTTP/1.1 200 OK\n" |
2128 { "HTTP/1.1 200 OK\n" | 1686 "Via: 1.1 Chrome-Compression-Proxy\n", |
2129 "Via: 1.0 Chrome-Compression-Proxy\n", | 1687 true, |
2130 true, | 1688 }, |
2131 }, | 1689 { |
2132 { "HTTP/1.1 200 OK\n" | 1690 "HTTP/1.1 200 OK\n" |
2133 "Via: 1.1 Foo-Bar, 1.1 Chrome-Compression-Proxy\n", | 1691 "Via: 1.0 Chrome-Compression-Proxy\n", |
2134 true, | 1692 true, |
2135 }, | 1693 }, |
2136 { "HTTP/1.1 200 OK\n" | 1694 { |
2137 "Via: 1.1 Chrome-Compression-Proxy, 1.1 Bar-Foo\n", | 1695 "HTTP/1.1 200 OK\n" |
2138 true, | 1696 "Via: 1.1 Foo-Bar, 1.1 Chrome-Compression-Proxy\n", |
2139 }, | 1697 true, |
2140 { "HTTP/1.1 200 OK\n" | 1698 }, |
2141 "Via: 1.1 chrome-compression-proxy\n", | 1699 { |
2142 false, | 1700 "HTTP/1.1 200 OK\n" |
2143 }, | 1701 "Via: 1.1 Chrome-Compression-Proxy, 1.1 Bar-Foo\n", |
2144 { "HTTP/1.1 200 OK\n" | 1702 true, |
2145 "Via: 1.1 Foo-Bar\n" | 1703 }, |
2146 "Via: 1.1 Chrome-Compression-Proxy\n", | 1704 { |
2147 true, | 1705 "HTTP/1.1 200 OK\n" |
2148 }, | 1706 "Via: 1.1 chrome-compression-proxy\n", |
2149 { "HTTP/1.1 200 OK\n" | 1707 false, |
2150 "Via: 1.1 Chrome-Proxy\n", | 1708 }, |
2151 false, | 1709 { |
2152 }, | 1710 "HTTP/1.1 200 OK\n" |
2153 { "HTTP/1.1 200 OK\n" | 1711 "Via: 1.1 Foo-Bar\n" |
2154 "Via: 1.1 Chrome Compression Proxy\n", | 1712 "Via: 1.1 Chrome-Compression-Proxy\n", |
2155 true, | 1713 true, |
2156 }, | 1714 }, |
2157 { "HTTP/1.1 200 OK\n" | 1715 { |
2158 "Via: 1.1 Foo-Bar, 1.1 Chrome Compression Proxy\n", | 1716 "HTTP/1.1 200 OK\n" |
2159 true, | 1717 "Via: 1.1 Chrome-Proxy\n", |
2160 }, | 1718 false, |
2161 { "HTTP/1.1 200 OK\n" | 1719 }, |
2162 "Via: 1.1 Chrome Compression Proxy, 1.1 Bar-Foo\n", | 1720 { |
2163 true, | 1721 "HTTP/1.1 200 OK\n" |
2164 }, | 1722 "Via: 1.1 Chrome Compression Proxy\n", |
2165 { "HTTP/1.1 200 OK\n" | 1723 true, |
2166 "Via: 1.1 chrome compression proxy\n", | 1724 }, |
2167 false, | 1725 { |
2168 }, | 1726 "HTTP/1.1 200 OK\n" |
2169 { "HTTP/1.1 200 OK\n" | 1727 "Via: 1.1 Foo-Bar, 1.1 Chrome Compression Proxy\n", |
2170 "Via: 1.1 Foo-Bar\n" | 1728 true, |
2171 "Via: 1.1 Chrome Compression Proxy\n", | 1729 }, |
2172 true, | 1730 { |
2173 }, | 1731 "HTTP/1.1 200 OK\n" |
2174 }; | 1732 "Via: 1.1 Chrome Compression Proxy, 1.1 Bar-Foo\n", |
| 1733 true, |
| 1734 }, |
| 1735 { |
| 1736 "HTTP/1.1 200 OK\n" |
| 1737 "Via: 1.1 chrome compression proxy\n", |
| 1738 false, |
| 1739 }, |
| 1740 { |
| 1741 "HTTP/1.1 200 OK\n" |
| 1742 "Via: 1.1 Foo-Bar\n" |
| 1743 "Via: 1.1 Chrome Compression Proxy\n", |
| 1744 true, |
| 1745 }, |
| 1746 }; |
2175 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1747 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
2176 std::string headers(tests[i].headers); | 1748 std::string headers(tests[i].headers); |
2177 HeadersToRaw(&headers); | 1749 HeadersToRaw(&headers); |
2178 scoped_refptr<net::HttpResponseHeaders> parsed( | 1750 scoped_refptr<net::HttpResponseHeaders> parsed( |
2179 new net::HttpResponseHeaders(headers)); | 1751 new net::HttpResponseHeaders(headers)); |
2180 | 1752 |
2181 EXPECT_EQ(tests[i].expected_result, parsed->IsDataReductionProxyResponse()); | 1753 EXPECT_EQ(tests[i].expected_result, parsed->IsDataReductionProxyResponse()); |
2182 } | 1754 } |
2183 } | 1755 } |
2184 | 1756 |
2185 TEST(HttpResponseHeadersTest, GetDataReductionProxyBypassEventType) { | 1757 TEST(HttpResponseHeadersTest, GetDataReductionProxyBypassEventType) { |
2186 const struct { | 1758 const struct { |
2187 const char* headers; | 1759 const char* headers; |
2188 net::ProxyService::DataReductionProxyBypassEventType expected_result; | 1760 net::ProxyService::DataReductionProxyBypassEventType expected_result; |
2189 } tests[] = { | 1761 } tests[] = { |
2190 { "HTTP/1.1 200 OK\n" | 1762 { |
2191 "Chrome-Proxy: bypass=0\n" | 1763 "HTTP/1.1 200 OK\n" |
2192 "Via: 1.1 Chrome-Compression-Proxy\n", | 1764 "Chrome-Proxy: bypass=0\n" |
2193 net::ProxyService::SHORT_BYPASS, | 1765 "Via: 1.1 Chrome-Compression-Proxy\n", |
2194 }, | 1766 net::ProxyService::SHORT_BYPASS, |
2195 { "HTTP/1.1 200 OK\n" | 1767 }, |
2196 "Chrome-Proxy: bypass=1799\n" | 1768 { |
2197 "Via: 1.1 Chrome-Compression-Proxy\n", | 1769 "HTTP/1.1 200 OK\n" |
2198 net::ProxyService::SHORT_BYPASS, | 1770 "Chrome-Proxy: bypass=1799\n" |
2199 }, | 1771 "Via: 1.1 Chrome-Compression-Proxy\n", |
2200 { "HTTP/1.1 200 OK\n" | 1772 net::ProxyService::SHORT_BYPASS, |
2201 "Chrome-Proxy: bypass=1800\n" | 1773 }, |
2202 "Via: 1.1 Chrome-Compression-Proxy\n", | 1774 { |
2203 net::ProxyService::LONG_BYPASS, | 1775 "HTTP/1.1 200 OK\n" |
2204 }, | 1776 "Chrome-Proxy: bypass=1800\n" |
2205 { "HTTP/1.1 500 Internal Server Error\n" | 1777 "Via: 1.1 Chrome-Compression-Proxy\n", |
2206 "Via: 1.1 Chrome-Compression-Proxy\n", | 1778 net::ProxyService::LONG_BYPASS, |
2207 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, | 1779 }, |
2208 }, | 1780 { |
2209 { "HTTP/1.1 501 Not Implemented\n" | 1781 "HTTP/1.1 500 Internal Server Error\n" |
2210 "Via: 1.1 Chrome-Compression-Proxy\n", | 1782 "Via: 1.1 Chrome-Compression-Proxy\n", |
2211 net::ProxyService::BYPASS_EVENT_TYPE_MAX, | 1783 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, |
2212 }, | 1784 }, |
2213 { "HTTP/1.1 502 Bad Gateway\n" | 1785 { |
2214 "Via: 1.1 Chrome-Compression-Proxy\n", | 1786 "HTTP/1.1 501 Not Implemented\n" |
2215 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, | 1787 "Via: 1.1 Chrome-Compression-Proxy\n", |
2216 }, | 1788 net::ProxyService::BYPASS_EVENT_TYPE_MAX, |
2217 { "HTTP/1.1 503 Service Unavailable\n" | 1789 }, |
2218 "Via: 1.1 Chrome-Compression-Proxy\n", | 1790 { |
2219 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, | 1791 "HTTP/1.1 502 Bad Gateway\n" |
2220 }, | 1792 "Via: 1.1 Chrome-Compression-Proxy\n", |
2221 { "HTTP/1.1 504 Gateway Timeout\n" | 1793 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, |
2222 "Via: 1.1 Chrome-Compression-Proxy\n", | 1794 }, |
2223 net::ProxyService::BYPASS_EVENT_TYPE_MAX, | 1795 { |
2224 }, | 1796 "HTTP/1.1 503 Service Unavailable\n" |
2225 { "HTTP/1.1 505 HTTP Version Not Supported\n" | 1797 "Via: 1.1 Chrome-Compression-Proxy\n", |
2226 "Via: 1.1 Chrome-Compression-Proxy\n", | 1798 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, |
2227 net::ProxyService::BYPASS_EVENT_TYPE_MAX, | 1799 }, |
2228 }, | 1800 { |
2229 { "HTTP/1.1 304 Not Modified\n", | 1801 "HTTP/1.1 504 Gateway Timeout\n" |
2230 net::ProxyService::BYPASS_EVENT_TYPE_MAX, | 1802 "Via: 1.1 Chrome-Compression-Proxy\n", |
2231 }, | 1803 net::ProxyService::BYPASS_EVENT_TYPE_MAX, |
2232 { "HTTP/1.1 200 OK\n", | 1804 }, |
2233 net::ProxyService::MISSING_VIA_HEADER, | 1805 { |
2234 }, | 1806 "HTTP/1.1 505 HTTP Version Not Supported\n" |
2235 { "HTTP/1.1 200 OK\n" | 1807 "Via: 1.1 Chrome-Compression-Proxy\n", |
2236 "Chrome-Proxy: bypass=1799\n", | 1808 net::ProxyService::BYPASS_EVENT_TYPE_MAX, |
2237 net::ProxyService::SHORT_BYPASS, | 1809 }, |
2238 }, | 1810 { |
2239 { "HTTP/1.1 502 Bad Gateway\n", | 1811 "HTTP/1.1 304 Not Modified\n", |
2240 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, | 1812 net::ProxyService::BYPASS_EVENT_TYPE_MAX, |
2241 }, | 1813 }, |
2242 { "HTTP/1.1 502 Bad Gateway\n" | 1814 { |
2243 "Chrome-Proxy: bypass=1799\n", | 1815 "HTTP/1.1 200 OK\n", net::ProxyService::MISSING_VIA_HEADER, |
2244 net::ProxyService::SHORT_BYPASS, | 1816 }, |
2245 }, | 1817 { |
2246 }; | 1818 "HTTP/1.1 200 OK\n" |
| 1819 "Chrome-Proxy: bypass=1799\n", |
| 1820 net::ProxyService::SHORT_BYPASS, |
| 1821 }, |
| 1822 { |
| 1823 "HTTP/1.1 502 Bad Gateway\n", |
| 1824 net::ProxyService::INTERNAL_SERVER_ERROR_BYPASS, |
| 1825 }, |
| 1826 { |
| 1827 "HTTP/1.1 502 Bad Gateway\n" |
| 1828 "Chrome-Proxy: bypass=1799\n", |
| 1829 net::ProxyService::SHORT_BYPASS, |
| 1830 }, |
| 1831 }; |
2247 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 1832 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
2248 std::string headers(tests[i].headers); | 1833 std::string headers(tests[i].headers); |
2249 HeadersToRaw(&headers); | 1834 HeadersToRaw(&headers); |
2250 scoped_refptr<net::HttpResponseHeaders> parsed( | 1835 scoped_refptr<net::HttpResponseHeaders> parsed( |
2251 new net::HttpResponseHeaders(headers)); | 1836 new net::HttpResponseHeaders(headers)); |
2252 net::HttpResponseHeaders::DataReductionProxyInfo chrome_proxy_info; | 1837 net::HttpResponseHeaders::DataReductionProxyInfo chrome_proxy_info; |
2253 EXPECT_EQ(tests[i].expected_result, | 1838 EXPECT_EQ(tests[i].expected_result, |
2254 parsed->GetDataReductionProxyBypassEventType(&chrome_proxy_info)); | 1839 parsed->GetDataReductionProxyBypassEventType(&chrome_proxy_info)); |
2255 } | 1840 } |
2256 } | 1841 } |
2257 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) | 1842 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) |
OLD | NEW |