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 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 | 1063 |
1064 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 1064 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
1065 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)) - | 1065 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)) - |
1066 static_cast<int64_t>(strlen("a fake websocket frame")), | 1066 static_cast<int64_t>(strlen("a fake websocket frame")), |
1067 parser.received_bytes()); | 1067 parser.received_bytes()); |
1068 } | 1068 } |
1069 | 1069 |
1070 // Helper class for constructing HttpStreamParser and running GET requests. | 1070 // Helper class for constructing HttpStreamParser and running GET requests. |
1071 class SimpleGetRunner { | 1071 class SimpleGetRunner { |
1072 public: | 1072 public: |
1073 SimpleGetRunner() | 1073 SimpleGetRunner() : read_buffer_(new GrowableIOBuffer), sequence_number_(0) { |
1074 : url_("http://localhost"), | |
1075 http_09_on_non_default_ports_enabled_(false), | |
1076 read_buffer_(new GrowableIOBuffer), | |
1077 sequence_number_(0) { | |
1078 writes_.push_back(MockWrite( | 1074 writes_.push_back(MockWrite( |
1079 SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n")); | 1075 SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n")); |
1080 } | 1076 } |
1081 | 1077 |
1082 void set_url(const GURL& url) { url_ = url; } | |
1083 void set_http_09_on_non_default_ports_enabled( | |
1084 bool http_09_on_non_default_ports_enabled) { | |
1085 http_09_on_non_default_ports_enabled_ = | |
1086 http_09_on_non_default_ports_enabled; | |
1087 } | |
1088 | |
1089 HttpStreamParser* parser() { return parser_.get(); } | 1078 HttpStreamParser* parser() { return parser_.get(); } |
1090 GrowableIOBuffer* read_buffer() { return read_buffer_.get(); } | 1079 GrowableIOBuffer* read_buffer() { return read_buffer_.get(); } |
1091 HttpResponseInfo* response_info() { return &response_info_; } | 1080 HttpResponseInfo* response_info() { return &response_info_; } |
1092 | 1081 |
1093 void AddInitialData(const std::string& data) { | 1082 void AddInitialData(const std::string& data) { |
1094 int offset = read_buffer_->offset(); | 1083 int offset = read_buffer_->offset(); |
1095 int size = data.size(); | 1084 int size = data.size(); |
1096 read_buffer_->SetCapacity(offset + size); | 1085 read_buffer_->SetCapacity(offset + size); |
1097 memcpy(read_buffer_->StartOfBuffer() + offset, data.data(), size); | 1086 memcpy(read_buffer_->StartOfBuffer() + offset, data.data(), size); |
1098 read_buffer_->set_offset(offset + size); | 1087 read_buffer_->set_offset(offset + size); |
1099 } | 1088 } |
1100 | 1089 |
1101 void AddRead(const std::string& data) { | 1090 void AddRead(const std::string& data) { |
1102 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data())); | 1091 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data())); |
1103 } | 1092 } |
1104 | 1093 |
1105 void SetupParserAndSendRequest() { | 1094 void SetupParserAndSendRequest() { |
1106 reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF | 1095 reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF |
1107 | 1096 |
1108 data_.reset(new SequencedSocketData(&reads_.front(), reads_.size(), | 1097 data_.reset(new SequencedSocketData(&reads_.front(), reads_.size(), |
1109 &writes_.front(), writes_.size())); | 1098 &writes_.front(), writes_.size())); |
1110 socket_handle_ = CreateConnectedSocketHandle(data_.get()); | 1099 socket_handle_ = CreateConnectedSocketHandle(data_.get()); |
1111 | 1100 |
1112 request_info_.method = "GET"; | 1101 request_info_.method = "GET"; |
1113 request_info_.url = url_; | 1102 request_info_.url = GURL("http://localhost"); |
1114 request_info_.load_flags = LOAD_NORMAL; | 1103 request_info_.load_flags = LOAD_NORMAL; |
1115 | 1104 |
1116 parser_.reset(new HttpStreamParser( | 1105 parser_.reset(new HttpStreamParser( |
1117 socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog())); | 1106 socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog())); |
1118 | 1107 |
1119 parser_->set_http_09_on_non_default_ports_enabled( | |
1120 http_09_on_non_default_ports_enabled_); | |
1121 | |
1122 TestCompletionCallback callback; | 1108 TestCompletionCallback callback; |
1123 ASSERT_EQ(OK, parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_, | 1109 ASSERT_EQ(OK, parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_, |
1124 &response_info_, callback.callback())); | 1110 &response_info_, callback.callback())); |
1125 } | 1111 } |
1126 | 1112 |
1127 void ReadHeadersExpectingError(Error error) { | 1113 void ReadHeaders() { |
1128 TestCompletionCallback callback; | 1114 TestCompletionCallback callback; |
1129 EXPECT_THAT(parser_->ReadResponseHeaders(callback.callback()), | 1115 EXPECT_THAT(parser_->ReadResponseHeaders(callback.callback()), IsOk()); |
1130 IsError(error)); | |
1131 } | 1116 } |
1132 | 1117 |
1133 void ReadHeaders() { ReadHeadersExpectingError(OK); } | |
1134 | |
1135 void ReadBody(int user_buf_len, int* read_lengths) { | 1118 void ReadBody(int user_buf_len, int* read_lengths) { |
1136 TestCompletionCallback callback; | 1119 TestCompletionCallback callback; |
1137 scoped_refptr<IOBuffer> buffer = new IOBuffer(user_buf_len); | 1120 scoped_refptr<IOBuffer> buffer = new IOBuffer(user_buf_len); |
1138 int rv; | 1121 int rv; |
1139 int i = 0; | 1122 int i = 0; |
1140 while (true) { | 1123 while (true) { |
1141 rv = parser_->ReadResponseBody( | 1124 rv = parser_->ReadResponseBody( |
1142 buffer.get(), user_buf_len, callback.callback()); | 1125 buffer.get(), user_buf_len, callback.callback()); |
1143 EXPECT_EQ(read_lengths[i], rv); | 1126 EXPECT_EQ(read_lengths[i], rv); |
1144 i++; | 1127 i++; |
1145 if (rv <= 0) | 1128 if (rv <= 0) |
1146 return; | 1129 return; |
1147 } | 1130 } |
1148 } | 1131 } |
1149 | 1132 |
1150 private: | 1133 private: |
1151 GURL url_; | |
1152 bool http_09_on_non_default_ports_enabled_; | |
1153 | |
1154 HttpRequestHeaders request_headers_; | 1134 HttpRequestHeaders request_headers_; |
1155 HttpResponseInfo response_info_; | 1135 HttpResponseInfo response_info_; |
1156 HttpRequestInfo request_info_; | 1136 HttpRequestInfo request_info_; |
1157 scoped_refptr<GrowableIOBuffer> read_buffer_; | 1137 scoped_refptr<GrowableIOBuffer> read_buffer_; |
1158 std::vector<MockRead> reads_; | 1138 std::vector<MockRead> reads_; |
1159 std::vector<MockWrite> writes_; | 1139 std::vector<MockWrite> writes_; |
1160 std::unique_ptr<ClientSocketHandle> socket_handle_; | 1140 std::unique_ptr<ClientSocketHandle> socket_handle_; |
1161 std::unique_ptr<SequencedSocketData> data_; | 1141 std::unique_ptr<SequencedSocketData> data_; |
1162 std::unique_ptr<HttpStreamParser> parser_; | 1142 std::unique_ptr<HttpStreamParser> parser_; |
1163 int sequence_number_; | 1143 int sequence_number_; |
1164 }; | 1144 }; |
1165 | 1145 |
1166 // Test that HTTP/0.9 works as expected, only on ports where it should be | 1146 // Test that HTTP/0.9 response size is correctly calculated. |
1167 // enabled. | 1147 TEST(HttpStreamParser, ReceivedBytesNoHeaders) { |
1168 TEST(HttpStreamParser, Http09PortTests) { | 1148 std::string response = "hello\r\nworld\r\n"; |
1169 struct TestCase { | |
1170 const char* url; | |
1171 bool http_09_on_non_default_ports_enabled; | |
1172 | 1149 |
1173 // Expected result when trying to read headers. | 1150 SimpleGetRunner get_runner; |
1174 Error expected_header_error; | 1151 get_runner.AddRead(response); |
1175 }; | 1152 get_runner.SetupParserAndSendRequest(); |
1176 | 1153 get_runner.ReadHeaders(); |
1177 const TestCase kTestCases[] = { | 1154 EXPECT_EQ(0, get_runner.parser()->received_bytes()); |
1178 // Default ports should work for HTTP/0.9, regardless of whether the port | |
1179 // is explicitly specified or not. | |
1180 {"http://foo.com/", false, OK}, | |
1181 {"http://foo.com:80/", false, OK}, | |
1182 {"https://foo.com/", false, OK}, | |
1183 {"https://foo.com:443/", false, OK}, | |
1184 | |
1185 // Non-standard ports should not support HTTP/0.9, by default. | |
1186 {"http://foo.com:8080/", false, ERR_INVALID_HTTP_RESPONSE}, | |
1187 {"https://foo.com:8080/", false, ERR_INVALID_HTTP_RESPONSE}, | |
1188 {"http://foo.com:443/", false, ERR_INVALID_HTTP_RESPONSE}, | |
1189 {"https://foo.com:80/", false, ERR_INVALID_HTTP_RESPONSE}, | |
1190 | |
1191 // Allowing non-default ports should not break the default ones. | |
1192 {"http://foo.com/", true, OK}, | |
1193 {"http://foo.com:80/", true, OK}, | |
1194 {"https://foo.com/", true, OK}, | |
1195 {"https://foo.com:443/", true, OK}, | |
1196 | |
1197 // Check that non-default ports works. | |
1198 {"http://foo.com:8080/", true, OK}, | |
1199 {"https://foo.com:8080/", true, OK}, | |
1200 {"http://foo.com:443/", true, OK}, | |
1201 {"https://foo.com:80/", true, OK}, | |
1202 }; | |
1203 | |
1204 std::string response = "hello\r\nworld\r\n"; | |
1205 int response_size = response.size(); | 1155 int response_size = response.size(); |
1206 | 1156 int read_lengths[] = {response_size, 0}; |
1207 for (const auto& test_case : kTestCases) { | 1157 get_runner.ReadBody(response_size, read_lengths); |
1208 SimpleGetRunner get_runner; | 1158 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
1209 get_runner.set_url(GURL(test_case.url)); | 1159 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP0_9, |
1210 get_runner.set_http_09_on_non_default_ports_enabled( | 1160 get_runner.response_info()->connection_info); |
1211 test_case.http_09_on_non_default_ports_enabled); | |
1212 get_runner.AddRead(response); | |
1213 get_runner.SetupParserAndSendRequest(); | |
1214 | |
1215 get_runner.ReadHeadersExpectingError(test_case.expected_header_error); | |
1216 if (test_case.expected_header_error != OK) | |
1217 continue; | |
1218 | |
1219 ASSERT_TRUE(get_runner.response_info()->headers); | |
1220 EXPECT_EQ("HTTP/0.9 200 OK", | |
1221 get_runner.response_info()->headers->GetStatusLine()); | |
1222 | |
1223 EXPECT_EQ(0, get_runner.parser()->received_bytes()); | |
1224 int read_lengths[] = {response_size, 0}; | |
1225 get_runner.ReadBody(response_size, read_lengths); | |
1226 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | |
1227 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP0_9, | |
1228 get_runner.response_info()->connection_info); | |
1229 } | |
1230 } | |
1231 | |
1232 // Make sure that HTTP/0.9 isn't allowed in the truncated header case on a weird | |
1233 // port. | |
1234 TEST(HttpStreamParser, Http09TruncatedHeaderPortTest) { | |
1235 SimpleGetRunner get_runner; | |
1236 get_runner.set_url(GURL("http://foo.com:8080/")); | |
1237 get_runner.AddRead("HT"); | |
1238 get_runner.SetupParserAndSendRequest(); | |
1239 | |
1240 get_runner.ReadHeadersExpectingError(ERR_INVALID_HTTP_RESPONSE); | |
1241 } | 1161 } |
1242 | 1162 |
1243 // Test basic case where there is no keep-alive or extra data from the socket, | 1163 // Test basic case where there is no keep-alive or extra data from the socket, |
1244 // and the entire response is received in a single read. | 1164 // and the entire response is received in a single read. |
1245 TEST(HttpStreamParser, ReceivedBytesNormal) { | 1165 TEST(HttpStreamParser, ReceivedBytesNormal) { |
1246 std::string headers = | 1166 std::string headers = |
1247 "HTTP/1.0 200 OK\r\n" | 1167 "HTTP/1.0 200 OK\r\n" |
1248 "Content-Length: 7\r\n\r\n"; | 1168 "Content-Length: 7\r\n\r\n"; |
1249 std::string body = "content"; | 1169 std::string body = "content"; |
1250 std::string response = headers + body; | 1170 std::string response = headers + body; |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1504 ASSERT_EQ(kBodySize, parser.ReadResponseBody( | 1424 ASSERT_EQ(kBodySize, parser.ReadResponseBody( |
1505 body_buffer.get(), kBodySize, callback.callback())); | 1425 body_buffer.get(), kBodySize, callback.callback())); |
1506 | 1426 |
1507 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 1427 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
1508 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); | 1428 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
1509 } | 1429 } |
1510 | 1430 |
1511 } // namespace | 1431 } // namespace |
1512 | 1432 |
1513 } // namespace net | 1433 } // namespace net |
OLD | NEW |