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

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

Issue 2648553002: HttpServer::ParseHeaders: don't DCHECK on bogus headers termination (Closed)
Patch Set: HttpServer::ParseHeaders: don't DCHECK on bogus headers termination (Rather handle it as a parse fa… 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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