Chromium Code Reviews| 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 <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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |