Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: net/http/http_response_headers_unittest.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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", &current_time); 717 base::Time::FromString("Wed, 28 Nov 2007 00:45:20 GMT", &current_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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698