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 |