| OLD | NEW |
| 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 <stdint.h> |
| 8 |
| 7 #include <algorithm> | 9 #include <algorithm> |
| 8 #include <string> | 10 #include <string> |
| 9 #include <vector> | 11 #include <vector> |
| 10 | 12 |
| 11 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 12 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 13 #include "base/files/scoped_temp_dir.h" | 15 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
| 15 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 16 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 payload.data(), payload.size())); | 194 payload.data(), payload.size())); |
| 193 | 195 |
| 194 scoped_ptr<UploadDataStream> body( | 196 scoped_ptr<UploadDataStream> body( |
| 195 new ElementsUploadDataStream(element_readers.Pass(), 0)); | 197 new ElementsUploadDataStream(element_readers.Pass(), 0)); |
| 196 ASSERT_EQ(OK, body->Init(CompletionCallback())); | 198 ASSERT_EQ(OK, body->Init(CompletionCallback())); |
| 197 // Shouldn't be merged if the in-memory body is large here. | 199 // Shouldn't be merged if the in-memory body is large here. |
| 198 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 200 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( |
| 199 "some header", body.get())); | 201 "some header", body.get())); |
| 200 } | 202 } |
| 201 | 203 |
| 204 TEST(HttpStreamParser, SentBytesNoHeaders) { |
| 205 MockWrite writes[] = { |
| 206 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"), |
| 207 }; |
| 208 |
| 209 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 210 scoped_ptr<ClientSocketHandle> socket_handle = |
| 211 CreateConnectedSocketHandle(&data); |
| 212 |
| 213 HttpRequestInfo request; |
| 214 request.method = "GET"; |
| 215 request.url = GURL("http://localhost"); |
| 216 |
| 217 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 218 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 219 BoundNetLog()); |
| 220 |
| 221 HttpResponseInfo response; |
| 222 TestCompletionCallback callback; |
| 223 EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", HttpRequestHeaders(), |
| 224 &response, callback.callback())); |
| 225 |
| 226 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 227 } |
| 228 |
| 229 TEST(HttpStreamParser, SentBytesWithHeaders) { |
| 230 MockWrite writes[] = { |
| 231 MockWrite(SYNCHRONOUS, 0, |
| 232 "GET / HTTP/1.1\r\n" |
| 233 "Host: localhost\r\n" |
| 234 "Connection: Keep-Alive\r\n\r\n"), |
| 235 }; |
| 236 |
| 237 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 238 scoped_ptr<ClientSocketHandle> socket_handle = |
| 239 CreateConnectedSocketHandle(&data); |
| 240 |
| 241 HttpRequestInfo request; |
| 242 request.method = "GET"; |
| 243 request.url = GURL("http://localhost"); |
| 244 |
| 245 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 246 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 247 BoundNetLog()); |
| 248 |
| 249 HttpRequestHeaders headers; |
| 250 headers.SetHeader("Host", "localhost"); |
| 251 headers.SetHeader("Connection", "Keep-Alive"); |
| 252 |
| 253 HttpResponseInfo response; |
| 254 TestCompletionCallback callback; |
| 255 EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response, |
| 256 callback.callback())); |
| 257 |
| 258 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 259 } |
| 260 |
| 261 TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) { |
| 262 MockWrite writes[] = { |
| 263 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"), |
| 264 MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"), |
| 265 MockWrite(SYNCHRONOUS, 2, "Connection: Keep-Alive\r\n\r\n"), |
| 266 }; |
| 267 |
| 268 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 269 scoped_ptr<ClientSocketHandle> socket_handle = |
| 270 CreateConnectedSocketHandle(&data); |
| 271 |
| 272 HttpRequestInfo request; |
| 273 request.method = "GET"; |
| 274 request.url = GURL("http://localhost"); |
| 275 |
| 276 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 277 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 278 BoundNetLog()); |
| 279 |
| 280 HttpRequestHeaders headers; |
| 281 headers.SetHeader("Host", "localhost"); |
| 282 headers.SetHeader("Connection", "Keep-Alive"); |
| 283 |
| 284 HttpResponseInfo response; |
| 285 TestCompletionCallback callback; |
| 286 |
| 287 EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response, |
| 288 callback.callback())); |
| 289 |
| 290 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 291 } |
| 292 |
| 293 TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) { |
| 294 MockWrite writes[] = { |
| 295 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"), |
| 296 MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"), |
| 297 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 2), |
| 298 }; |
| 299 |
| 300 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 301 scoped_ptr<ClientSocketHandle> socket_handle = |
| 302 CreateConnectedSocketHandle(&data); |
| 303 |
| 304 HttpRequestInfo request; |
| 305 request.method = "GET"; |
| 306 request.url = GURL("http://localhost"); |
| 307 |
| 308 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 309 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 310 BoundNetLog()); |
| 311 |
| 312 HttpRequestHeaders headers; |
| 313 headers.SetHeader("Host", "localhost"); |
| 314 headers.SetHeader("Connection", "Keep-Alive"); |
| 315 |
| 316 HttpResponseInfo response; |
| 317 TestCompletionCallback callback; |
| 318 EXPECT_EQ(ERR_CONNECTION_RESET, |
| 319 parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response, |
| 320 callback.callback())); |
| 321 |
| 322 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 323 } |
| 324 |
| 325 TEST(HttpStreamParser, SentBytesPost) { |
| 326 MockWrite writes[] = { |
| 327 MockWrite(SYNCHRONOUS, 0, "POST / HTTP/1.1\r\n"), |
| 328 MockWrite(SYNCHRONOUS, 1, "Content-Length: 12\r\n\r\n"), |
| 329 MockWrite(SYNCHRONOUS, 2, "hello world!"), |
| 330 }; |
| 331 |
| 332 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 333 scoped_ptr<ClientSocketHandle> socket_handle = |
| 334 CreateConnectedSocketHandle(&data); |
| 335 |
| 336 ScopedVector<UploadElementReader> element_readers; |
| 337 element_readers.push_back(new UploadBytesElementReader("hello world!", 12)); |
| 338 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0); |
| 339 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback())); |
| 340 |
| 341 HttpRequestInfo request; |
| 342 request.method = "POST"; |
| 343 request.url = GURL("http://localhost"); |
| 344 request.upload_data_stream = &upload_data_stream; |
| 345 |
| 346 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 347 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 348 BoundNetLog()); |
| 349 |
| 350 HttpRequestHeaders headers; |
| 351 headers.SetHeader("Content-Length", "12"); |
| 352 |
| 353 HttpResponseInfo response; |
| 354 TestCompletionCallback callback; |
| 355 EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, |
| 356 callback.callback())); |
| 357 |
| 358 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 359 } |
| 360 |
| 361 TEST(HttpStreamParser, SentBytesChunkedPostError) { |
| 362 static const char kChunk[] = "Chunk 1"; |
| 363 |
| 364 MockWrite writes[] = { |
| 365 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"), |
| 366 MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"), |
| 367 MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"), |
| 368 MockWrite(SYNCHRONOUS, ERR_FAILED, 3), |
| 369 }; |
| 370 |
| 371 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 372 scoped_ptr<ClientSocketHandle> socket_handle = |
| 373 CreateConnectedSocketHandle(&data); |
| 374 |
| 375 ChunkedUploadDataStream upload_data_stream(0); |
| 376 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback())); |
| 377 |
| 378 HttpRequestInfo request; |
| 379 request.method = "POST"; |
| 380 request.url = GURL("http://localhost"); |
| 381 request.upload_data_stream = &upload_data_stream; |
| 382 |
| 383 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 384 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 385 BoundNetLog()); |
| 386 |
| 387 HttpRequestHeaders headers; |
| 388 headers.SetHeader("Transfer-Encoding", "chunked"); |
| 389 |
| 390 HttpResponseInfo response; |
| 391 TestCompletionCallback callback; |
| 392 EXPECT_EQ(ERR_IO_PENDING, parser.SendRequest("POST / HTTP/1.1\r\n", headers, |
| 393 &response, callback.callback())); |
| 394 |
| 395 base::RunLoop().RunUntilIdle(); |
| 396 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false); |
| 397 |
| 398 base::RunLoop().RunUntilIdle(); |
| 399 // This write should fail. |
| 400 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false); |
| 401 EXPECT_EQ(ERR_FAILED, callback.WaitForResult()); |
| 402 |
| 403 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 404 } |
| 405 |
| 202 // Test to ensure the HttpStreamParser state machine does not get confused | 406 // Test to ensure the HttpStreamParser state machine does not get confused |
| 203 // when sending a request with a chunked body with only one chunk that becomes | 407 // when sending a request with a chunked body with only one chunk that becomes |
| 204 // available asynchronously. | 408 // available asynchronously. |
| 205 TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) { | 409 TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) { |
| 206 static const char kChunk[] = "Chunk"; | 410 static const char kChunk[] = "Chunk"; |
| 207 | 411 |
| 208 MockWrite writes[] = { | 412 MockWrite writes[] = { |
| 209 MockWrite(ASYNC, 0, | 413 MockWrite(ASYNC, 0, |
| 210 "GET /one.html HTTP/1.1\r\n" | 414 "GET /one.html HTTP/1.1\r\n" |
| 211 "Transfer-Encoding: chunked\r\n\r\n"), | 415 "Transfer-Encoding: chunked\r\n\r\n"), |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 // Attempt to read the response status and the response headers. | 466 // Attempt to read the response status and the response headers. |
| 263 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); | 467 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); |
| 264 ASSERT_GT(callback.WaitForResult(), 0); | 468 ASSERT_GT(callback.WaitForResult(), 0); |
| 265 | 469 |
| 266 // Finally, attempt to read the response body. | 470 // Finally, attempt to read the response body. |
| 267 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); | 471 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); |
| 268 ASSERT_EQ(ERR_IO_PENDING, | 472 ASSERT_EQ(ERR_IO_PENDING, |
| 269 parser.ReadResponseBody(body_buffer.get(), kBodySize, | 473 parser.ReadResponseBody(body_buffer.get(), kBodySize, |
| 270 callback.callback())); | 474 callback.callback())); |
| 271 ASSERT_EQ(kBodySize, callback.WaitForResult()); | 475 ASSERT_EQ(kBodySize, callback.WaitForResult()); |
| 476 |
| 477 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 478 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
| 272 } | 479 } |
| 273 | 480 |
| 274 // Test to ensure the HttpStreamParser state machine does not get confused | 481 // Test to ensure the HttpStreamParser state machine does not get confused |
| 275 // when sending a request with a chunked body with only one chunk that is | 482 // when sending a request with a chunked body with only one chunk that is |
| 276 // available synchronously. | 483 // available synchronously. |
| 277 TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) { | 484 TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) { |
| 278 static const char kChunk[] = "Chunk"; | 485 static const char kChunk[] = "Chunk"; |
| 279 | 486 |
| 280 MockWrite writes[] = { | 487 MockWrite writes[] = { |
| 281 MockWrite(ASYNC, 0, | 488 MockWrite(ASYNC, 0, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 // Attempt to read the response status and the response headers. | 536 // Attempt to read the response status and the response headers. |
| 330 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); | 537 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); |
| 331 ASSERT_GT(callback.WaitForResult(), 0); | 538 ASSERT_GT(callback.WaitForResult(), 0); |
| 332 | 539 |
| 333 // Finally, attempt to read the response body. | 540 // Finally, attempt to read the response body. |
| 334 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); | 541 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); |
| 335 ASSERT_EQ(ERR_IO_PENDING, | 542 ASSERT_EQ(ERR_IO_PENDING, |
| 336 parser.ReadResponseBody(body_buffer.get(), kBodySize, | 543 parser.ReadResponseBody(body_buffer.get(), kBodySize, |
| 337 callback.callback())); | 544 callback.callback())); |
| 338 ASSERT_EQ(kBodySize, callback.WaitForResult()); | 545 ASSERT_EQ(kBodySize, callback.WaitForResult()); |
| 546 |
| 547 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 548 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
| 339 } | 549 } |
| 340 | 550 |
| 341 // Test to ensure the HttpStreamParser state machine does not get confused | 551 // Test to ensure the HttpStreamParser state machine does not get confused |
| 342 // when sending a request with a chunked body, where chunks become available | 552 // when sending a request with a chunked body, where chunks become available |
| 343 // asynchronously, over a socket where writes may also complete | 553 // asynchronously, over a socket where writes may also complete |
| 344 // asynchronously. | 554 // asynchronously. |
| 345 // This is a regression test for http://crbug.com/132243 | 555 // This is a regression test for http://crbug.com/132243 |
| 346 TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) { | 556 TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) { |
| 347 // The chunks that will be written in the request, as reflected in the | 557 // The chunks that will be written in the request, as reflected in the |
| 348 // MockWrites below. | 558 // MockWrites below. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 // Attempt to read the response status and the response headers. | 629 // Attempt to read the response status and the response headers. |
| 420 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); | 630 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); |
| 421 ASSERT_GT(callback.WaitForResult(), 0); | 631 ASSERT_GT(callback.WaitForResult(), 0); |
| 422 | 632 |
| 423 // Finally, attempt to read the response body. | 633 // Finally, attempt to read the response body. |
| 424 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); | 634 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); |
| 425 ASSERT_EQ(ERR_IO_PENDING, | 635 ASSERT_EQ(ERR_IO_PENDING, |
| 426 parser.ReadResponseBody(body_buffer.get(), kBodySize, | 636 parser.ReadResponseBody(body_buffer.get(), kBodySize, |
| 427 callback.callback())); | 637 callback.callback())); |
| 428 ASSERT_EQ(kBodySize, callback.WaitForResult()); | 638 ASSERT_EQ(kBodySize, callback.WaitForResult()); |
| 639 |
| 640 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 641 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
| 429 } | 642 } |
| 430 | 643 |
| 431 // Test to ensure the HttpStreamParser state machine does not get confused | 644 // Test to ensure the HttpStreamParser state machine does not get confused |
| 432 // when there's only one "chunk" with 0 bytes, and is received from the | 645 // when there's only one "chunk" with 0 bytes, and is received from the |
| 433 // UploadStream only after sending the request headers successfully. | 646 // UploadStream only after sending the request headers successfully. |
| 434 TEST(HttpStreamParser, AsyncEmptyChunkedUpload) { | 647 TEST(HttpStreamParser, AsyncEmptyChunkedUpload) { |
| 435 MockWrite writes[] = { | 648 MockWrite writes[] = { |
| 436 MockWrite(ASYNC, 0, | 649 MockWrite(ASYNC, 0, |
| 437 "GET /one.html HTTP/1.1\r\n" | 650 "GET /one.html HTTP/1.1\r\n" |
| 438 "Transfer-Encoding: chunked\r\n\r\n"), | 651 "Transfer-Encoding: chunked\r\n\r\n"), |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 // Attempt to read the response status and the response headers. | 699 // Attempt to read the response status and the response headers. |
| 487 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); | 700 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); |
| 488 ASSERT_GT(callback.WaitForResult(), 0); | 701 ASSERT_GT(callback.WaitForResult(), 0); |
| 489 | 702 |
| 490 // Finally, attempt to read the response body. | 703 // Finally, attempt to read the response body. |
| 491 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); | 704 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); |
| 492 ASSERT_EQ(ERR_IO_PENDING, | 705 ASSERT_EQ(ERR_IO_PENDING, |
| 493 parser.ReadResponseBody(body_buffer.get(), kBodySize, | 706 parser.ReadResponseBody(body_buffer.get(), kBodySize, |
| 494 callback.callback())); | 707 callback.callback())); |
| 495 ASSERT_EQ(kBodySize, callback.WaitForResult()); | 708 ASSERT_EQ(kBodySize, callback.WaitForResult()); |
| 709 |
| 710 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 711 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
| 496 } | 712 } |
| 497 | 713 |
| 498 // Test to ensure the HttpStreamParser state machine does not get confused | 714 // Test to ensure the HttpStreamParser state machine does not get confused |
| 499 // when there's only one "chunk" with 0 bytes, which was already appended before | 715 // when there's only one "chunk" with 0 bytes, which was already appended before |
| 500 // the request was started. | 716 // the request was started. |
| 501 TEST(HttpStreamParser, SyncEmptyChunkedUpload) { | 717 TEST(HttpStreamParser, SyncEmptyChunkedUpload) { |
| 502 MockWrite writes[] = { | 718 MockWrite writes[] = { |
| 503 MockWrite(ASYNC, 0, | 719 MockWrite(ASYNC, 0, |
| 504 "GET /one.html HTTP/1.1\r\n" | 720 "GET /one.html HTTP/1.1\r\n" |
| 505 "Transfer-Encoding: chunked\r\n\r\n"), | 721 "Transfer-Encoding: chunked\r\n\r\n"), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 // Attempt to read the response status and the response headers. | 768 // Attempt to read the response status and the response headers. |
| 553 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); | 769 ASSERT_EQ(ERR_IO_PENDING, parser.ReadResponseHeaders(callback.callback())); |
| 554 ASSERT_GT(callback.WaitForResult(), 0); | 770 ASSERT_GT(callback.WaitForResult(), 0); |
| 555 | 771 |
| 556 // Finally, attempt to read the response body. | 772 // Finally, attempt to read the response body. |
| 557 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); | 773 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); |
| 558 ASSERT_EQ(ERR_IO_PENDING, | 774 ASSERT_EQ(ERR_IO_PENDING, |
| 559 parser.ReadResponseBody(body_buffer.get(), kBodySize, | 775 parser.ReadResponseBody(body_buffer.get(), kBodySize, |
| 560 callback.callback())); | 776 callback.callback())); |
| 561 ASSERT_EQ(kBodySize, callback.WaitForResult()); | 777 ASSERT_EQ(kBodySize, callback.WaitForResult()); |
| 778 |
| 779 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 780 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
| 562 } | 781 } |
| 563 | 782 |
| 564 TEST(HttpStreamParser, TruncatedHeaders) { | 783 TEST(HttpStreamParser, TruncatedHeaders) { |
| 565 MockRead truncated_status_reads[] = { | 784 MockRead truncated_status_reads[] = { |
| 566 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 20"), | 785 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 20"), |
| 567 MockRead(SYNCHRONOUS, 0, 2), // EOF | 786 MockRead(SYNCHRONOUS, 0, 2), // EOF |
| 568 }; | 787 }; |
| 569 | 788 |
| 570 MockRead truncated_after_status_reads[] = { | 789 MockRead truncated_after_status_reads[] = { |
| 571 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\n"), | 790 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\n"), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 HttpStreamParser parser( | 852 HttpStreamParser parser( |
| 634 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); | 853 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); |
| 635 | 854 |
| 636 HttpRequestHeaders request_headers; | 855 HttpRequestHeaders request_headers; |
| 637 HttpResponseInfo response_info; | 856 HttpResponseInfo response_info; |
| 638 TestCompletionCallback callback; | 857 TestCompletionCallback callback; |
| 639 ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", request_headers, | 858 ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", request_headers, |
| 640 &response_info, callback.callback())); | 859 &response_info, callback.callback())); |
| 641 | 860 |
| 642 int rv = parser.ReadResponseHeaders(callback.callback()); | 861 int rv = parser.ReadResponseHeaders(callback.callback()); |
| 862 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), |
| 863 parser.sent_bytes()); |
| 643 if (i == arraysize(reads) - 1) { | 864 if (i == arraysize(reads) - 1) { |
| 644 EXPECT_EQ(OK, rv); | 865 EXPECT_EQ(OK, rv); |
| 645 EXPECT_TRUE(response_info.headers.get()); | 866 EXPECT_TRUE(response_info.headers.get()); |
| 867 EXPECT_EQ(CountReadBytes(reads[i], 2), parser.received_bytes()); |
| 646 } else { | 868 } else { |
| 647 if (protocol == HTTP) { | 869 if (protocol == HTTP) { |
| 648 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | 870 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); |
| 649 EXPECT_TRUE(response_info.headers.get()); | 871 EXPECT_TRUE(response_info.headers.get()); |
| 872 EXPECT_EQ(CountReadBytes(reads[i], 2), parser.received_bytes()); |
| 650 } else { | 873 } else { |
| 651 EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv); | 874 EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv); |
| 652 EXPECT_FALSE(response_info.headers.get()); | 875 EXPECT_FALSE(response_info.headers.get()); |
| 876 EXPECT_EQ(0, parser.received_bytes()); |
| 653 } | 877 } |
| 654 } | 878 } |
| 655 } | 879 } |
| 656 } | 880 } |
| 657 } | 881 } |
| 658 | 882 |
| 659 // Confirm that on 101 response, the headers are parsed but the data that | 883 // Confirm that on 101 response, the headers are parsed but the data that |
| 660 // follows remains in the buffer. | 884 // follows remains in the buffer. |
| 661 TEST(HttpStreamParser, Websocket101Response) { | 885 TEST(HttpStreamParser, Websocket101Response) { |
| 662 MockRead reads[] = { | 886 MockRead reads[] = { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 693 | 917 |
| 694 EXPECT_EQ(OK, parser.ReadResponseHeaders(callback.callback())); | 918 EXPECT_EQ(OK, parser.ReadResponseHeaders(callback.callback())); |
| 695 ASSERT_TRUE(response_info.headers.get()); | 919 ASSERT_TRUE(response_info.headers.get()); |
| 696 EXPECT_EQ(101, response_info.headers->response_code()); | 920 EXPECT_EQ(101, response_info.headers->response_code()); |
| 697 EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade")); | 921 EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade")); |
| 698 EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket")); | 922 EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket")); |
| 699 EXPECT_EQ(read_buffer->capacity(), read_buffer->offset()); | 923 EXPECT_EQ(read_buffer->capacity(), read_buffer->offset()); |
| 700 EXPECT_EQ("a fake websocket frame", | 924 EXPECT_EQ("a fake websocket frame", |
| 701 base::StringPiece(read_buffer->StartOfBuffer(), | 925 base::StringPiece(read_buffer->StartOfBuffer(), |
| 702 read_buffer->capacity())); | 926 read_buffer->capacity())); |
| 927 |
| 928 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 929 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)) - |
| 930 static_cast<int64_t>(strlen("a fake websocket frame")), |
| 931 parser.received_bytes()); |
| 703 } | 932 } |
| 704 | 933 |
| 705 // Helper class for constructing HttpStreamParser and running GET requests. | 934 // Helper class for constructing HttpStreamParser and running GET requests. |
| 706 class SimpleGetRunner { | 935 class SimpleGetRunner { |
| 707 public: | 936 public: |
| 708 SimpleGetRunner() : read_buffer_(new GrowableIOBuffer), sequence_number_(0) { | 937 SimpleGetRunner() : read_buffer_(new GrowableIOBuffer), sequence_number_(0) { |
| 709 writes_.push_back(MockWrite( | 938 writes_.push_back(MockWrite( |
| 710 SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n")); | 939 SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n")); |
| 711 } | 940 } |
| 712 | 941 |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 // when a ResponseBodyDrainer is used. | 1239 // when a ResponseBodyDrainer is used. |
| 1011 TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { | 1240 TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { |
| 1012 MockWrite writes[] = { | 1241 MockWrite writes[] = { |
| 1013 MockWrite(SYNCHRONOUS, 0, | 1242 MockWrite(SYNCHRONOUS, 0, |
| 1014 "GET /foo.html HTTP/1.1\r\n\r\n"), | 1243 "GET /foo.html HTTP/1.1\r\n\r\n"), |
| 1015 }; | 1244 }; |
| 1016 | 1245 |
| 1017 const int kBodySize = 1; | 1246 const int kBodySize = 1; |
| 1018 MockRead reads[] = { | 1247 MockRead reads[] = { |
| 1019 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), | 1248 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), |
| 1020 MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n\r\n"), | 1249 MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n"), |
| 1021 MockRead(SYNCHRONOUS, 3, "Connection: Keep-Alive\r\n\r\n"), | 1250 MockRead(SYNCHRONOUS, 3, "Connection: Keep-Alive\r\n\r\n"), |
| 1022 MockRead(SYNCHRONOUS, 4, "1"), | 1251 MockRead(SYNCHRONOUS, 4, "1"), |
| 1023 MockRead(SYNCHRONOUS, 0, 5), // EOF | 1252 MockRead(SYNCHRONOUS, 0, 5), // EOF |
| 1024 }; | 1253 }; |
| 1025 | 1254 |
| 1026 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); | 1255 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1027 scoped_ptr<ClientSocketHandle> socket_handle = | 1256 scoped_ptr<ClientSocketHandle> socket_handle = |
| 1028 CreateConnectedSocketHandle(&data); | 1257 CreateConnectedSocketHandle(&data); |
| 1029 | 1258 |
| 1030 scoped_ptr<HttpRequestInfo> request_info(new HttpRequestInfo()); | 1259 scoped_ptr<HttpRequestInfo> request_info(new HttpRequestInfo()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1044 | 1273 |
| 1045 // If the object that owns the HttpStreamParser is deleted, it takes the | 1274 // If the object that owns the HttpStreamParser is deleted, it takes the |
| 1046 // objects passed to the HttpStreamParser with it. | 1275 // objects passed to the HttpStreamParser with it. |
| 1047 request_info.reset(); | 1276 request_info.reset(); |
| 1048 request_headers.reset(); | 1277 request_headers.reset(); |
| 1049 response_info.reset(); | 1278 response_info.reset(); |
| 1050 | 1279 |
| 1051 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); | 1280 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); |
| 1052 ASSERT_EQ(kBodySize, parser.ReadResponseBody( | 1281 ASSERT_EQ(kBodySize, parser.ReadResponseBody( |
| 1053 body_buffer.get(), kBodySize, callback.callback())); | 1282 body_buffer.get(), kBodySize, callback.callback())); |
| 1283 |
| 1284 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 1285 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
| 1054 } | 1286 } |
| 1055 | 1287 |
| 1056 } // namespace | 1288 } // namespace |
| 1057 | 1289 |
| 1058 } // namespace net | 1290 } // namespace net |
| OLD | NEW |