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 "net/http/http_stream_parser.h" | 5 #include "net/http/http_stream_parser.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 int size = data.size(); | 1206 int size = data.size(); |
1207 read_buffer_->SetCapacity(offset + size); | 1207 read_buffer_->SetCapacity(offset + size); |
1208 memcpy(read_buffer_->StartOfBuffer() + offset, data.data(), size); | 1208 memcpy(read_buffer_->StartOfBuffer() + offset, data.data(), size); |
1209 read_buffer_->set_offset(offset + size); | 1209 read_buffer_->set_offset(offset + size); |
1210 } | 1210 } |
1211 | 1211 |
1212 void AddRead(const std::string& data) { | 1212 void AddRead(const std::string& data) { |
1213 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data())); | 1213 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data())); |
1214 } | 1214 } |
1215 | 1215 |
| 1216 // Simple overload - the above method requires using std::strings that outlive |
| 1217 // the function call. This version works with inlined C-style strings. |
| 1218 void AddRead(const char* data) { |
| 1219 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data)); |
| 1220 } |
| 1221 |
1216 void SetupParserAndSendRequest() { | 1222 void SetupParserAndSendRequest() { |
1217 reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF | 1223 reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF |
1218 | 1224 |
1219 data_.reset(new SequencedSocketData(&reads_.front(), reads_.size(), | 1225 data_.reset(new SequencedSocketData(&reads_.front(), reads_.size(), |
1220 &writes_.front(), writes_.size())); | 1226 &writes_.front(), writes_.size())); |
1221 socket_handle_ = CreateConnectedSocketHandle(data_.get()); | 1227 socket_handle_ = CreateConnectedSocketHandle(data_.get()); |
1222 | 1228 |
1223 request_info_.method = "GET"; | 1229 request_info_.method = "GET"; |
1224 request_info_.url = url_; | 1230 request_info_.url = url_; |
1225 request_info_.load_flags = LOAD_NORMAL; | 1231 request_info_.load_flags = LOAD_NORMAL; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 int sequence_number_; | 1280 int sequence_number_; |
1275 }; | 1281 }; |
1276 | 1282 |
1277 // Test that HTTP/0.9 works as expected, only on ports where it should be | 1283 // Test that HTTP/0.9 works as expected, only on ports where it should be |
1278 // enabled. | 1284 // enabled. |
1279 TEST(HttpStreamParser, Http09PortTests) { | 1285 TEST(HttpStreamParser, Http09PortTests) { |
1280 struct TestCase { | 1286 struct TestCase { |
1281 const char* url; | 1287 const char* url; |
1282 bool http_09_on_non_default_ports_enabled; | 1288 bool http_09_on_non_default_ports_enabled; |
1283 | 1289 |
1284 // Expected result when trying to read headers. | 1290 // Expected result when trying to read headers and response is an HTTP/0.9 |
1285 Error expected_header_error; | 1291 // non-Shoutcast response. |
| 1292 Error expected_09_header_error; |
| 1293 |
| 1294 // Expected result when trying to read headers for a shoutcast response. |
| 1295 Error expected_shoutcast_header_error; |
1286 }; | 1296 }; |
1287 | 1297 |
1288 const TestCase kTestCases[] = { | 1298 const TestCase kTestCases[] = { |
1289 // Default ports should work for HTTP/0.9, regardless of whether the port | 1299 // Default ports should work for HTTP/0.9, regardless of whether the port |
1290 // is explicitly specified or not. | 1300 // is explicitly specified or not. |
1291 {"http://foo.com/", false, OK}, | 1301 {"http://foo.com/", false, OK, OK}, |
1292 {"http://foo.com:80/", false, OK}, | 1302 {"http://foo.com:80/", false, OK, OK}, |
1293 {"https://foo.com/", false, OK}, | 1303 {"https://foo.com/", false, OK, OK}, |
1294 {"https://foo.com:443/", false, OK}, | 1304 {"https://foo.com:443/", false, OK, OK}, |
1295 | 1305 |
1296 // Non-standard ports should not support HTTP/0.9, by default. | 1306 // Non-standard ports should not support HTTP/0.9, by default. |
1297 {"http://foo.com:8080/", false, ERR_INVALID_HTTP_RESPONSE}, | 1307 {"http://foo.com:8080/", false, ERR_INVALID_HTTP_RESPONSE, OK}, |
1298 {"https://foo.com:8080/", false, ERR_INVALID_HTTP_RESPONSE}, | 1308 {"https://foo.com:8080/", false, ERR_INVALID_HTTP_RESPONSE, |
1299 {"http://foo.com:443/", false, ERR_INVALID_HTTP_RESPONSE}, | 1309 ERR_INVALID_HTTP_RESPONSE}, |
1300 {"https://foo.com:80/", false, ERR_INVALID_HTTP_RESPONSE}, | 1310 {"http://foo.com:443/", false, ERR_INVALID_HTTP_RESPONSE, OK}, |
| 1311 {"https://foo.com:80/", false, ERR_INVALID_HTTP_RESPONSE, |
| 1312 ERR_INVALID_HTTP_RESPONSE}, |
1301 | 1313 |
1302 // Allowing non-default ports should not break the default ones. | 1314 // Allowing non-default ports should not break the default ones. |
1303 {"http://foo.com/", true, OK}, | 1315 {"http://foo.com/", true, OK, OK}, |
1304 {"http://foo.com:80/", true, OK}, | 1316 {"http://foo.com:80/", true, OK, OK}, |
1305 {"https://foo.com/", true, OK}, | 1317 {"https://foo.com/", true, OK, OK}, |
1306 {"https://foo.com:443/", true, OK}, | 1318 {"https://foo.com:443/", true, OK, OK}, |
1307 | 1319 |
1308 // Check that non-default ports works. | 1320 // Check that non-default ports works. |
1309 {"http://foo.com:8080/", true, OK}, | 1321 {"http://foo.com:8080/", true, OK, OK}, |
1310 {"https://foo.com:8080/", true, OK}, | 1322 {"https://foo.com:8080/", true, OK, OK}, |
1311 {"http://foo.com:443/", true, OK}, | 1323 {"http://foo.com:443/", true, OK, OK}, |
1312 {"https://foo.com:80/", true, OK}, | 1324 {"https://foo.com:80/", true, OK, OK}, |
1313 }; | 1325 }; |
1314 | 1326 |
1315 std::string response = "hello\r\nworld\r\n"; | 1327 const std::string kResponse = "hello\r\nworld\r\n"; |
1316 int response_size = response.size(); | |
1317 | 1328 |
1318 for (const auto& test_case : kTestCases) { | 1329 for (const auto& test_case : kTestCases) { |
1319 SimpleGetRunner get_runner; | 1330 SimpleGetRunner get_runner; |
1320 get_runner.set_url(GURL(test_case.url)); | 1331 get_runner.set_url(GURL(test_case.url)); |
1321 get_runner.set_http_09_on_non_default_ports_enabled( | 1332 get_runner.set_http_09_on_non_default_ports_enabled( |
1322 test_case.http_09_on_non_default_ports_enabled); | 1333 test_case.http_09_on_non_default_ports_enabled); |
1323 get_runner.AddRead(response); | 1334 get_runner.AddRead(kResponse); |
1324 get_runner.SetupParserAndSendRequest(); | 1335 get_runner.SetupParserAndSendRequest(); |
1325 | 1336 |
1326 get_runner.ReadHeadersExpectingError(test_case.expected_header_error); | 1337 get_runner.ReadHeadersExpectingError(test_case.expected_09_header_error); |
1327 if (test_case.expected_header_error != OK) | 1338 if (test_case.expected_09_header_error != OK) |
1328 continue; | 1339 continue; |
1329 | 1340 |
1330 ASSERT_TRUE(get_runner.response_info()->headers); | 1341 ASSERT_TRUE(get_runner.response_info()->headers); |
1331 EXPECT_EQ("HTTP/0.9 200 OK", | 1342 EXPECT_EQ("HTTP/0.9 200 OK", |
1332 get_runner.response_info()->headers->GetStatusLine()); | 1343 get_runner.response_info()->headers->GetStatusLine()); |
1333 | 1344 |
1334 EXPECT_EQ(0, get_runner.parser()->received_bytes()); | 1345 EXPECT_EQ(0, get_runner.parser()->received_bytes()); |
1335 int read_lengths[] = {response_size, 0}; | 1346 int read_lengths[] = {kResponse.size(), 0}; |
1336 get_runner.ReadBody(response_size, read_lengths); | 1347 get_runner.ReadBody(kResponse.size(), read_lengths); |
1337 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 1348 EXPECT_EQ(kResponse.size(), |
| 1349 static_cast<size_t>(get_runner.parser()->received_bytes())); |
| 1350 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP0_9, |
| 1351 get_runner.response_info()->connection_info); |
| 1352 } |
| 1353 |
| 1354 const std::string kShoutcastResponse = "ICY 200 blah\r\n\r\n"; |
| 1355 for (const auto& test_case : kTestCases) { |
| 1356 SimpleGetRunner get_runner; |
| 1357 get_runner.set_url(GURL(test_case.url)); |
| 1358 get_runner.set_http_09_on_non_default_ports_enabled( |
| 1359 test_case.http_09_on_non_default_ports_enabled); |
| 1360 get_runner.AddRead(kShoutcastResponse); |
| 1361 get_runner.SetupParserAndSendRequest(); |
| 1362 |
| 1363 get_runner.ReadHeadersExpectingError( |
| 1364 test_case.expected_shoutcast_header_error); |
| 1365 if (test_case.expected_shoutcast_header_error != OK) |
| 1366 continue; |
| 1367 |
| 1368 ASSERT_TRUE(get_runner.response_info()->headers); |
| 1369 EXPECT_EQ("HTTP/0.9 200 OK", |
| 1370 get_runner.response_info()->headers->GetStatusLine()); |
| 1371 |
| 1372 EXPECT_EQ(0, get_runner.parser()->received_bytes()); |
| 1373 int read_lengths[] = {kShoutcastResponse.size(), 0}; |
| 1374 get_runner.ReadBody(kShoutcastResponse.size(), read_lengths); |
| 1375 EXPECT_EQ(kShoutcastResponse.size(), |
| 1376 static_cast<size_t>(get_runner.parser()->received_bytes())); |
1338 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP0_9, | 1377 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP0_9, |
1339 get_runner.response_info()->connection_info); | 1378 get_runner.response_info()->connection_info); |
1340 } | 1379 } |
1341 } | 1380 } |
1342 | 1381 |
| 1382 // Make sure that Shoutcast is recognized when receiving one byte at a time. |
| 1383 TEST(HttpStreamParser, ShoutcastSingleByteReads) { |
| 1384 SimpleGetRunner get_runner; |
| 1385 get_runner.set_url(GURL("http://foo.com:8080/")); |
| 1386 get_runner.set_http_09_on_non_default_ports_enabled(false); |
| 1387 get_runner.AddRead("i"); |
| 1388 get_runner.AddRead("c"); |
| 1389 get_runner.AddRead("Y"); |
| 1390 // Needed because HttpStreamParser::Read returns ERR_CONNECTION_CLOSED on |
| 1391 // small response headers, which HttpNetworkTransaction replaces with net::OK. |
| 1392 // TODO(mmenke): Can we just change that behavior? |
| 1393 get_runner.AddRead(" Extra stuff"); |
| 1394 get_runner.SetupParserAndSendRequest(); |
| 1395 |
| 1396 get_runner.ReadHeadersExpectingError(OK); |
| 1397 EXPECT_EQ("HTTP/0.9 200 OK", |
| 1398 get_runner.response_info()->headers->GetStatusLine()); |
| 1399 } |
| 1400 |
| 1401 // Make sure that Shoutcast is recognized when receiving any string starting |
| 1402 // with "ICY", regardless of capitalization, and without a space following it |
| 1403 // (The latter behavior is just to match HTTP detection). |
| 1404 TEST(HttpStreamParser, ShoutcastWeirdHeader) { |
| 1405 SimpleGetRunner get_runner; |
| 1406 get_runner.set_url(GURL("http://foo.com:8080/")); |
| 1407 get_runner.set_http_09_on_non_default_ports_enabled(false); |
| 1408 get_runner.AddRead("iCyCreamSundae"); |
| 1409 get_runner.SetupParserAndSendRequest(); |
| 1410 |
| 1411 get_runner.ReadHeadersExpectingError(OK); |
| 1412 EXPECT_EQ("HTTP/0.9 200 OK", |
| 1413 get_runner.response_info()->headers->GetStatusLine()); |
| 1414 } |
| 1415 |
1343 // Make sure that HTTP/0.9 isn't allowed in the truncated header case on a weird | 1416 // Make sure that HTTP/0.9 isn't allowed in the truncated header case on a weird |
1344 // port. | 1417 // port. |
1345 TEST(HttpStreamParser, Http09TruncatedHeaderPortTest) { | 1418 TEST(HttpStreamParser, Http09TruncatedHeaderPortTest) { |
1346 SimpleGetRunner get_runner; | 1419 SimpleGetRunner get_runner; |
1347 get_runner.set_url(GURL("http://foo.com:8080/")); | 1420 get_runner.set_url(GURL("http://foo.com:8080/")); |
1348 std::string response = "HT"; | 1421 std::string response = "HT"; |
1349 get_runner.AddRead(response); | 1422 get_runner.AddRead(response); |
1350 get_runner.SetupParserAndSendRequest(); | 1423 get_runner.SetupParserAndSendRequest(); |
1351 | 1424 |
1352 get_runner.ReadHeadersExpectingError(ERR_INVALID_HTTP_RESPONSE); | 1425 get_runner.ReadHeadersExpectingError(ERR_INVALID_HTTP_RESPONSE); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 ASSERT_EQ(kBodySize, parser.ReadResponseBody( | 1689 ASSERT_EQ(kBodySize, parser.ReadResponseBody( |
1617 body_buffer.get(), kBodySize, callback.callback())); | 1690 body_buffer.get(), kBodySize, callback.callback())); |
1618 | 1691 |
1619 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 1692 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
1620 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); | 1693 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
1621 } | 1694 } |
1622 | 1695 |
1623 } // namespace | 1696 } // namespace |
1624 | 1697 |
1625 } // namespace net | 1698 } // namespace net |
OLD | NEW |