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

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

Issue 2314073003: Handle non-HTTP/1.1 requests more gracefully in net::HttpServer. (Closed)
Patch Set: More tests Created 4 years, 3 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
« net/server/http_server.cc ('K') | « 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 return false; 125 return false;
126 while (!IsCompleteResponse(*message)) { 126 while (!IsCompleteResponse(*message)) {
127 std::string chunk; 127 std::string chunk;
128 if (!Read(&chunk, 1)) 128 if (!Read(&chunk, 1))
129 return false; 129 return false;
130 message->append(chunk); 130 message->append(chunk);
131 } 131 }
132 return true; 132 return true;
133 } 133 }
134 134
135 TCPClientSocket& socket() { return *socket_; }
136
135 private: 137 private:
136 void OnConnect(const base::Closure& quit_loop, int result) { 138 void OnConnect(const base::Closure& quit_loop, int result) {
137 connect_result_ = result; 139 connect_result_ = result;
138 quit_loop.Run(); 140 quit_loop.Run();
139 } 141 }
140 142
141 void Write() { 143 void Write() {
142 int result = socket_->Write( 144 int result = socket_->Write(
143 write_buffer_.get(), 145 write_buffer_.get(),
144 write_buffer_->BytesRemaining(), 146 write_buffer_->BytesRemaining(),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 HttpServerTest() : quit_after_request_count_(0) {} 193 HttpServerTest() : quit_after_request_count_(0) {}
192 194
193 void SetUp() override { 195 void SetUp() override {
194 std::unique_ptr<ServerSocket> server_socket( 196 std::unique_ptr<ServerSocket> server_socket(
195 new TCPServerSocket(NULL, NetLog::Source())); 197 new TCPServerSocket(NULL, NetLog::Source()));
196 server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1); 198 server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1);
197 server_.reset(new HttpServer(std::move(server_socket), this)); 199 server_.reset(new HttpServer(std::move(server_socket), this));
198 ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk()); 200 ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk());
199 } 201 }
200 202
201 void OnConnect(int connection_id) override {} 203 void OnConnect(int connection_id) override {
204 DCHECK(connection_map_.find(connection_id) == connection_map_.end());
205 connection_map_[connection_id] = true;
206 }
202 207
203 void OnHttpRequest(int connection_id, 208 void OnHttpRequest(int connection_id,
204 const HttpServerRequestInfo& info) override { 209 const HttpServerRequestInfo& info) override {
205 requests_.push_back(std::make_pair(info, connection_id)); 210 requests_.push_back(std::make_pair(info, connection_id));
206 if (requests_.size() == quit_after_request_count_) 211 if (requests_.size() == quit_after_request_count_)
207 run_loop_quit_func_.Run(); 212 run_loop_quit_func_.Run();
208 } 213 }
209 214
210 void OnWebSocketRequest(int connection_id, 215 void OnWebSocketRequest(int connection_id,
211 const HttpServerRequestInfo& info) override { 216 const HttpServerRequestInfo& info) override {
212 NOTREACHED(); 217 NOTREACHED();
213 } 218 }
214 219
215 void OnWebSocketMessage(int connection_id, const std::string& data) override { 220 void OnWebSocketMessage(int connection_id, const std::string& data) override {
216 NOTREACHED(); 221 NOTREACHED();
217 } 222 }
218 223
219 void OnClose(int connection_id) override {} 224 void OnClose(int connection_id) override {
225 DCHECK(connection_map_.find(connection_id) != connection_map_.end());
226 connection_map_[connection_id] = false;
227 }
220 228
221 bool RunUntilRequestsReceived(size_t count) { 229 bool RunUntilRequestsReceived(size_t count) {
222 quit_after_request_count_ = count; 230 quit_after_request_count_ = count;
223 if (requests_.size() == count) 231 if (requests_.size() == count)
224 return true; 232 return true;
225 233
226 base::RunLoop run_loop; 234 base::RunLoop run_loop;
227 run_loop_quit_func_ = run_loop.QuitClosure(); 235 run_loop_quit_func_ = run_loop.QuitClosure();
228 bool success = RunLoopWithTimeout(&run_loop); 236 bool success = RunLoopWithTimeout(&run_loop);
229 run_loop_quit_func_.Reset(); 237 run_loop_quit_func_.Reset();
230 return success; 238 return success;
231 } 239 }
232 240
233 HttpServerRequestInfo GetRequest(size_t request_index) { 241 HttpServerRequestInfo GetRequest(size_t request_index) {
234 return requests_[request_index].first; 242 return requests_[request_index].first;
235 } 243 }
236 244
237 int GetConnectionId(size_t request_index) { 245 int GetConnectionId(size_t request_index) {
238 return requests_[request_index].second; 246 return requests_[request_index].second;
239 } 247 }
240 248
241 void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) { 249 void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) {
242 server_->accepted_socket_.reset(socket.release()); 250 server_->accepted_socket_.reset(socket.release());
243 server_->HandleAcceptResult(OK); 251 server_->HandleAcceptResult(OK);
244 } 252 }
245 253
254 std::unordered_map<int, bool>& connection_map() { return connection_map_; }
255
246 protected: 256 protected:
247 std::unique_ptr<HttpServer> server_; 257 std::unique_ptr<HttpServer> server_;
248 IPEndPoint server_address_; 258 IPEndPoint server_address_;
249 base::Closure run_loop_quit_func_; 259 base::Closure run_loop_quit_func_;
250 std::vector<std::pair<HttpServerRequestInfo, int> > requests_; 260 std::vector<std::pair<HttpServerRequestInfo, int> > requests_;
261 std::unordered_map<int /* connection_id */, bool /* connected */>
262 connection_map_;
251 263
252 private: 264 private:
253 size_t quit_after_request_count_; 265 size_t quit_after_request_count_;
254 }; 266 };
255 267
256 namespace { 268 namespace {
257 269
258 class WebSocketTest : public HttpServerTest { 270 class WebSocketTest : public HttpServerTest {
259 void OnHttpRequest(int connection_id, 271 void OnHttpRequest(int connection_id,
260 const HttpServerRequestInfo& info) override { 272 const HttpServerRequestInfo& info) override {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 server_->SendRaw(GetConnectionId(0), "Raw Data "); 477 server_->SendRaw(GetConnectionId(0), "Raw Data ");
466 server_->SendRaw(GetConnectionId(0), "More Data"); 478 server_->SendRaw(GetConnectionId(0), "More Data");
467 server_->SendRaw(GetConnectionId(0), "Third Piece of Data"); 479 server_->SendRaw(GetConnectionId(0), "Third Piece of Data");
468 480
469 const std::string expected_response("Raw Data More DataThird Piece of Data"); 481 const std::string expected_response("Raw Data More DataThird Piece of Data");
470 std::string response; 482 std::string response;
471 ASSERT_TRUE(client.Read(&response, expected_response.length())); 483 ASSERT_TRUE(client.Read(&response, expected_response.length()));
472 ASSERT_EQ(expected_response, response); 484 ASSERT_EQ(expected_response, response);
473 } 485 }
474 486
487 TEST_F(HttpServerTest, WrongProtocolRequest) {
488 const char* const kBadProtocolRequests[] = {
489 "GET /test HTTP/1.0\r\n\r\n",
490 "GET /test foo\r\n\r\n",
491 "GET /test \r\n\r\n",
492 };
493
494 for (size_t i = 0; i < arraysize(kBadProtocolRequests); ++i) {
495 TestHttpClient client;
496 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk());
497
498 client.Send(kBadProtocolRequests[i]);
499 ASSERT_FALSE(RunUntilRequestsReceived(1));
500
501 // Assert that the delegate was updated properly.
502 ASSERT_EQ(1u, connection_map().size());
503 ASSERT_FALSE(connection_map().begin()->second);
504
505 // Assert that the socket was opened then closed.
506 ASSERT_TRUE(client.socket().WasEverUsed());
507 ASSERT_FALSE(client.socket().IsConnected());
mmenke 2016/09/15 17:40:12 This is potentially racy - the server could exit t
slan 2016/09/16 22:35:30 Done.
508
509 // Reset the state of the connection map.
510 connection_map().clear();
511 }
512 }
513
475 class MockStreamSocket : public StreamSocket { 514 class MockStreamSocket : public StreamSocket {
476 public: 515 public:
477 MockStreamSocket() 516 MockStreamSocket()
478 : connected_(true), 517 : connected_(true),
479 read_buf_(NULL), 518 read_buf_(NULL),
480 read_buf_len_(0) {} 519 read_buf_len_(0) {}
481 520
482 // StreamSocket 521 // StreamSocket
483 int Connect(const CompletionCallback& callback) override { 522 int Connect(const CompletionCallback& callback) override {
484 return ERR_NOT_IMPLEMENTED; 523 return ERR_NOT_IMPLEMENTED;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 ASSERT_TRUE(client.ReadResponse(&response3)); 672 ASSERT_TRUE(client.ReadResponse(&response3));
634 ASSERT_TRUE(base::StartsWith(response3, "HTTP/1.1 200 OK", 673 ASSERT_TRUE(base::StartsWith(response3, "HTTP/1.1 200 OK",
635 base::CompareCase::SENSITIVE)); 674 base::CompareCase::SENSITIVE));
636 ASSERT_TRUE(base::EndsWith(response3, "Content for /test3", 675 ASSERT_TRUE(base::EndsWith(response3, "Content for /test3",
637 base::CompareCase::SENSITIVE)); 676 base::CompareCase::SENSITIVE));
638 } 677 }
639 678
640 class CloseOnConnectHttpServerTest : public HttpServerTest { 679 class CloseOnConnectHttpServerTest : public HttpServerTest {
641 public: 680 public:
642 void OnConnect(int connection_id) override { 681 void OnConnect(int connection_id) override {
682 HttpServerTest::OnConnect(connection_id);
643 connection_ids_.push_back(connection_id); 683 connection_ids_.push_back(connection_id);
644 server_->Close(connection_id); 684 server_->Close(connection_id);
645 } 685 }
646 686
647 protected: 687 protected:
648 std::vector<int> connection_ids_; 688 std::vector<int> connection_ids_;
649 }; 689 };
650 690
651 TEST_F(CloseOnConnectHttpServerTest, ServerImmediatelyClosesConnection) { 691 TEST_F(CloseOnConnectHttpServerTest, ServerImmediatelyClosesConnection) {
652 TestHttpClient client; 692 TestHttpClient client;
653 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); 693 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk());
654 client.Send("GET / HTTP/1.1\r\n\r\n"); 694 client.Send("GET / HTTP/1.1\r\n\r\n");
655 ASSERT_FALSE(RunUntilRequestsReceived(1)); 695 ASSERT_FALSE(RunUntilRequestsReceived(1));
656 ASSERT_EQ(1ul, connection_ids_.size()); 696 ASSERT_EQ(1ul, connection_ids_.size());
657 ASSERT_EQ(0ul, requests_.size()); 697 ASSERT_EQ(0ul, requests_.size());
658 } 698 }
659 699
660 } // namespace 700 } // namespace
661 701
662 } // namespace net 702 } // namespace net
OLDNEW
« net/server/http_server.cc ('K') | « net/server/http_server.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698