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