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

Side by Side Diff: net/http/http_stream_parser_unittest.cc

Issue 1166693004: Use SequencedSocketData in HttpStreamParserTests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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 | « no previous file | 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 (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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 25 matching lines...) Expand all
36 namespace { 36 namespace {
37 37
38 const size_t kOutputSize = 1024; // Just large enough for this test. 38 const size_t kOutputSize = 1024; // Just large enough for this test.
39 // The number of bytes that can fit in a buffer of kOutputSize. 39 // The number of bytes that can fit in a buffer of kOutputSize.
40 const size_t kMaxPayloadSize = 40 const size_t kMaxPayloadSize =
41 kOutputSize - HttpStreamParser::kChunkHeaderFooterSize; 41 kOutputSize - HttpStreamParser::kChunkHeaderFooterSize;
42 42
43 // Helper method to create a connected ClientSocketHandle using |data|. 43 // Helper method to create a connected ClientSocketHandle using |data|.
44 // Modifies |data|. 44 // Modifies |data|.
45 scoped_ptr<ClientSocketHandle> CreateConnectedSocketHandle( 45 scoped_ptr<ClientSocketHandle> CreateConnectedSocketHandle(
46 DeterministicSocketData* data) { 46 SequencedSocketData* data) {
47 data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); 47 data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
48 48
49 scoped_ptr<DeterministicMockTCPClientSocket> transport( 49 scoped_ptr<MockTCPClientSocket> socket(
50 new DeterministicMockTCPClientSocket(nullptr, data)); 50 new MockTCPClientSocket(net::AddressList(), nullptr, data));
51 data->set_delegate(transport->AsWeakPtr()); 51 data->set_socket(socket.get());
52 52
53 TestCompletionCallback callback; 53 TestCompletionCallback callback;
54 EXPECT_EQ(OK, transport->Connect(callback.callback())); 54 EXPECT_EQ(OK, socket->Connect(callback.callback()));
55 55
56 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle); 56 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
57 socket_handle->SetSocket(transport.Pass()); 57 socket_handle->SetSocket(socket.Pass());
58 return socket_handle.Pass(); 58 return socket_handle.Pass();
59 } 59 }
60 60
61 // The empty payload is how the last chunk is encoded. 61 // The empty payload is how the last chunk is encoded.
62 TEST(HttpStreamParser, EncodeChunk_EmptyPayload) { 62 TEST(HttpStreamParser, EncodeChunk_EmptyPayload) {
63 char output[kOutputSize]; 63 char output[kOutputSize];
64 64
65 const base::StringPiece kPayload = ""; 65 const base::StringPiece kPayload = "";
66 const base::StringPiece kExpected = "0\r\n\r\n"; 66 const base::StringPiece kExpected = "0\r\n\r\n";
67 const int num_bytes_written = 67 const int num_bytes_written =
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 MockRead reads[] = { 222 MockRead reads[] = {
223 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n"), 223 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n"),
224 MockRead(ASYNC, 4, "Content-Length: 8\r\n\r\n"), 224 MockRead(ASYNC, 4, "Content-Length: 8\r\n\r\n"),
225 MockRead(ASYNC, 5, "one.html"), 225 MockRead(ASYNC, 5, "one.html"),
226 MockRead(SYNCHRONOUS, 0, 6), // EOF 226 MockRead(SYNCHRONOUS, 0, 6), // EOF
227 }; 227 };
228 228
229 ChunkedUploadDataStream upload_stream(0); 229 ChunkedUploadDataStream upload_stream(0);
230 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback())); 230 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
231 231
232 DeterministicSocketData data(reads, arraysize(reads), writes, 232 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
233 arraysize(writes));
234 scoped_ptr<ClientSocketHandle> socket_handle = 233 scoped_ptr<ClientSocketHandle> socket_handle =
235 CreateConnectedSocketHandle(&data); 234 CreateConnectedSocketHandle(&data);
236 235
237 HttpRequestInfo request_info; 236 HttpRequestInfo request_info;
238 request_info.method = "GET"; 237 request_info.method = "GET";
239 request_info.url = GURL("http://localhost"); 238 request_info.url = GURL("http://localhost");
240 request_info.upload_data_stream = &upload_stream; 239 request_info.upload_data_stream = &upload_stream;
241 240
242 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 241 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
243 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), 242 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(),
244 BoundNetLog()); 243 BoundNetLog());
245 244
246 HttpRequestHeaders request_headers; 245 HttpRequestHeaders request_headers;
247 request_headers.SetHeader("Transfer-Encoding", "chunked"); 246 request_headers.SetHeader("Transfer-Encoding", "chunked");
248 247
249 HttpResponseInfo response_info; 248 HttpResponseInfo response_info;
250 TestCompletionCallback callback; 249 TestCompletionCallback callback;
251 // This will attempt to Write() the initial request and headers, which will 250 // This will attempt to Write() the initial request and headers, which will
252 // complete asynchronously. 251 // complete asynchronously.
253 ASSERT_EQ(ERR_IO_PENDING, 252 ASSERT_EQ(ERR_IO_PENDING,
254 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers, 253 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
255 &response_info, callback.callback())); 254 &response_info, callback.callback()));
256 255
257 // Complete the initial request write. 256 // Complete the initial request write. Callback should not have been invoked.
258 data.RunFor(1); 257 base::RunLoop().RunUntilIdle();
259 ASSERT_FALSE(callback.have_result()); 258 ASSERT_FALSE(callback.have_result());
260 259
261 // Now append the only chunk. 260 // Now append the only chunk and wait for the callback.
262 upload_stream.AppendData(kChunk, arraysize(kChunk) - 1, true); 261 upload_stream.AppendData(kChunk, arraysize(kChunk) - 1, true);
263 // Write the chunk.
264 data.RunFor(1);
265 ASSERT_FALSE(callback.have_result());
266
267 // Write the trailer.
268 data.RunFor(1);
269 ASSERT_TRUE(callback.have_result());
270 ASSERT_EQ(OK, callback.WaitForResult()); 262 ASSERT_EQ(OK, callback.WaitForResult());
271 263
272 // Attempt to read the response status and the response headers. 264 // Attempt to read the response status and the response headers.
273 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); 265 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback()));
274 data.RunFor(2);
275 ASSERT_TRUE(callback.have_result());
276 ASSERT_GT(callback.WaitForResult(), 0); 266 ASSERT_GT(callback.WaitForResult(), 0);
277 267
278 // Finally, attempt to read the response body. 268 // Finally, attempt to read the response body.
279 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 269 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
280 ASSERT_EQ(ERR_IO_PENDING, 270 ASSERT_EQ(ERR_IO_PENDING,
281 parser.ReadResponseBody(body_buffer.get(), kBodySize, 271 parser.ReadResponseBody(body_buffer.get(), kBodySize,
282 callback.callback())); 272 callback.callback()));
283 data.RunFor(1);
284 ASSERT_TRUE(callback.have_result());
285 ASSERT_EQ(kBodySize, callback.WaitForResult()); 273 ASSERT_EQ(kBodySize, callback.WaitForResult());
286 } 274 }
287 275
288 // Test to ensure the HttpStreamParser state machine does not get confused 276 // Test to ensure the HttpStreamParser state machine does not get confused
289 // when sending a request with a chunked body with only one chunk that is 277 // when sending a request with a chunked body with only one chunk that is
290 // available synchronously. 278 // available synchronously.
291 TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) { 279 TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) {
292 static const char kChunk[] = "Chunk"; 280 static const char kChunk[] = "Chunk";
293 281
294 MockWrite writes[] = { 282 MockWrite writes[] = {
(...skipping 13 matching lines...) Expand all
308 MockRead(ASYNC, 4, "Content-Length: 8\r\n\r\n"), 296 MockRead(ASYNC, 4, "Content-Length: 8\r\n\r\n"),
309 MockRead(ASYNC, 5, "one.html"), 297 MockRead(ASYNC, 5, "one.html"),
310 MockRead(SYNCHRONOUS, 0, 6), // EOF 298 MockRead(SYNCHRONOUS, 0, 6), // EOF
311 }; 299 };
312 300
313 ChunkedUploadDataStream upload_stream(0); 301 ChunkedUploadDataStream upload_stream(0);
314 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback())); 302 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
315 // Append the only chunk. 303 // Append the only chunk.
316 upload_stream.AppendData(kChunk, arraysize(kChunk) - 1, true); 304 upload_stream.AppendData(kChunk, arraysize(kChunk) - 1, true);
317 305
318 DeterministicSocketData data(reads, arraysize(reads), writes, 306 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
319 arraysize(writes));
320 scoped_ptr<ClientSocketHandle> socket_handle = 307 scoped_ptr<ClientSocketHandle> socket_handle =
321 CreateConnectedSocketHandle(&data); 308 CreateConnectedSocketHandle(&data);
322 309
323 HttpRequestInfo request_info; 310 HttpRequestInfo request_info;
324 request_info.method = "GET"; 311 request_info.method = "GET";
325 request_info.url = GURL("http://localhost"); 312 request_info.url = GURL("http://localhost");
326 request_info.upload_data_stream = &upload_stream; 313 request_info.upload_data_stream = &upload_stream;
327 314
328 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 315 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
329 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), 316 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(),
330 BoundNetLog()); 317 BoundNetLog());
331 318
332 HttpRequestHeaders request_headers; 319 HttpRequestHeaders request_headers;
333 request_headers.SetHeader("Transfer-Encoding", "chunked"); 320 request_headers.SetHeader("Transfer-Encoding", "chunked");
334 321
335 HttpResponseInfo response_info; 322 HttpResponseInfo response_info;
336 TestCompletionCallback callback; 323 TestCompletionCallback callback;
337 // This will attempt to Write() the initial request and headers, which will 324 // This will attempt to Write() the initial request and headers, which will
338 // complete asynchronously. 325 // complete asynchronously.
339 ASSERT_EQ(ERR_IO_PENDING, 326 ASSERT_EQ(ERR_IO_PENDING,
340 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers, 327 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
341 &response_info, callback.callback())); 328 &response_info, callback.callback()));
342
343 // Write the request and the only chunk.
344 data.RunFor(2);
345
346 // Write the trailer.
347 data.RunFor(1);
348 ASSERT_TRUE(callback.have_result());
349 ASSERT_EQ(OK, callback.WaitForResult()); 329 ASSERT_EQ(OK, callback.WaitForResult());
350 330
351 // Attempt to read the response status and the response headers. 331 // Attempt to read the response status and the response headers.
352 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); 332 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback()));
353 data.RunFor(2);
354 ASSERT_TRUE(callback.have_result());
355 ASSERT_GT(callback.WaitForResult(), 0); 333 ASSERT_GT(callback.WaitForResult(), 0);
356 334
357 // Finally, attempt to read the response body. 335 // Finally, attempt to read the response body.
358 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 336 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
359 ASSERT_EQ(ERR_IO_PENDING, 337 ASSERT_EQ(ERR_IO_PENDING,
360 parser.ReadResponseBody(body_buffer.get(), kBodySize, 338 parser.ReadResponseBody(body_buffer.get(), kBodySize,
361 callback.callback())); 339 callback.callback()));
362 data.RunFor(1);
363 ASSERT_TRUE(callback.have_result());
364 ASSERT_EQ(kBodySize, callback.WaitForResult()); 340 ASSERT_EQ(kBodySize, callback.WaitForResult());
365 } 341 }
366 342
367 // Test to ensure the HttpStreamParser state machine does not get confused 343 // Test to ensure the HttpStreamParser state machine does not get confused
368 // when sending a request with a chunked body, where chunks become available 344 // when sending a request with a chunked body, where chunks become available
369 // asynchronously, over a socket where writes may also complete 345 // asynchronously, over a socket where writes may also complete
370 // asynchronously. 346 // asynchronously.
371 // This is a regression test for http://crbug.com/132243 347 // This is a regression test for http://crbug.com/132243
372 TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) { 348 TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) {
373 // The chunks that will be written in the request, as reflected in the 349 // The chunks that will be written in the request, as reflected in the
(...skipping 20 matching lines...) Expand all
394 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"), 370 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"),
395 MockRead(ASYNC, 6, "Content-Length: 8\r\n\r\n"), 371 MockRead(ASYNC, 6, "Content-Length: 8\r\n\r\n"),
396 MockRead(ASYNC, 7, "one.html"), 372 MockRead(ASYNC, 7, "one.html"),
397 MockRead(SYNCHRONOUS, 0, 8), // EOF 373 MockRead(SYNCHRONOUS, 0, 8), // EOF
398 }; 374 };
399 375
400 ChunkedUploadDataStream upload_stream(0); 376 ChunkedUploadDataStream upload_stream(0);
401 upload_stream.AppendData(kChunk1, arraysize(kChunk1) - 1, false); 377 upload_stream.AppendData(kChunk1, arraysize(kChunk1) - 1, false);
402 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback())); 378 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
403 379
404 DeterministicSocketData data(reads, arraysize(reads), writes, 380 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
405 arraysize(writes));
406 scoped_ptr<ClientSocketHandle> socket_handle = 381 scoped_ptr<ClientSocketHandle> socket_handle =
407 CreateConnectedSocketHandle(&data); 382 CreateConnectedSocketHandle(&data);
408 383
409 HttpRequestInfo request_info; 384 HttpRequestInfo request_info;
410 request_info.method = "GET"; 385 request_info.method = "GET";
411 request_info.url = GURL("http://localhost"); 386 request_info.url = GURL("http://localhost");
412 request_info.upload_data_stream = &upload_stream; 387 request_info.upload_data_stream = &upload_stream;
413 388
414 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 389 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
415 HttpStreamParser parser( 390 HttpStreamParser parser(
416 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); 391 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog());
417 392
418 HttpRequestHeaders request_headers; 393 HttpRequestHeaders request_headers;
419 request_headers.SetHeader("Transfer-Encoding", "chunked"); 394 request_headers.SetHeader("Transfer-Encoding", "chunked");
420 395
421 HttpResponseInfo response_info; 396 HttpResponseInfo response_info;
422 TestCompletionCallback callback; 397 TestCompletionCallback callback;
423 // This will attempt to Write() the initial request and headers, which will 398 // This will attempt to Write() the initial request and headers, which will
424 // complete asynchronously. 399 // complete asynchronously.
425 ASSERT_EQ(ERR_IO_PENDING, 400 ASSERT_EQ(ERR_IO_PENDING,
426 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers, 401 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
427 &response_info, callback.callback())); 402 &response_info, callback.callback()));
428
429 // Complete the initial request write. Additionally, this should enqueue the
430 // first chunk.
431 data.RunFor(1);
432 ASSERT_FALSE(callback.have_result()); 403 ASSERT_FALSE(callback.have_result());
433 404
434 // Now append another chunk (while the first write is still pending), which 405 // Sending the request and the first chunk completes.
435 // should not confuse the state machine. 406 base::RunLoop().RunUntilIdle();
407 ASSERT_FALSE(callback.have_result());
408
409 // Now append another chunk.
436 upload_stream.AppendData(kChunk2, arraysize(kChunk2) - 1, false); 410 upload_stream.AppendData(kChunk2, arraysize(kChunk2) - 1, false);
437 ASSERT_FALSE(callback.have_result()); 411 ASSERT_FALSE(callback.have_result());
438 412
439 // Complete writing the first chunk, which should then enqueue the second 413 // Add the final chunk, while the write for the second is still pending,
440 // chunk for writing and return, because it is set to complete 414 // which should not confuse the state machine.
441 // asynchronously.
442 data.RunFor(1);
443 ASSERT_FALSE(callback.have_result());
444
445 // Complete writing the second chunk. However, because no chunks are
446 // available yet, no further writes should be called until a new chunk is
447 // added.
448 data.RunFor(1);
449 ASSERT_FALSE(callback.have_result());
450
451 // Add the final chunk. This will enqueue another write, but it will not
452 // complete due to the async nature.
453 upload_stream.AppendData(kChunk3, arraysize(kChunk3) - 1, true); 415 upload_stream.AppendData(kChunk3, arraysize(kChunk3) - 1, true);
454 ASSERT_FALSE(callback.have_result()); 416 ASSERT_FALSE(callback.have_result());
455 417
456 // Finalize writing the last chunk, which will enqueue the trailer. 418 // Wait for writes to complete.
457 data.RunFor(1);
458 ASSERT_FALSE(callback.have_result());
459
460 // Finalize writing the trailer.
461 data.RunFor(1);
462 ASSERT_TRUE(callback.have_result());
463 ASSERT_EQ(OK, callback.WaitForResult()); 419 ASSERT_EQ(OK, callback.WaitForResult());
464 420
465 // Attempt to read the response status and the response headers. 421 // Attempt to read the response status and the response headers.
466 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); 422 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback()));
467 data.RunFor(2);
468 ASSERT_TRUE(callback.have_result());
469 ASSERT_GT(callback.WaitForResult(), 0); 423 ASSERT_GT(callback.WaitForResult(), 0);
470 424
471 // Finally, attempt to read the response body. 425 // Finally, attempt to read the response body.
472 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 426 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
473 ASSERT_EQ(ERR_IO_PENDING, 427 ASSERT_EQ(ERR_IO_PENDING,
474 parser.ReadResponseBody(body_buffer.get(), kBodySize, 428 parser.ReadResponseBody(body_buffer.get(), kBodySize,
475 callback.callback())); 429 callback.callback()));
476 data.RunFor(1);
477 ASSERT_TRUE(callback.have_result());
478 ASSERT_EQ(kBodySize, callback.WaitForResult()); 430 ASSERT_EQ(kBodySize, callback.WaitForResult());
479 } 431 }
480 432
481 // Test to ensure the HttpStreamParser state machine does not get confused 433 // Test to ensure the HttpStreamParser state machine does not get confused
482 // when there's only one "chunk" with 0 bytes, and is received from the 434 // when there's only one "chunk" with 0 bytes, and is received from the
483 // UploadStream only after sending the request headers successfully. 435 // UploadStream only after sending the request headers successfully.
484 TEST(HttpStreamParser, AsyncEmptyChunkedUpload) { 436 TEST(HttpStreamParser, AsyncEmptyChunkedUpload) {
485 MockWrite writes[] = { 437 MockWrite writes[] = {
486 MockWrite(ASYNC, 0, 438 MockWrite(ASYNC, 0,
487 "GET /one.html HTTP/1.1\r\n" 439 "GET /one.html HTTP/1.1\r\n"
488 "Transfer-Encoding: chunked\r\n\r\n"), 440 "Transfer-Encoding: chunked\r\n\r\n"),
489 MockWrite(ASYNC, 1, "0\r\n\r\n"), 441 MockWrite(ASYNC, 1, "0\r\n\r\n"),
490 }; 442 };
491 443
492 // The size of the response body, as reflected in the Content-Length of the 444 // The size of the response body, as reflected in the Content-Length of the
493 // MockRead below. 445 // MockRead below.
494 const int kBodySize = 8; 446 const int kBodySize = 8;
495 447
496 MockRead reads[] = { 448 MockRead reads[] = {
497 MockRead(ASYNC, 2, "HTTP/1.1 200 OK\r\n"), 449 MockRead(ASYNC, 2, "HTTP/1.1 200 OK\r\n"),
498 MockRead(ASYNC, 3, "Content-Length: 8\r\n\r\n"), 450 MockRead(ASYNC, 3, "Content-Length: 8\r\n\r\n"),
499 MockRead(ASYNC, 4, "one.html"), 451 MockRead(ASYNC, 4, "one.html"),
500 MockRead(SYNCHRONOUS, 0, 5), // EOF 452 MockRead(SYNCHRONOUS, 0, 5), // EOF
501 }; 453 };
502 454
503 ChunkedUploadDataStream upload_stream(0); 455 ChunkedUploadDataStream upload_stream(0);
504 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback())); 456 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
505 457
506 DeterministicSocketData data(reads, arraysize(reads), writes, 458 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
507 arraysize(writes));
508 scoped_ptr<ClientSocketHandle> socket_handle = 459 scoped_ptr<ClientSocketHandle> socket_handle =
509 CreateConnectedSocketHandle(&data); 460 CreateConnectedSocketHandle(&data);
510 461
511 HttpRequestInfo request_info; 462 HttpRequestInfo request_info;
512 request_info.method = "GET"; 463 request_info.method = "GET";
513 request_info.url = GURL("http://localhost"); 464 request_info.url = GURL("http://localhost");
514 request_info.upload_data_stream = &upload_stream; 465 request_info.upload_data_stream = &upload_stream;
515 466
516 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 467 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
517 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), 468 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(),
518 BoundNetLog()); 469 BoundNetLog());
519 470
520 HttpRequestHeaders request_headers; 471 HttpRequestHeaders request_headers;
521 request_headers.SetHeader("Transfer-Encoding", "chunked"); 472 request_headers.SetHeader("Transfer-Encoding", "chunked");
522 473
523 HttpResponseInfo response_info; 474 HttpResponseInfo response_info;
524 TestCompletionCallback callback; 475 TestCompletionCallback callback;
525 // This will attempt to Write() the initial request and headers, which will 476 // This will attempt to Write() the initial request and headers, which will
526 // complete asynchronously. 477 // complete asynchronously.
527 ASSERT_EQ(ERR_IO_PENDING, 478 ASSERT_EQ(ERR_IO_PENDING,
528 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers, 479 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
529 &response_info, callback.callback())); 480 &response_info, callback.callback()));
530 481
531 // Complete writing the request headers.
532 data.RunFor(1);
533 ASSERT_FALSE(callback.have_result());
534
535 // Now append the terminal 0-byte "chunk". 482 // Now append the terminal 0-byte "chunk".
536 upload_stream.AppendData(nullptr, 0, true); 483 upload_stream.AppendData(nullptr, 0, true);
537 ASSERT_FALSE(callback.have_result()); 484 ASSERT_FALSE(callback.have_result());
538 485
539 // Finalize writing the trailer.
540 data.RunFor(1);
541 ASSERT_TRUE(callback.have_result());
542 ASSERT_EQ(OK, callback.WaitForResult()); 486 ASSERT_EQ(OK, callback.WaitForResult());
543 487
544 // Attempt to read the response status and the response headers. 488 // Attempt to read the response status and the response headers.
545 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); 489 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback()));
546 data.RunFor(2);
547 ASSERT_TRUE(callback.have_result());
548 ASSERT_GT(callback.WaitForResult(), 0); 490 ASSERT_GT(callback.WaitForResult(), 0);
549 491
550 // Finally, attempt to read the response body. 492 // Finally, attempt to read the response body.
551 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 493 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
552 ASSERT_EQ(ERR_IO_PENDING, 494 ASSERT_EQ(ERR_IO_PENDING,
553 parser.ReadResponseBody(body_buffer.get(), kBodySize, 495 parser.ReadResponseBody(body_buffer.get(), kBodySize,
554 callback.callback())); 496 callback.callback()));
555 data.RunFor(1);
556 ASSERT_TRUE(callback.have_result());
557 ASSERT_EQ(kBodySize, callback.WaitForResult()); 497 ASSERT_EQ(kBodySize, callback.WaitForResult());
558 } 498 }
559 499
560 // Test to ensure the HttpStreamParser state machine does not get confused 500 // Test to ensure the HttpStreamParser state machine does not get confused
561 // when there's only one "chunk" with 0 bytes, which was already appended before 501 // when there's only one "chunk" with 0 bytes, which was already appended before
562 // the request was started. 502 // the request was started.
563 TEST(HttpStreamParser, SyncEmptyChunkedUpload) { 503 TEST(HttpStreamParser, SyncEmptyChunkedUpload) {
564 MockWrite writes[] = { 504 MockWrite writes[] = {
565 MockWrite(ASYNC, 0, 505 MockWrite(ASYNC, 0,
566 "GET /one.html HTTP/1.1\r\n" 506 "GET /one.html HTTP/1.1\r\n"
(...skipping 10 matching lines...) Expand all
577 MockRead(ASYNC, 3, "Content-Length: 8\r\n\r\n"), 517 MockRead(ASYNC, 3, "Content-Length: 8\r\n\r\n"),
578 MockRead(ASYNC, 4, "one.html"), 518 MockRead(ASYNC, 4, "one.html"),
579 MockRead(SYNCHRONOUS, 0, 5), // EOF 519 MockRead(SYNCHRONOUS, 0, 5), // EOF
580 }; 520 };
581 521
582 ChunkedUploadDataStream upload_stream(0); 522 ChunkedUploadDataStream upload_stream(0);
583 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback())); 523 ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback()));
584 // Append final empty chunk. 524 // Append final empty chunk.
585 upload_stream.AppendData(nullptr, 0, true); 525 upload_stream.AppendData(nullptr, 0, true);
586 526
587 DeterministicSocketData data(reads, arraysize(reads), writes, 527 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
588 arraysize(writes));
589 scoped_ptr<ClientSocketHandle> socket_handle = 528 scoped_ptr<ClientSocketHandle> socket_handle =
590 CreateConnectedSocketHandle(&data); 529 CreateConnectedSocketHandle(&data);
591 530
592 HttpRequestInfo request_info; 531 HttpRequestInfo request_info;
593 request_info.method = "GET"; 532 request_info.method = "GET";
594 request_info.url = GURL("http://localhost"); 533 request_info.url = GURL("http://localhost");
595 request_info.upload_data_stream = &upload_stream; 534 request_info.upload_data_stream = &upload_stream;
596 535
597 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 536 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
598 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), 537 HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(),
599 BoundNetLog()); 538 BoundNetLog());
600 539
601 HttpRequestHeaders request_headers; 540 HttpRequestHeaders request_headers;
602 request_headers.SetHeader("Transfer-Encoding", "chunked"); 541 request_headers.SetHeader("Transfer-Encoding", "chunked");
603 542
604 HttpResponseInfo response_info; 543 HttpResponseInfo response_info;
605 TestCompletionCallback callback; 544 TestCompletionCallback callback;
606 // This will attempt to Write() the initial request and headers, which will 545 // This will attempt to Write() the initial request and headers, which will
607 // complete asynchronously. 546 // complete asynchronously.
608 ASSERT_EQ(ERR_IO_PENDING, 547 ASSERT_EQ(ERR_IO_PENDING,
609 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers, 548 parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
610 &response_info, callback.callback())); 549 &response_info, callback.callback()));
611 550
612 // Complete writing the request headers and body. 551 // Complete writing the request headers and body.
613 data.RunFor(2);
614 ASSERT_TRUE(callback.have_result());
615 ASSERT_EQ(OK, callback.WaitForResult()); 552 ASSERT_EQ(OK, callback.WaitForResult());
616 553
617 // Attempt to read the response status and the response headers. 554 // Attempt to read the response status and the response headers.
618 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); 555 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback()));
619 data.RunFor(2);
620 ASSERT_TRUE(callback.have_result());
621 ASSERT_GT(callback.WaitForResult(), 0); 556 ASSERT_GT(callback.WaitForResult(), 0);
622 557
623 // Finally, attempt to read the response body. 558 // Finally, attempt to read the response body.
624 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 559 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
625 ASSERT_EQ(ERR_IO_PENDING, 560 ASSERT_EQ(ERR_IO_PENDING,
626 parser.ReadResponseBody(body_buffer.get(), kBodySize, 561 parser.ReadResponseBody(body_buffer.get(), kBodySize,
627 callback.callback())); 562 callback.callback()));
628 data.RunFor(1);
629 ASSERT_TRUE(callback.have_result());
630 ASSERT_EQ(kBodySize, callback.WaitForResult()); 563 ASSERT_EQ(kBodySize, callback.WaitForResult());
631 } 564 }
632 565
633 TEST(HttpStreamParser, TruncatedHeaders) { 566 TEST(HttpStreamParser, TruncatedHeaders) {
634 MockRead truncated_status_reads[] = { 567 MockRead truncated_status_reads[] = {
635 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 20"), 568 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 20"),
636 MockRead(SYNCHRONOUS, 0, 2), // EOF 569 MockRead(SYNCHRONOUS, 0, 2), // EOF
637 }; 570 };
638 571
639 MockRead truncated_after_status_reads[] = { 572 MockRead truncated_after_status_reads[] = {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 HTTP = 0, 611 HTTP = 0,
679 HTTPS, 612 HTTPS,
680 NUM_PROTOCOLS, 613 NUM_PROTOCOLS,
681 }; 614 };
682 615
683 for (size_t protocol = 0; protocol < NUM_PROTOCOLS; protocol++) { 616 for (size_t protocol = 0; protocol < NUM_PROTOCOLS; protocol++) {
684 SCOPED_TRACE(protocol); 617 SCOPED_TRACE(protocol);
685 618
686 for (size_t i = 0; i < arraysize(reads); i++) { 619 for (size_t i = 0; i < arraysize(reads); i++) {
687 SCOPED_TRACE(i); 620 SCOPED_TRACE(i);
688 DeterministicSocketData data(reads[i], 2, writes, arraysize(writes)); 621 SequencedSocketData data(reads[i], 2, writes, arraysize(writes));
689 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); 622 scoped_ptr<ClientSocketHandle> socket_handle(
690 data.SetStop(3); 623 CreateConnectedSocketHandle(&data));
691
692 scoped_ptr<DeterministicMockTCPClientSocket> transport(
693 new DeterministicMockTCPClientSocket(NULL, &data));
694 data.set_delegate(transport->AsWeakPtr());
695
696 TestCompletionCallback callback;
697 int rv = transport->Connect(callback.callback());
698 ASSERT_EQ(OK, rv);
699
700 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
701 socket_handle->SetSocket(transport.Pass());
702 624
703 HttpRequestInfo request_info; 625 HttpRequestInfo request_info;
704 request_info.method = "GET"; 626 request_info.method = "GET";
705 if (protocol == HTTP) { 627 if (protocol == HTTP) {
706 request_info.url = GURL("http://localhost"); 628 request_info.url = GURL("http://localhost");
707 } else { 629 } else {
708 request_info.url = GURL("https://localhost"); 630 request_info.url = GURL("https://localhost");
709 } 631 }
710 request_info.load_flags = LOAD_NORMAL; 632 request_info.load_flags = LOAD_NORMAL;
711 633
712 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 634 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
713 HttpStreamParser parser( 635 HttpStreamParser parser(
714 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); 636 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog());
715 637
716 HttpRequestHeaders request_headers; 638 HttpRequestHeaders request_headers;
717 HttpResponseInfo response_info; 639 HttpResponseInfo response_info;
718 rv = parser.SendRequest("GET / HTTP/1.1\r\n", request_headers, 640 TestCompletionCallback callback;
719 &response_info, callback.callback()); 641 ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", request_headers,
720 ASSERT_EQ(OK, rv); 642 &response_info, callback.callback()));
721 643
722 rv = parser.ReadResponseHeaders(callback.callback()); 644 int rv = parser.ReadResponseHeaders(callback.callback());
723 if (i == arraysize(reads) - 1) { 645 if (i == arraysize(reads) - 1) {
724 EXPECT_EQ(OK, rv); 646 EXPECT_EQ(OK, rv);
725 EXPECT_TRUE(response_info.headers.get()); 647 EXPECT_TRUE(response_info.headers.get());
726 } else { 648 } else {
727 if (protocol == HTTP) { 649 if (protocol == HTTP) {
728 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); 650 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
729 EXPECT_TRUE(response_info.headers.get()); 651 EXPECT_TRUE(response_info.headers.get());
730 } else { 652 } else {
731 EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv); 653 EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv);
732 EXPECT_FALSE(response_info.headers.get()); 654 EXPECT_FALSE(response_info.headers.get());
(...skipping 12 matching lines...) Expand all
745 "Upgrade: websocket\r\n" 667 "Upgrade: websocket\r\n"
746 "Connection: Upgrade\r\n" 668 "Connection: Upgrade\r\n"
747 "\r\n" 669 "\r\n"
748 "a fake websocket frame"), 670 "a fake websocket frame"),
749 }; 671 };
750 672
751 MockWrite writes[] = { 673 MockWrite writes[] = {
752 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"), 674 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"),
753 }; 675 };
754 676
755 DeterministicSocketData data(reads, arraysize(reads), 677 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
756 writes, arraysize(writes)); 678 scoped_ptr<ClientSocketHandle> socket_handle =
757 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); 679 CreateConnectedSocketHandle(&data);
758 data.SetStop(2);
759
760 scoped_ptr<DeterministicMockTCPClientSocket> transport(
761 new DeterministicMockTCPClientSocket(NULL, &data));
762 data.set_delegate(transport->AsWeakPtr());
763
764 TestCompletionCallback callback;
765 int rv = transport->Connect(callback.callback());
766 ASSERT_EQ(OK, rv);
767
768 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
769 socket_handle->SetSocket(transport.Pass());
770 680
771 HttpRequestInfo request_info; 681 HttpRequestInfo request_info;
772 request_info.method = "GET"; 682 request_info.method = "GET";
773 request_info.url = GURL("http://localhost"); 683 request_info.url = GURL("http://localhost");
774 request_info.load_flags = LOAD_NORMAL; 684 request_info.load_flags = LOAD_NORMAL;
775 685
776 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 686 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
777 HttpStreamParser parser( 687 HttpStreamParser parser(
778 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); 688 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog());
779 689
780 HttpRequestHeaders request_headers; 690 HttpRequestHeaders request_headers;
781 HttpResponseInfo response_info; 691 HttpResponseInfo response_info;
782 rv = parser.SendRequest("GET / HTTP/1.1\r\n", request_headers, 692 TestCompletionCallback callback;
783 &response_info, callback.callback()); 693 ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", request_headers,
784 ASSERT_EQ(OK, rv); 694 &response_info, callback.callback()));
785 695
786 rv = parser.ReadResponseHeaders(callback.callback()); 696 EXPECT_EQ(OK, parser.ReadResponseHeaders(callback.callback()));
787 EXPECT_EQ(OK, rv);
788 ASSERT_TRUE(response_info.headers.get()); 697 ASSERT_TRUE(response_info.headers.get());
789 EXPECT_EQ(101, response_info.headers->response_code()); 698 EXPECT_EQ(101, response_info.headers->response_code());
790 EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade")); 699 EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade"));
791 EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket")); 700 EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket"));
792 EXPECT_EQ(read_buffer->capacity(), read_buffer->offset()); 701 EXPECT_EQ(read_buffer->capacity(), read_buffer->offset());
793 EXPECT_EQ("a fake websocket frame", 702 EXPECT_EQ("a fake websocket frame",
794 base::StringPiece(read_buffer->StartOfBuffer(), 703 base::StringPiece(read_buffer->StartOfBuffer(),
795 read_buffer->capacity())); 704 read_buffer->capacity()));
796 } 705 }
797 706
(...skipping 17 matching lines...) Expand all
815 read_buffer_->set_offset(offset + size); 724 read_buffer_->set_offset(offset + size);
816 } 725 }
817 726
818 void AddRead(const std::string& data) { 727 void AddRead(const std::string& data) {
819 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data())); 728 reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data()));
820 } 729 }
821 730
822 void SetupParserAndSendRequest() { 731 void SetupParserAndSendRequest() {
823 reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF 732 reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF
824 733
825 socket_handle_.reset(new ClientSocketHandle); 734 data_.reset(new SequencedSocketData(&reads_.front(), reads_.size(),
826 data_.reset(new DeterministicSocketData( 735 &writes_.front(), writes_.size()));
827 &reads_.front(), reads_.size(), &writes_.front(), writes_.size())); 736 socket_handle_ = CreateConnectedSocketHandle(data_.get());
828 data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
829 data_->SetStop(reads_.size() + writes_.size());
830
831 transport_.reset(new DeterministicMockTCPClientSocket(NULL, data_.get()));
832 data_->set_delegate(transport_->AsWeakPtr());
833
834 TestCompletionCallback callback;
835 int rv = transport_->Connect(callback.callback());
836 rv = callback.GetResult(rv);
837 ASSERT_EQ(OK, rv);
838
839 socket_handle_->SetSocket(transport_.Pass());
840 737
841 request_info_.method = "GET"; 738 request_info_.method = "GET";
842 request_info_.url = GURL("http://localhost"); 739 request_info_.url = GURL("http://localhost");
843 request_info_.load_flags = LOAD_NORMAL; 740 request_info_.load_flags = LOAD_NORMAL;
844 741
845 parser_.reset(new HttpStreamParser( 742 parser_.reset(new HttpStreamParser(
846 socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog())); 743 socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog()));
847 744
848 rv = parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_, 745 TestCompletionCallback callback;
849 &response_info_, callback.callback()); 746 ASSERT_EQ(OK, parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_,
850 ASSERT_EQ(OK, rv); 747 &response_info_, callback.callback()));
851 } 748 }
852 749
853 void ReadHeaders() { 750 void ReadHeaders() {
854 TestCompletionCallback callback; 751 TestCompletionCallback callback;
855 EXPECT_EQ(OK, parser_->ReadResponseHeaders(callback.callback())); 752 EXPECT_EQ(OK, parser_->ReadResponseHeaders(callback.callback()));
856 } 753 }
857 754
858 void ReadBody(int user_buf_len, int* read_lengths) { 755 void ReadBody(int user_buf_len, int* read_lengths) {
859 TestCompletionCallback callback; 756 TestCompletionCallback callback;
860 scoped_refptr<IOBuffer> buffer = new IOBuffer(user_buf_len); 757 scoped_refptr<IOBuffer> buffer = new IOBuffer(user_buf_len);
(...skipping 10 matching lines...) Expand all
871 } 768 }
872 769
873 private: 770 private:
874 HttpRequestHeaders request_headers_; 771 HttpRequestHeaders request_headers_;
875 HttpResponseInfo response_info_; 772 HttpResponseInfo response_info_;
876 HttpRequestInfo request_info_; 773 HttpRequestInfo request_info_;
877 scoped_refptr<GrowableIOBuffer> read_buffer_; 774 scoped_refptr<GrowableIOBuffer> read_buffer_;
878 std::vector<MockRead> reads_; 775 std::vector<MockRead> reads_;
879 std::vector<MockWrite> writes_; 776 std::vector<MockWrite> writes_;
880 scoped_ptr<ClientSocketHandle> socket_handle_; 777 scoped_ptr<ClientSocketHandle> socket_handle_;
881 scoped_ptr<DeterministicSocketData> data_; 778 scoped_ptr<SequencedSocketData> data_;
882 scoped_ptr<DeterministicMockTCPClientSocket> transport_;
883 scoped_ptr<HttpStreamParser> parser_; 779 scoped_ptr<HttpStreamParser> parser_;
884 int sequence_number_; 780 int sequence_number_;
885 }; 781 };
886 782
887 // Test that HTTP/0.9 response size is correctly calculated. 783 // Test that HTTP/0.9 response size is correctly calculated.
888 TEST(HttpStreamParser, ReceivedBytesNoHeaders) { 784 TEST(HttpStreamParser, ReceivedBytesNoHeaders) {
889 std::string response = "hello\r\nworld\r\n"; 785 std::string response = "hello\r\nworld\r\n";
890 786
891 SimpleGetRunner get_runner; 787 SimpleGetRunner get_runner;
892 get_runner.AddRead(response); 788 get_runner.AddRead(response);
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); 1007 EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
1112 } 1008 }
1113 1009
1114 // Test that an HttpStreamParser can be read from after it's received headers 1010 // Test that an HttpStreamParser can be read from after it's received headers
1115 // and data structures owned by its owner have been deleted. This happens 1011 // and data structures owned by its owner have been deleted. This happens
1116 // when a ResponseBodyDrainer is used. 1012 // when a ResponseBodyDrainer is used.
1117 TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { 1013 TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
1118 MockWrite writes[] = { 1014 MockWrite writes[] = {
1119 MockWrite(SYNCHRONOUS, 0, 1015 MockWrite(SYNCHRONOUS, 0,
1120 "GET /foo.html HTTP/1.1\r\n\r\n"), 1016 "GET /foo.html HTTP/1.1\r\n\r\n"),
1121 MockWrite(SYNCHRONOUS, 1, "1"),
1122 }; 1017 };
1123 1018
1124 const int kBodySize = 1; 1019 const int kBodySize = 1;
1125 MockRead reads[] = { 1020 MockRead reads[] = {
1126 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), 1021 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
1127 MockRead(SYNCHRONOUS, 6, "Content-Length: 1\r\n\r\n"), 1022 MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n\r\n"),
1128 MockRead(SYNCHRONOUS, 6, "Connection: Keep-Alive\r\n\r\n"), 1023 MockRead(SYNCHRONOUS, 3, "Connection: Keep-Alive\r\n\r\n"),
1129 MockRead(SYNCHRONOUS, 7, "1"), 1024 MockRead(SYNCHRONOUS, 4, "1"),
1130 MockRead(SYNCHRONOUS, 0, 8), // EOF 1025 MockRead(SYNCHRONOUS, 0, 5), // EOF
1131 }; 1026 };
1132 1027
1133 StaticSocketDataProvider data(reads, arraysize(reads), writes, 1028 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
1134 arraysize(writes)); 1029 scoped_ptr<ClientSocketHandle> socket_handle =
1135 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); 1030 CreateConnectedSocketHandle(&data);
1136
1137 scoped_ptr<MockTCPClientSocket> transport(
1138 new MockTCPClientSocket(AddressList(), NULL, &data));
1139
1140 TestCompletionCallback callback;
1141 ASSERT_EQ(OK, transport->Connect(callback.callback()));
1142
1143 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
1144 socket_handle->SetSocket(transport.Pass());
1145 1031
1146 scoped_ptr<HttpRequestInfo> request_info(new HttpRequestInfo()); 1032 scoped_ptr<HttpRequestInfo> request_info(new HttpRequestInfo());
1147 request_info->method = "GET"; 1033 request_info->method = "GET";
1148 request_info->url = GURL("http://somewhere/foo.html"); 1034 request_info->url = GURL("http://somewhere/foo.html");
1149 1035
1150 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); 1036 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1151 HttpStreamParser parser(socket_handle.get(), request_info.get(), 1037 HttpStreamParser parser(socket_handle.get(), request_info.get(),
1152 read_buffer.get(), BoundNetLog()); 1038 read_buffer.get(), BoundNetLog());
1153 1039
1154 scoped_ptr<HttpRequestHeaders> request_headers(new HttpRequestHeaders()); 1040 scoped_ptr<HttpRequestHeaders> request_headers(new HttpRequestHeaders());
1155 scoped_ptr<HttpResponseInfo> response_info(new HttpResponseInfo()); 1041 scoped_ptr<HttpResponseInfo> response_info(new HttpResponseInfo());
1042 TestCompletionCallback callback;
1156 ASSERT_EQ(OK, parser.SendRequest("GET /foo.html HTTP/1.1\r\n", 1043 ASSERT_EQ(OK, parser.SendRequest("GET /foo.html HTTP/1.1\r\n",
1157 *request_headers, response_info.get(), callback.callback())); 1044 *request_headers, response_info.get(), callback.callback()));
1158 ASSERT_EQ(OK, parser.ReadResponseHeaders(callback.callback())); 1045 ASSERT_EQ(OK, parser.ReadResponseHeaders(callback.callback()));
1159 1046
1160 // If the object that owns the HttpStreamParser is deleted, it takes the 1047 // If the object that owns the HttpStreamParser is deleted, it takes the
1161 // objects passed to the HttpStreamParser with it. 1048 // objects passed to the HttpStreamParser with it.
1162 request_info.reset(); 1049 request_info.reset();
1163 request_headers.reset(); 1050 request_headers.reset();
1164 response_info.reset(); 1051 response_info.reset();
1165 1052
1166 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 1053 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
1167 ASSERT_EQ(kBodySize, parser.ReadResponseBody( 1054 ASSERT_EQ(kBodySize, parser.ReadResponseBody(
1168 body_buffer.get(), kBodySize, callback.callback())); 1055 body_buffer.get(), kBodySize, callback.callback()));
1169 } 1056 }
1170 1057
1171 } // namespace 1058 } // namespace
1172 1059
1173 } // namespace net 1060 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698