| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 // Check to see if we're done reading. | 523 // Check to see if we're done reading. |
| 524 if (IsResponseBodyComplete()) | 524 if (IsResponseBodyComplete()) |
| 525 return 0; | 525 return 0; |
| 526 | 526 |
| 527 DCHECK_EQ(0, read_buf_->offset()); | 527 DCHECK_EQ(0, read_buf_->offset()); |
| 528 return connection_->socket()->Read(user_read_buf_, user_read_buf_len_, | 528 return connection_->socket()->Read(user_read_buf_, user_read_buf_len_, |
| 529 &io_callback_); | 529 &io_callback_); |
| 530 } | 530 } |
| 531 | 531 |
| 532 int HttpStreamParser::DoReadBodyComplete(int result) { | 532 int HttpStreamParser::DoReadBodyComplete(int result) { |
| 533 // When the connection is closed, there are numerous ways to interpret it. | 533 // If we didn't get a Content-Length and aren't using a chunked encoding, |
| 534 // | 534 // the only way to signal the end of a stream is to close the connection, |
| 535 // - If a Content-Length header is present and the body contains exactly that | 535 // so we don't treat that as an error, though in some cases we may not |
| 536 // number of bytes at connection close, the response is successful. | 536 // have completely received the resource. |
| 537 // | 537 if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse()) |
| 538 // - If a Content-Length header is present and the body contains fewer bytes | 538 result = ERR_CONNECTION_CLOSED; |
| 539 // than promised by the header at connection close, it may indicate that | |
| 540 // the connection was closed prematurely, or it may indicate that the | |
| 541 // server sent an invalid Content-Length header. Unfortunately, the invalid | |
| 542 // Content-Length header case does occur in practice and other browsers are | |
| 543 // tolerant of it, so this is reported as an ERR_CONTENT_LENGTH_MISMATCH | |
| 544 // rather than an ERR_CONNECTION_CLOSE. | |
| 545 // | |
| 546 // - If chunked encoding is used and the terminating chunk has been processed | |
| 547 // when the connection is closed, the response is successful. | |
| 548 // | |
| 549 // - If chunked encoding is used and the terminating chunk has not been | |
| 550 // processed when the connection is closed, it may indicate that the | |
| 551 // connection was closed prematurely or it may indicate that the server | |
| 552 // sent an invalid chunked encoding. We choose to treat it as | |
| 553 // an invalid chunked encoding. | |
| 554 // | |
| 555 // - If a Content-Length is not present and chunked encoding is not used, | |
| 556 // connection close is the only way to signal that the response is | |
| 557 // complete. Unfortunately, this also means that there is no way to detect | |
| 558 // early close of a connection. No error is returned. | |
| 559 if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse()) { | |
| 560 if (chunked_decoder_.get()) | |
| 561 result = ERR_INVALID_CHUNKED_ENCODING; | |
| 562 else | |
| 563 result = ERR_CONTENT_LENGTH_MISMATCH; | |
| 564 } | |
| 565 | 539 |
| 566 // Filter incoming data if appropriate. FilterBuf may return an error. | 540 // Filter incoming data if appropriate. FilterBuf may return an error. |
| 567 if (result > 0 && chunked_decoder_.get()) { | 541 if (result > 0 && chunked_decoder_.get()) { |
| 568 result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result); | 542 result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result); |
| 569 if (result == 0 && !chunked_decoder_->reached_eof()) { | 543 if (result == 0 && !chunked_decoder_->reached_eof()) { |
| 570 // Don't signal completion of the Read call yet or else it'll look like | 544 // Don't signal completion of the Read call yet or else it'll look like |
| 571 // we received end-of-file. Wait for more data. | 545 // we received end-of-file. Wait for more data. |
| 572 io_state_ = STATE_READ_BODY; | 546 io_state_ = STATE_READ_BODY; |
| 573 return OK; | 547 return OK; |
| 574 } | 548 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 void HttpStreamParser::GetSSLCertRequestInfo( | 759 void HttpStreamParser::GetSSLCertRequestInfo( |
| 786 SSLCertRequestInfo* cert_request_info) { | 760 SSLCertRequestInfo* cert_request_info) { |
| 787 if (request_->url.SchemeIs("https") && connection_->socket()) { | 761 if (request_->url.SchemeIs("https") && connection_->socket()) { |
| 788 SSLClientSocket* ssl_socket = | 762 SSLClientSocket* ssl_socket = |
| 789 static_cast<SSLClientSocket*>(connection_->socket()); | 763 static_cast<SSLClientSocket*>(connection_->socket()); |
| 790 ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 764 ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| 791 } | 765 } |
| 792 } | 766 } |
| 793 | 767 |
| 794 } // namespace net | 768 } // namespace net |
| OLD | NEW |