Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 scoped_refptr<DrainableIOBuffer> write_buffer_; | 184 scoped_refptr<DrainableIOBuffer> write_buffer_; |
| 185 std::unique_ptr<TCPClientSocket> socket_; | 185 std::unique_ptr<TCPClientSocket> socket_; |
| 186 int connect_result_; | 186 int connect_result_; |
| 187 }; | 187 }; |
| 188 | 188 |
| 189 } // namespace | 189 } // namespace |
| 190 | 190 |
| 191 class HttpServerTest : public testing::Test, | 191 class HttpServerTest : public testing::Test, |
| 192 public HttpServer::Delegate { | 192 public HttpServer::Delegate { |
| 193 public: | 193 public: |
| 194 HttpServerTest() : quit_after_request_count_(0) {} | 194 HttpServerTest() |
| 195 : quit_after_request_count_(0), quit_on_close_connection_(-1) {} | |
| 195 | 196 |
| 196 void SetUp() override { | 197 void SetUp() override { |
| 197 std::unique_ptr<ServerSocket> server_socket( | 198 std::unique_ptr<ServerSocket> server_socket( |
| 198 new TCPServerSocket(NULL, NetLogSource())); | 199 new TCPServerSocket(NULL, NetLogSource())); |
| 199 server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1); | 200 server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1); |
| 200 server_.reset(new HttpServer(std::move(server_socket), this)); | 201 server_.reset(new HttpServer(std::move(server_socket), this)); |
| 201 ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk()); | 202 ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk()); |
| 202 } | 203 } |
| 203 | 204 |
| 204 void OnConnect(int connection_id) override { | 205 void OnConnect(int connection_id) override { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 218 NOTREACHED(); | 219 NOTREACHED(); |
| 219 } | 220 } |
| 220 | 221 |
| 221 void OnWebSocketMessage(int connection_id, const std::string& data) override { | 222 void OnWebSocketMessage(int connection_id, const std::string& data) override { |
| 222 NOTREACHED(); | 223 NOTREACHED(); |
| 223 } | 224 } |
| 224 | 225 |
| 225 void OnClose(int connection_id) override { | 226 void OnClose(int connection_id) override { |
| 226 DCHECK(connection_map_.find(connection_id) != connection_map_.end()); | 227 DCHECK(connection_map_.find(connection_id) != connection_map_.end()); |
| 227 connection_map_[connection_id] = false; | 228 connection_map_[connection_id] = false; |
| 229 if (connection_id == quit_on_close_connection_) { | |
| 230 // Once we return, some DeleteSoon's may be posted, so we want to delay | |
| 231 // exiting the test's event loop until right after that. | |
| 232 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 233 FROM_HERE, run_loop_quit_func_, base::TimeDelta::FromMilliseconds(1)); | |
|
mmenke
2017/01/20 15:55:11
Not a fan of this sort of fuziness, particularly i
Maks Orlovich
2017/01/20 16:38:28
That is a nicer option, indeed. Did that (in TearD
| |
| 234 } | |
| 228 } | 235 } |
| 229 | 236 |
| 230 bool RunUntilRequestsReceived(size_t count) { | 237 bool RunUntilRequestsReceived(size_t count) { |
| 231 quit_after_request_count_ = count; | 238 quit_after_request_count_ = count; |
| 232 if (requests_.size() == count) | 239 if (requests_.size() == count) |
| 233 return true; | 240 return true; |
| 234 | 241 |
| 235 base::RunLoop run_loop; | 242 base::RunLoop run_loop; |
| 236 run_loop_quit_func_ = run_loop.QuitClosure(); | 243 run_loop_quit_func_ = run_loop.QuitClosure(); |
| 237 bool success = RunLoopWithTimeout(&run_loop); | 244 bool success = RunLoopWithTimeout(&run_loop); |
| 238 run_loop_quit_func_.Reset(); | 245 run_loop_quit_func_.Reset(); |
| 239 return success; | 246 return success; |
| 240 } | 247 } |
| 241 | 248 |
| 249 bool RunUntilConnectionIdClosed(int connection_id) { | |
| 250 quit_on_close_connection_ = connection_id; | |
| 251 auto iter = connection_map_.find(connection_id); | |
| 252 if (iter != connection_map_.end() && !iter->second) { | |
| 253 // Already disconnected | |
| 254 return true; | |
| 255 } | |
| 256 | |
| 257 base::RunLoop run_loop; | |
| 258 run_loop_quit_func_ = run_loop.QuitClosure(); | |
| 259 bool success = RunLoopWithTimeout(&run_loop); | |
| 260 run_loop_quit_func_.Reset(); | |
| 261 return success; | |
| 262 } | |
| 263 | |
| 242 HttpServerRequestInfo GetRequest(size_t request_index) { | 264 HttpServerRequestInfo GetRequest(size_t request_index) { |
| 243 return requests_[request_index].first; | 265 return requests_[request_index].first; |
| 244 } | 266 } |
| 245 | 267 |
| 268 size_t GetNumRequests() { return requests_.size(); } | |
|
mmenke
2017/01/20 15:55:11
optional nit: Think it's a little more common to
mmenke
2017/01/20 15:55:11
nit const
Maks Orlovich
2017/01/20 16:38:28
Done.
Maks Orlovich
2017/01/20 16:38:28
Done.
| |
| 269 | |
| 246 int GetConnectionId(size_t request_index) { | 270 int GetConnectionId(size_t request_index) { |
| 247 return requests_[request_index].second; | 271 return requests_[request_index].second; |
| 248 } | 272 } |
| 249 | 273 |
| 250 void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) { | 274 void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) { |
| 251 server_->accepted_socket_ = std::move(socket); | 275 server_->accepted_socket_ = std::move(socket); |
| 252 server_->HandleAcceptResult(OK); | 276 server_->HandleAcceptResult(OK); |
| 253 } | 277 } |
| 254 | 278 |
| 255 std::unordered_map<int, bool>& connection_map() { return connection_map_; } | 279 std::unordered_map<int, bool>& connection_map() { return connection_map_; } |
| 256 | 280 |
| 257 protected: | 281 protected: |
| 258 std::unique_ptr<HttpServer> server_; | 282 std::unique_ptr<HttpServer> server_; |
| 259 IPEndPoint server_address_; | 283 IPEndPoint server_address_; |
| 260 base::Closure run_loop_quit_func_; | 284 base::Closure run_loop_quit_func_; |
| 261 std::vector<std::pair<HttpServerRequestInfo, int> > requests_; | 285 std::vector<std::pair<HttpServerRequestInfo, int> > requests_; |
| 262 std::unordered_map<int /* connection_id */, bool /* connected */> | 286 std::unordered_map<int /* connection_id */, bool /* connected */> |
| 263 connection_map_; | 287 connection_map_; |
| 264 | 288 |
| 265 private: | 289 private: |
| 266 size_t quit_after_request_count_; | 290 size_t quit_after_request_count_; |
| 291 int quit_on_close_connection_; | |
| 267 }; | 292 }; |
| 268 | 293 |
| 269 namespace { | 294 namespace { |
| 270 | 295 |
| 271 class WebSocketTest : public HttpServerTest { | 296 class WebSocketTest : public HttpServerTest { |
| 272 void OnHttpRequest(int connection_id, | 297 void OnHttpRequest(int connection_id, |
| 273 const HttpServerRequestInfo& info) override { | 298 const HttpServerRequestInfo& info) override { |
| 274 NOTREACHED(); | 299 NOTREACHED(); |
| 275 } | 300 } |
| 276 | 301 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 289 client.Send("GET /test HTTP/1.1\r\n\r\n"); | 314 client.Send("GET /test HTTP/1.1\r\n\r\n"); |
| 290 ASSERT_TRUE(RunUntilRequestsReceived(1)); | 315 ASSERT_TRUE(RunUntilRequestsReceived(1)); |
| 291 ASSERT_EQ("GET", GetRequest(0).method); | 316 ASSERT_EQ("GET", GetRequest(0).method); |
| 292 ASSERT_EQ("/test", GetRequest(0).path); | 317 ASSERT_EQ("/test", GetRequest(0).path); |
| 293 ASSERT_EQ("", GetRequest(0).data); | 318 ASSERT_EQ("", GetRequest(0).data); |
| 294 ASSERT_EQ(0u, GetRequest(0).headers.size()); | 319 ASSERT_EQ(0u, GetRequest(0).headers.size()); |
| 295 ASSERT_TRUE(base::StartsWith(GetRequest(0).peer.ToString(), "127.0.0.1", | 320 ASSERT_TRUE(base::StartsWith(GetRequest(0).peer.ToString(), "127.0.0.1", |
| 296 base::CompareCase::SENSITIVE)); | 321 base::CompareCase::SENSITIVE)); |
| 297 } | 322 } |
| 298 | 323 |
| 324 TEST_F(HttpServerTest, RequestBrokenTermination) { | |
| 325 TestHttpClient client; | |
| 326 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); | |
| 327 client.Send("GET /test HTTP/1.1\r\n\r)"); | |
| 328 ASSERT_TRUE(RunUntilConnectionIdClosed(1)); | |
| 329 EXPECT_EQ(0u, GetNumRequests()); | |
|
mmenke
2017/01/20 15:55:11
Wait for the client socket to be closed, and verif
Maks Orlovich
2017/01/20 16:38:28
WrongProtocolRequest did that, so I factored out a
| |
| 330 } | |
| 331 | |
| 299 TEST_F(HttpServerTest, RequestWithHeaders) { | 332 TEST_F(HttpServerTest, RequestWithHeaders) { |
| 300 TestHttpClient client; | 333 TestHttpClient client; |
| 301 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); | 334 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); |
| 302 const char* const kHeaders[][3] = { | 335 const char* const kHeaders[][3] = { |
| 303 {"Header", ": ", "1"}, | 336 {"Header", ": ", "1"}, |
| 304 {"HeaderWithNoWhitespace", ":", "1"}, | 337 {"HeaderWithNoWhitespace", ":", "1"}, |
| 305 {"HeaderWithWhitespace", " : \t ", "1 1 1 \t "}, | 338 {"HeaderWithWhitespace", " : \t ", "1 1 1 \t "}, |
| 306 {"HeaderWithColon", ": ", "1:1"}, | 339 {"HeaderWithColon", ": ", "1:1"}, |
| 307 {"EmptyHeader", ":", ""}, | 340 {"EmptyHeader", ":", ""}, |
| 308 {"EmptyHeaderWithWhitespace", ": \t ", ""}, | 341 {"EmptyHeaderWithWhitespace", ": \t ", ""}, |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); | 732 ASSERT_THAT(client.ConnectAndWait(server_address_), IsOk()); |
| 700 client.Send("GET / HTTP/1.1\r\n\r\n"); | 733 client.Send("GET / HTTP/1.1\r\n\r\n"); |
| 701 ASSERT_FALSE(RunUntilRequestsReceived(1)); | 734 ASSERT_FALSE(RunUntilRequestsReceived(1)); |
| 702 ASSERT_EQ(1ul, connection_ids_.size()); | 735 ASSERT_EQ(1ul, connection_ids_.size()); |
| 703 ASSERT_EQ(0ul, requests_.size()); | 736 ASSERT_EQ(0ul, requests_.size()); |
| 704 } | 737 } |
| 705 | 738 |
| 706 } // namespace | 739 } // namespace |
| 707 | 740 |
| 708 } // namespace net | 741 } // namespace net |
| OLD | NEW |