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

Side by Side Diff: net/server/http_server_unittest.cc

Issue 2648553002: HttpServer::ParseHeaders: don't DCHECK on bogus headers termination (Closed)
Patch Set: Remove test that doesn't belong in this CL. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/server/http_server.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/server/http_server.h" 5 #include "net/server/http_server.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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 return false; 126 return false;
127 while (!IsCompleteResponse(*message)) { 127 while (!IsCompleteResponse(*message)) {
128 std::string chunk; 128 std::string chunk;
129 if (!Read(&chunk, 1)) 129 if (!Read(&chunk, 1))
130 return false; 130 return false;
131 message->append(chunk); 131 message->append(chunk);
132 } 132 }
133 return true; 133 return true;
134 } 134 }
135 135
136 bool TestUsedThenDisconnectedWithNoData() {
mmenke 2017/01/20 18:20:57 Rather than a bool, suggest: void ExpectUsedThenD
Maks Orlovich 2017/01/20 19:00:20 Done.
137 // Check that the socket was opened...
138 if (!socket_->WasEverUsed()) {
139 return false;
140 }
mmenke 2017/01/20 18:20:57 nit: No braces when if + body take up one line ea
Maks Orlovich 2017/01/20 19:00:20 Made moot by above.
141
142 // ...then closed when the server disconnected. Verify that the socket was
143 // closed by checking that a Read() fails.
144 std::string response;
145 if (Read(&response, 1u)) {
146 return false;
147 }
mmenke 2017/01/20 18:20:57 nit: --braces
Maks Orlovich 2017/01/20 19:00:20 Likewise
148
149 return response.empty();
150 }
151
136 TCPClientSocket& socket() { return *socket_; } 152 TCPClientSocket& socket() { return *socket_; }
137 153
138 private: 154 private:
139 void OnConnect(const base::Closure& quit_loop, int result) { 155 void OnConnect(const base::Closure& quit_loop, int result) {
140 connect_result_ = result; 156 connect_result_ = result;
141 quit_loop.Run(); 157 quit_loop.Run();
142 } 158 }
143 159
144 void Write() { 160 void Write() {
145 int result = socket_->Write( 161 int result = socket_->Write(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 scoped_refptr<DrainableIOBuffer> write_buffer_; 200 scoped_refptr<DrainableIOBuffer> write_buffer_;
185 std::unique_ptr<TCPClientSocket> socket_; 201 std::unique_ptr<TCPClientSocket> socket_;
186 int connect_result_; 202 int connect_result_;
187 }; 203 };
188 204
189 } // namespace 205 } // namespace
190 206
191 class HttpServerTest : public testing::Test, 207 class HttpServerTest : public testing::Test,
192 public HttpServer::Delegate { 208 public HttpServer::Delegate {
193 public: 209 public:
194 HttpServerTest() : quit_after_request_count_(0) {} 210 HttpServerTest()
211 : quit_after_request_count_(0), quit_on_close_connection_(-1) {}
195 212
196 void SetUp() override { 213 void SetUp() override {
197 std::unique_ptr<ServerSocket> server_socket( 214 std::unique_ptr<ServerSocket> server_socket(
198 new TCPServerSocket(NULL, NetLogSource())); 215 new TCPServerSocket(NULL, NetLogSource()));
199 server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1); 216 server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1);
200 server_.reset(new HttpServer(std::move(server_socket), this)); 217 server_.reset(new HttpServer(std::move(server_socket), this));
201 ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk()); 218 ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk());
202 } 219 }
203 220
221 void TearDown() override {
222 // We need to run the event loop some to make sure that the memory
mmenke 2017/01/20 18:20:57 nit: Avoid "we" in comments - it's a bit ambiguou
Maks Orlovich 2017/01/20 19:00:20 Done.
223 // handed over to DeleteSoon gets fully freed.
224 base::RunLoop().RunUntilIdle();
225 }
226
204 void OnConnect(int connection_id) override { 227 void OnConnect(int connection_id) override {
205 DCHECK(connection_map_.find(connection_id) == connection_map_.end()); 228 DCHECK(connection_map_.find(connection_id) == connection_map_.end());
206 connection_map_[connection_id] = true; 229 connection_map_[connection_id] = true;
207 } 230 }
208 231
209 void OnHttpRequest(int connection_id, 232 void OnHttpRequest(int connection_id,
210 const HttpServerRequestInfo& info) override { 233 const HttpServerRequestInfo& info) override {
211 requests_.push_back(std::make_pair(info, connection_id)); 234 requests_.push_back(std::make_pair(info, connection_id));
212 if (requests_.size() == quit_after_request_count_) 235 if (requests_.size() == quit_after_request_count_)
213 run_loop_quit_func_.Run(); 236 run_loop_quit_func_.Run();
214 } 237 }
215 238
216 void OnWebSocketRequest(int connection_id, 239 void OnWebSocketRequest(int connection_id,
217 const HttpServerRequestInfo& info) override { 240 const HttpServerRequestInfo& info) override {
218 NOTREACHED(); 241 NOTREACHED();
219 } 242 }
220 243
221 void OnWebSocketMessage(int connection_id, const std::string& data) override { 244 void OnWebSocketMessage(int connection_id, const std::string& data) override {
222 NOTREACHED(); 245 NOTREACHED();
223 } 246 }
224 247
225 void OnClose(int connection_id) override { 248 void OnClose(int connection_id) override {
226 DCHECK(connection_map_.find(connection_id) != connection_map_.end()); 249 DCHECK(connection_map_.find(connection_id) != connection_map_.end());
227 connection_map_[connection_id] = false; 250 connection_map_[connection_id] = false;
251 if (connection_id == quit_on_close_connection_) {
252 run_loop_quit_func_.Run();
253 }
mmenke 2017/01/20 18:20:57 nit: --braces
Maks Orlovich 2017/01/20 19:00:20 Done.
228 } 254 }
229 255
230 bool RunUntilRequestsReceived(size_t count) { 256 bool RunUntilRequestsReceived(size_t count) {
231 quit_after_request_count_ = count; 257 quit_after_request_count_ = count;
232 if (requests_.size() == count) 258 if (requests_.size() == count)
233 return true; 259 return true;
234 260
235 base::RunLoop run_loop; 261 base::RunLoop run_loop;
236 run_loop_quit_func_ = run_loop.QuitClosure(); 262 run_loop_quit_func_ = run_loop.QuitClosure();
237 bool success = RunLoopWithTimeout(&run_loop); 263 bool success = RunLoopWithTimeout(&run_loop);
238 run_loop_quit_func_.Reset(); 264 run_loop_quit_func_.Reset();
239 return success; 265 return success;
240 } 266 }
241 267
268 bool RunUntilConnectionIdClosed(int connection_id) {
269 quit_on_close_connection_ = connection_id;
270 auto iter = connection_map_.find(connection_id);
271 if (iter != connection_map_.end() && !iter->second) {
272 // Already disconnected
mmenke 2017/01/20 18:20:57 nit: Predominant style is to send more comment-y
Maks Orlovich 2017/01/20 19:00:20 Done.
273 return true;
274 }
275
276 base::RunLoop run_loop;
277 run_loop_quit_func_ = run_loop.QuitClosure();
278 bool success = RunLoopWithTimeout(&run_loop);
279 run_loop_quit_func_.Reset();
280 return success;
281 }
282
242 HttpServerRequestInfo GetRequest(size_t request_index) { 283 HttpServerRequestInfo GetRequest(size_t request_index) {
243 return requests_[request_index].first; 284 return requests_[request_index].first;
244 } 285 }
245 286
287 size_t num_requests() const { return requests_.size(); }
288
246 int GetConnectionId(size_t request_index) { 289 int GetConnectionId(size_t request_index) {
247 return requests_[request_index].second; 290 return requests_[request_index].second;
248 } 291 }
249 292
250 void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) { 293 void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) {
251 server_->accepted_socket_ = std::move(socket); 294 server_->accepted_socket_ = std::move(socket);
252 server_->HandleAcceptResult(OK); 295 server_->HandleAcceptResult(OK);
253 } 296 }
254 297
255 std::unordered_map<int, bool>& connection_map() { return connection_map_; } 298 std::unordered_map<int, bool>& connection_map() { return connection_map_; }
256 299
257 protected: 300 protected:
258 std::unique_ptr<HttpServer> server_; 301 std::unique_ptr<HttpServer> server_;
259 IPEndPoint server_address_; 302 IPEndPoint server_address_;
260 base::Closure run_loop_quit_func_; 303 base::Closure run_loop_quit_func_;
261 std::vector<std::pair<HttpServerRequestInfo, int> > requests_; 304 std::vector<std::pair<HttpServerRequestInfo, int> > requests_;
262 std::unordered_map<int /* connection_id */, bool /* connected */> 305 std::unordered_map<int /* connection_id */, bool /* connected */>
263 connection_map_; 306 connection_map_;
264 307
265 private: 308 private:
266 size_t quit_after_request_count_; 309 size_t quit_after_request_count_;
310 int quit_on_close_connection_;
267 }; 311 };
268 312
269 namespace { 313 namespace {
270 314
271 class WebSocketTest : public HttpServerTest { 315 class WebSocketTest : public HttpServerTest {
272 void OnHttpRequest(int connection_id, 316 void OnHttpRequest(int connection_id,
273 const HttpServerRequestInfo& info) override { 317 const HttpServerRequestInfo& info) override {
274 NOTREACHED(); 318 NOTREACHED();
275 } 319 }
276 320
(...skipping 12 matching lines...) Expand all
289 client.Send("GET /test HTTP/1.1\r\n\r\n"); 333 client.Send("GET /test HTTP/1.1\r\n\r\n");
290 ASSERT_TRUE(RunUntilRequestsReceived(1)); 334 ASSERT_TRUE(RunUntilRequestsReceived(1));
291 ASSERT_EQ("GET", GetRequest(0).method); 335 ASSERT_EQ("GET", GetRequest(0).method);
292 ASSERT_EQ("/test", GetRequest(0).path); 336 ASSERT_EQ("/test", GetRequest(0).path);
293 ASSERT_EQ("", GetRequest(0).data); 337 ASSERT_EQ("", GetRequest(0).data);
294 ASSERT_EQ(0u, GetRequest(0).headers.size()); 338 ASSERT_EQ(0u, GetRequest(0).headers.size());
295 ASSERT_TRUE(base::StartsWith(GetRequest(0).peer.ToString(), "127.0.0.1", 339 ASSERT_TRUE(base::StartsWith(GetRequest(0).peer.ToString(), "127.0.0.1",
296 base::CompareCase::SENSITIVE)); 340 base::CompareCase::SENSITIVE));
297 } 341 }
298 342
343 TEST_F(HttpServerTest, RequestBrokenTermination) {
344 TestHttpClient client;
345 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk());
346 client.Send("GET /test HTTP/1.1\r\n\r)");
347 ASSERT_TRUE(RunUntilConnectionIdClosed(1));
348 EXPECT_EQ(0u, num_requests());
349 EXPECT_TRUE(client.TestUsedThenDisconnectedWithNoData());
350 }
351
299 TEST_F(HttpServerTest, RequestWithHeaders) { 352 TEST_F(HttpServerTest, RequestWithHeaders) {
300 TestHttpClient client; 353 TestHttpClient client;
301 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); 354 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk());
302 const char* const kHeaders[][3] = { 355 const char* const kHeaders[][3] = {
303 {"Header", ": ", "1"}, 356 {"Header", ": ", "1"},
304 {"HeaderWithNoWhitespace", ":", "1"}, 357 {"HeaderWithNoWhitespace", ":", "1"},
305 {"HeaderWithWhitespace", " : \t ", "1 1 1 \t "}, 358 {"HeaderWithWhitespace", " : \t ", "1 1 1 \t "},
306 {"HeaderWithColon", ": ", "1:1"}, 359 {"HeaderWithColon", ": ", "1:1"},
307 {"EmptyHeader", ":", ""}, 360 {"EmptyHeader", ":", ""},
308 {"EmptyHeaderWithWhitespace", ": \t ", ""}, 361 {"EmptyHeaderWithWhitespace", ": \t ", ""},
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 TestHttpClient client; 549 TestHttpClient client;
497 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); 550 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk());
498 551
499 client.Send(kBadProtocolRequests[i]); 552 client.Send(kBadProtocolRequests[i]);
500 ASSERT_FALSE(RunUntilRequestsReceived(1)); 553 ASSERT_FALSE(RunUntilRequestsReceived(1));
501 554
502 // Assert that the delegate was updated properly. 555 // Assert that the delegate was updated properly.
503 ASSERT_EQ(1u, connection_map().size()); 556 ASSERT_EQ(1u, connection_map().size());
504 ASSERT_FALSE(connection_map().begin()->second); 557 ASSERT_FALSE(connection_map().begin()->second);
505 558
506 // Assert that the socket was opened... 559 ASSERT_TRUE(client.TestUsedThenDisconnectedWithNoData());
507 ASSERT_TRUE(client.socket().WasEverUsed());
508
509 // ...then closed when the server disconnected. Verify that the socket was
510 // closed by checking that a Read() fails.
511 std::string response;
512 ASSERT_FALSE(client.Read(&response, 1u));
513 ASSERT_EQ(std::string(), response);
514 560
515 // Reset the state of the connection map. 561 // Reset the state of the connection map.
516 connection_map().clear(); 562 connection_map().clear();
517 } 563 }
518 } 564 }
519 565
520 class MockStreamSocket : public StreamSocket { 566 class MockStreamSocket : public StreamSocket {
521 public: 567 public:
522 MockStreamSocket() 568 MockStreamSocket()
523 : connected_(true), 569 : connected_(true),
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); 745 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk());
700 client.Send("GET / HTTP/1.1\r\n\r\n"); 746 client.Send("GET / HTTP/1.1\r\n\r\n");
701 ASSERT_FALSE(RunUntilRequestsReceived(1)); 747 ASSERT_FALSE(RunUntilRequestsReceived(1));
702 ASSERT_EQ(1ul, connection_ids_.size()); 748 ASSERT_EQ(1ul, connection_ids_.size());
703 ASSERT_EQ(0ul, requests_.size()); 749 ASSERT_EQ(0ul, requests_.size());
704 } 750 }
705 751
706 } // namespace 752 } // namespace
707 753
708 } // namespace net 754 } // namespace net
OLDNEW
« no previous file with comments | « net/server/http_server.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698