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

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

Issue 2130733003: [HttpStreamParser]: Flush buffers as soon as request is sent. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased + mmenke's comments Created 4 years, 5 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/http/http_stream_parser.h ('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 (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 <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 callback_ = callback; 326 callback_ = callback;
327 327
328 return result > 0 ? OK : result; 328 return result > 0 ? OK : result;
329 } 329 }
330 330
331 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) { 331 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) {
332 DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE); 332 DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE);
333 DCHECK(callback_.is_null()); 333 DCHECK(callback_.is_null());
334 DCHECK(!callback.is_null()); 334 DCHECK(!callback.is_null());
335 DCHECK_EQ(0, read_buf_unused_offset_); 335 DCHECK_EQ(0, read_buf_unused_offset_);
336 DCHECK(SendRequestBuffersEmpty());
336 337
337 // This function can be called with io_state_ == STATE_DONE if the 338 // This function can be called with io_state_ == STATE_DONE if the
338 // connection is closed after seeing just a 1xx response code. 339 // connection is closed after seeing just a 1xx response code.
339 if (io_state_ == STATE_DONE) 340 if (io_state_ == STATE_DONE)
340 return ERR_CONNECTION_CLOSED; 341 return ERR_CONNECTION_CLOSED;
341 342
342 int result = OK; 343 int result = OK;
343 io_state_ = STATE_READ_HEADERS; 344 io_state_ = STATE_READ_HEADERS;
344 345
345 if (read_buf_->offset() > 0) { 346 if (read_buf_->offset() > 0) {
(...skipping 16 matching lines...) Expand all
362 connection_->socket()->Disconnect(); 363 connection_->socket()->Disconnect();
363 connection_->Reset(); 364 connection_->Reset();
364 } 365 }
365 366
366 int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len, 367 int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len,
367 const CompletionCallback& callback) { 368 const CompletionCallback& callback) {
368 DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE); 369 DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE);
369 DCHECK(callback_.is_null()); 370 DCHECK(callback_.is_null());
370 DCHECK(!callback.is_null()); 371 DCHECK(!callback.is_null());
371 DCHECK_LE(buf_len, kMaxBufSize); 372 DCHECK_LE(buf_len, kMaxBufSize);
373 DCHECK(SendRequestBuffersEmpty());
372 // Added to investigate crbug.com/499663. 374 // Added to investigate crbug.com/499663.
373 CHECK(buf); 375 CHECK(buf);
374 376
375 if (io_state_ == STATE_DONE) 377 if (io_state_ == STATE_DONE)
376 return OK; 378 return OK;
377 379
378 user_read_buf_ = buf; 380 user_read_buf_ = buf;
379 user_read_buf_len_ = buf_len; 381 user_read_buf_len_ = buf_len;
380 io_state_ = STATE_READ_BODY; 382 io_state_ = STATE_READ_BODY;
381 383
(...skipping 20 matching lines...) Expand all
402 do { 404 do {
403 DCHECK_NE(ERR_IO_PENDING, result); 405 DCHECK_NE(ERR_IO_PENDING, result);
404 DCHECK_NE(STATE_DONE, io_state_); 406 DCHECK_NE(STATE_DONE, io_state_);
405 DCHECK_NE(STATE_NONE, io_state_); 407 DCHECK_NE(STATE_NONE, io_state_);
406 State state = io_state_; 408 State state = io_state_;
407 io_state_ = STATE_NONE; 409 io_state_ = STATE_NONE;
408 switch (state) { 410 switch (state) {
409 case STATE_SEND_HEADERS: 411 case STATE_SEND_HEADERS:
410 DCHECK_EQ(OK, result); 412 DCHECK_EQ(OK, result);
411 result = DoSendHeaders(); 413 result = DoSendHeaders();
414 DCHECK_NE(STATE_NONE, io_state_);
412 break; 415 break;
413 case STATE_SEND_HEADERS_COMPLETE: 416 case STATE_SEND_HEADERS_COMPLETE:
414 result = DoSendHeadersComplete(result); 417 result = DoSendHeadersComplete(result);
418 DCHECK_NE(STATE_NONE, io_state_);
415 break; 419 break;
416 case STATE_SEND_BODY: 420 case STATE_SEND_BODY:
417 DCHECK_EQ(OK, result); 421 DCHECK_EQ(OK, result);
418 result = DoSendBody(); 422 result = DoSendBody();
423 DCHECK_NE(STATE_NONE, io_state_);
419 break; 424 break;
420 case STATE_SEND_BODY_COMPLETE: 425 case STATE_SEND_BODY_COMPLETE:
421 result = DoSendBodyComplete(result); 426 result = DoSendBodyComplete(result);
427 DCHECK_NE(STATE_NONE, io_state_);
422 break; 428 break;
423 case STATE_SEND_REQUEST_READ_BODY_COMPLETE: 429 case STATE_SEND_REQUEST_READ_BODY_COMPLETE:
424 result = DoSendRequestReadBodyComplete(result); 430 result = DoSendRequestReadBodyComplete(result);
431 DCHECK_NE(STATE_NONE, io_state_);
432 break;
433 case STATE_SEND_REQUEST_COMPLETE:
434 result = DoSendRequestComplete(result);
425 break; 435 break;
426 case STATE_READ_HEADERS: 436 case STATE_READ_HEADERS:
427 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS); 437 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS);
428 DCHECK_GE(result, 0); 438 DCHECK_GE(result, 0);
429 result = DoReadHeaders(); 439 result = DoReadHeaders();
430 break; 440 break;
431 case STATE_READ_HEADERS_COMPLETE: 441 case STATE_READ_HEADERS_COMPLETE:
432 result = DoReadHeadersComplete(result); 442 result = DoReadHeadersComplete(result);
433 net_log_.EndEventWithNetErrorCode( 443 net_log_.EndEventWithNetErrorCode(
434 NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, result); 444 NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, result);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 return connection_->socket() 478 return connection_->socket()
469 ->Write(request_headers_.get(), bytes_remaining, io_callback_); 479 ->Write(request_headers_.get(), bytes_remaining, io_callback_);
470 } 480 }
471 481
472 int HttpStreamParser::DoSendHeadersComplete(int result) { 482 int HttpStreamParser::DoSendHeadersComplete(int result) {
473 if (result < 0) { 483 if (result < 0) {
474 // In the unlikely case that the headers and body were merged, all the 484 // In the unlikely case that the headers and body were merged, all the
475 // the headers were sent, but not all of the body way, and |result| is 485 // the headers were sent, but not all of the body way, and |result| is
476 // an error that this should try reading after, stash the error for now and 486 // an error that this should try reading after, stash the error for now and
477 // act like the request was successfully sent. 487 // act like the request was successfully sent.
488 io_state_ = STATE_SEND_REQUEST_COMPLETE;
478 if (request_headers_->BytesConsumed() >= request_headers_length_ && 489 if (request_headers_->BytesConsumed() >= request_headers_length_ &&
479 ShouldTryReadingOnUploadError(result)) { 490 ShouldTryReadingOnUploadError(result)) {
480 upload_error_ = result; 491 upload_error_ = result;
481 return OK; 492 return OK;
482 } 493 }
483 return result; 494 return result;
484 } 495 }
485 496
486 sent_bytes_ += result; 497 sent_bytes_ += result;
487 request_headers_->DidConsume(result); 498 request_headers_->DidConsume(result);
(...skipping 11 matching lines...) Expand all
499 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY, 510 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY,
500 base::Bind(&NetLogSendRequestBodyCallback, 511 base::Bind(&NetLogSendRequestBodyCallback,
501 request_->upload_data_stream->size(), 512 request_->upload_data_stream->size(),
502 request_->upload_data_stream->is_chunked(), 513 request_->upload_data_stream->is_chunked(),
503 false /* not merged */)); 514 false /* not merged */));
504 io_state_ = STATE_SEND_BODY; 515 io_state_ = STATE_SEND_BODY;
505 return OK; 516 return OK;
506 } 517 }
507 518
508 // Finished sending the request. 519 // Finished sending the request.
520 io_state_ = STATE_SEND_REQUEST_COMPLETE;
509 return OK; 521 return OK;
510 } 522 }
511 523
512 int HttpStreamParser::DoSendBody() { 524 int HttpStreamParser::DoSendBody() {
513 if (request_body_send_buf_->BytesRemaining() > 0) { 525 if (request_body_send_buf_->BytesRemaining() > 0) {
514 io_state_ = STATE_SEND_BODY_COMPLETE; 526 io_state_ = STATE_SEND_BODY_COMPLETE;
515 return connection_->socket() 527 return connection_->socket()
516 ->Write(request_body_send_buf_.get(), 528 ->Write(request_body_send_buf_.get(),
517 request_body_send_buf_->BytesRemaining(), 529 request_body_send_buf_->BytesRemaining(),
518 io_callback_); 530 io_callback_);
519 } 531 }
520 532
521 if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) { 533 if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) {
522 // Finished sending the request. 534 // Finished sending the request.
535 io_state_ = STATE_SEND_REQUEST_COMPLETE;
523 return OK; 536 return OK;
524 } 537 }
525 538
526 request_body_read_buf_->Clear(); 539 request_body_read_buf_->Clear();
527 io_state_ = STATE_SEND_REQUEST_READ_BODY_COMPLETE; 540 io_state_ = STATE_SEND_REQUEST_READ_BODY_COMPLETE;
528 return request_->upload_data_stream->Read(request_body_read_buf_.get(), 541 return request_->upload_data_stream->Read(request_body_read_buf_.get(),
529 request_body_read_buf_->capacity(), 542 request_body_read_buf_->capacity(),
530 io_callback_); 543 io_callback_);
531 } 544 }
532 545
533 int HttpStreamParser::DoSendBodyComplete(int result) { 546 int HttpStreamParser::DoSendBodyComplete(int result) {
534 if (result < 0) { 547 if (result < 0) {
535 // If |result| is an error that this should try reading after, stash the 548 // If |result| is an error that this should try reading after, stash the
536 // error for now and act like the request was successfully sent. 549 // error for now and act like the request was successfully sent.
550 io_state_ = STATE_SEND_REQUEST_COMPLETE;
537 if (ShouldTryReadingOnUploadError(result)) { 551 if (ShouldTryReadingOnUploadError(result)) {
538 upload_error_ = result; 552 upload_error_ = result;
539 return OK; 553 return OK;
540 } 554 }
541 return result; 555 return result;
542 } 556 }
543 557
544 sent_bytes_ += result; 558 sent_bytes_ += result;
545 request_body_send_buf_->DidConsume(result); 559 request_body_send_buf_->DidConsume(result);
546 560
547 io_state_ = STATE_SEND_BODY; 561 io_state_ = STATE_SEND_BODY;
548 return OK; 562 return OK;
549 } 563 }
550 564
551 int HttpStreamParser::DoSendRequestReadBodyComplete(int result) { 565 int HttpStreamParser::DoSendRequestReadBodyComplete(int result) {
552 // |result| is the result of read from the request body from the last call to 566 // |result| is the result of read from the request body from the last call to
553 // DoSendBody(). 567 // DoSendBody().
554 if (result < 0) 568 if (result < 0) {
569 io_state_ = STATE_SEND_REQUEST_COMPLETE;
555 return result; 570 return result;
571 }
556 572
557 // Chunked data needs to be encoded. 573 // Chunked data needs to be encoded.
558 if (request_->upload_data_stream->is_chunked()) { 574 if (request_->upload_data_stream->is_chunked()) {
559 if (result == 0) { // Reached the end. 575 if (result == 0) { // Reached the end.
560 DCHECK(request_->upload_data_stream->IsEOF()); 576 DCHECK(request_->upload_data_stream->IsEOF());
561 sent_last_chunk_ = true; 577 sent_last_chunk_ = true;
562 } 578 }
563 // Encode the buffer as 1 chunk. 579 // Encode the buffer as 1 chunk.
564 const base::StringPiece payload(request_body_read_buf_->data(), result); 580 const base::StringPiece payload(request_body_read_buf_->data(), result);
565 request_body_send_buf_->Clear(); 581 request_body_send_buf_->Clear();
566 result = EncodeChunk(payload, 582 result = EncodeChunk(payload,
567 request_body_send_buf_->data(), 583 request_body_send_buf_->data(),
568 request_body_send_buf_->capacity()); 584 request_body_send_buf_->capacity());
569 } 585 }
570 586
571 if (result == 0) { // Reached the end. 587 if (result == 0) { // Reached the end.
572 // Reaching EOF means we can finish sending request body unless the data is 588 // Reaching EOF means we can finish sending request body unless the data is
573 // chunked. (i.e. No need to send the terminal chunk.) 589 // chunked. (i.e. No need to send the terminal chunk.)
574 DCHECK(request_->upload_data_stream->IsEOF()); 590 DCHECK(request_->upload_data_stream->IsEOF());
575 DCHECK(!request_->upload_data_stream->is_chunked()); 591 DCHECK(!request_->upload_data_stream->is_chunked());
576 // Finished sending the request. 592 // Finished sending the request.
593 io_state_ = STATE_SEND_REQUEST_COMPLETE;
577 } else if (result > 0) { 594 } else if (result > 0) {
578 request_body_send_buf_->DidAppend(result); 595 request_body_send_buf_->DidAppend(result);
579 result = 0; 596 result = 0;
580 io_state_ = STATE_SEND_BODY; 597 io_state_ = STATE_SEND_BODY;
581 } 598 }
582 return result; 599 return result;
583 } 600 }
584 601
602 int HttpStreamParser::DoSendRequestComplete(int result) {
603 DCHECK_NE(result, ERR_IO_PENDING);
604 FlushBuffers();
605 return result;
606 }
607
585 int HttpStreamParser::DoReadHeaders() { 608 int HttpStreamParser::DoReadHeaders() {
586 io_state_ = STATE_READ_HEADERS_COMPLETE; 609 io_state_ = STATE_READ_HEADERS_COMPLETE;
587 610
588 // Grow the read buffer if necessary. 611 // Grow the read buffer if necessary.
589 if (read_buf_->RemainingCapacity() == 0) 612 if (read_buf_->RemainingCapacity() == 0)
590 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize); 613 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize);
591 614
592 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. 615 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
593 // See if the user is passing in an IOBuffer with a NULL |data_|. 616 // See if the user is passing in an IOBuffer with a NULL |data_|.
594 CHECK(read_buf_->data()); 617 CHECK(read_buf_->data());
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 return false; 1210 return false;
1188 } 1211 }
1189 1212
1190 void HttpStreamParser::ValidateStatusLine(const std::string& status_line) { 1213 void HttpStreamParser::ValidateStatusLine(const std::string& status_line) {
1191 HttpStatusLineValidator::StatusLineStatus status = 1214 HttpStatusLineValidator::StatusLineStatus status =
1192 HttpStatusLineValidator::ValidateStatusLine(status_line); 1215 HttpStatusLineValidator::ValidateStatusLine(status_line);
1193 UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status, 1216 UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status,
1194 HttpStatusLineValidator::STATUS_LINE_MAX); 1217 HttpStatusLineValidator::STATUS_LINE_MAX);
1195 } 1218 }
1196 1219
1220 void HttpStreamParser::FlushBuffers() {
mmenke 2016/07/12 16:13:41 nit: You can inline this in HttpStreamParser::DoS
1221 request_headers_ = nullptr;
1222 request_body_send_buf_ = nullptr;
1223 request_body_read_buf_ = nullptr;
1224 }
1225
1226 bool HttpStreamParser::SendRequestBuffersEmpty() {
1227 return request_headers_ == nullptr && request_body_send_buf_ == nullptr &&
1228 request_body_send_buf_ == nullptr;
1229 }
1230
1197 } // namespace net 1231 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698