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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 | 72 |
| 73 namespace net { | 73 namespace net { |
| 74 | 74 |
| 75 // Similar to DrainableIOBuffer(), but this version comes with its own | 75 // Similar to DrainableIOBuffer(), but this version comes with its own |
| 76 // storage. The motivation is to avoid repeated allocations of | 76 // storage. The motivation is to avoid repeated allocations of |
| 77 // DrainableIOBuffer. | 77 // DrainableIOBuffer. |
| 78 // | 78 // |
| 79 // Example: | 79 // Example: |
| 80 // | 80 // |
| 81 // scoped_refptr<SeekableIOBuffer> buf = new SeekableIOBuffer(1024); | 81 // scoped_refptr<SeekableIOBuffer> buf = new SeekableIOBuffer(1024); |
| 82 // // capacity() == 1024. size() == BytesRemaining == BytesConsumed() == 0. | 82 // // capacity() == 1024. size() == BytesRemaining() == BytesConsumed() == 0. |
| 83 // // data() points to the beginning of the buffer. | 83 // // data() points to the beginning of the buffer. |
| 84 // | 84 // |
| 85 // // Read() takes an IOBuffer. | 85 // // Read() takes an IOBuffer. |
| 86 // int bytes_read = some_reader->Read(buf, buf->capacity()); | 86 // int bytes_read = some_reader->Read(buf, buf->capacity()); |
| 87 // buf->DidAppend(bytes_read); | 87 // buf->DidAppend(bytes_read); |
| 88 // // size() == BytesRemaining() == bytes_read. data() is unaffected. | 88 // // size() == BytesRemaining() == bytes_read. data() is unaffected. |
| 89 // | 89 // |
| 90 // while (buf->BytesRemaining() > 0) { | 90 // while (buf->BytesRemaining() > 0) { |
| 91 // // Write() takes an IOBuffer. If it takes const char*, we could | 91 // // Write() takes an IOBuffer. If it takes const char*, we could |
| 92 /// // simply use the regular IOBuffer like buf->data() + offset. | 92 /// // simply use the regular IOBuffer like buf->data() + offset. |
| 93 // int bytes_written = Write(buf, buf->BytesRemaining()); | 93 // int bytes_written = Write(buf, buf->BytesRemaining()); |
| 94 // buf->DidConsume(bytes_written); | 94 // buf->DidConsume(bytes_written); |
| 95 // } | 95 // } |
| 96 // // BytesRemaining() == 0. BytesConsumed() == size(). | 96 // // BytesRemaining() == 0. BytesConsumed() == size(). |
| 97 // // data() points to the end of the comsumed bytes (exclusive). | 97 // // data() points to the end of the consumed bytes (exclusive). |
| 98 // | 98 // |
| 99 // // If you want to reuse the buffer, be sure to clear the buffer. | 99 // // If you want to reuse the buffer, be sure to clear the buffer. |
| 100 // buf->Clear(); | 100 // buf->Clear(); |
| 101 // // size() == BytesRemaining() == BytesConsumed() == 0. | 101 // // size() == BytesRemaining() == BytesConsumed() == 0. |
| 102 // // data() points to the beginning of the buffer. | 102 // // data() points to the beginning of the buffer. |
| 103 // | 103 // |
| 104 class HttpStreamParser::SeekableIOBuffer : public net::IOBuffer { | 104 class HttpStreamParser::SeekableIOBuffer : public net::IOBuffer { |
| 105 public: | 105 public: |
| 106 explicit SeekableIOBuffer(int capacity) | 106 explicit SeekableIOBuffer(int capacity) |
| 107 : IOBuffer(capacity), | 107 : IOBuffer(capacity), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 // the object is created. | 154 // the object is created. |
| 155 int capacity() const { return capacity_; }; | 155 int capacity() const { return capacity_; }; |
| 156 | 156 |
| 157 private: | 157 private: |
| 158 virtual ~SeekableIOBuffer() { | 158 virtual ~SeekableIOBuffer() { |
| 159 // data_ will be deleted in IOBuffer::~IOBuffer(). | 159 // data_ will be deleted in IOBuffer::~IOBuffer(). |
| 160 data_ = real_data_; | 160 data_ = real_data_; |
| 161 } | 161 } |
| 162 | 162 |
| 163 char* real_data_; | 163 char* real_data_; |
| 164 int capacity_; | 164 const int capacity_; |
| 165 int size_; | 165 int size_; |
| 166 int used_; | 166 int used_; |
| 167 }; | 167 }; |
| 168 | 168 |
| 169 // 2 CRLFs + max of 8 hex chars. | 169 // 2 CRLFs + max of 8 hex chars. |
| 170 const size_t HttpStreamParser::kChunkHeaderFooterSize = 12; | 170 const size_t HttpStreamParser::kChunkHeaderFooterSize = 12; |
| 171 | 171 |
| 172 HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, | 172 HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, |
| 173 const HttpRequestInfo* request, | 173 const HttpRequestInfo* request, |
| 174 GrowableIOBuffer* read_buffer, | 174 GrowableIOBuffer* read_buffer, |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 if (result == ERR_IO_PENDING) | 286 if (result == ERR_IO_PENDING) |
| 287 callback_ = callback; | 287 callback_ = callback; |
| 288 | 288 |
| 289 return result > 0 ? OK : result; | 289 return result > 0 ? OK : result; |
| 290 } | 290 } |
| 291 | 291 |
| 292 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) { | 292 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) { |
| 293 DCHECK(io_state_ == STATE_REQUEST_SENT || io_state_ == STATE_DONE); | 293 DCHECK(io_state_ == STATE_REQUEST_SENT || io_state_ == STATE_DONE); |
| 294 DCHECK(callback_.is_null()); | 294 DCHECK(callback_.is_null()); |
| 295 DCHECK(!callback.is_null()); | 295 DCHECK(!callback.is_null()); |
| 296 DCHECK_EQ(0, read_buf_unused_offset_); | |
| 296 | 297 |
| 297 // This function can be called with io_state_ == STATE_DONE if the | 298 // This function can be called with io_state_ == STATE_DONE if the |
| 298 // connection is closed after seeing just a 1xx response code. | 299 // connection is closed after seeing just a 1xx response code. |
| 299 if (io_state_ == STATE_DONE) | 300 if (io_state_ == STATE_DONE) |
| 300 return ERR_CONNECTION_CLOSED; | 301 return ERR_CONNECTION_CLOSED; |
| 301 | 302 |
| 302 int result = OK; | 303 int result = OK; |
| 303 io_state_ = STATE_READ_HEADERS; | 304 io_state_ = STATE_READ_HEADERS; |
| 304 | 305 |
| 305 if (read_buf_->offset() > 0) { | 306 if (read_buf_->offset() > 0) { |
| 306 // Simulate the state where the data was just read from the socket. | 307 // Simulate the state where the data was just read from the socket. |
| 307 result = read_buf_->offset() - read_buf_unused_offset_; | 308 result = read_buf_->offset(); |
| 308 read_buf_->set_offset(read_buf_unused_offset_); | 309 read_buf_->set_offset(0); |
| 309 } | 310 } |
| 310 if (result > 0) | 311 if (result > 0) |
| 311 io_state_ = STATE_READ_HEADERS_COMPLETE; | 312 io_state_ = STATE_READ_HEADERS_COMPLETE; |
| 312 | 313 |
| 313 result = DoLoop(result); | 314 result = DoLoop(result); |
| 314 if (result == ERR_IO_PENDING) | 315 if (result == ERR_IO_PENDING) |
| 315 callback_ = callback; | 316 callback_ = callback; |
| 316 | 317 |
| 317 return result > 0 ? OK : result; | 318 return result > 0 ? OK : result; |
| 318 } | 319 } |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 | 511 |
| 511 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. | 512 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. |
| 512 // See if the user is passing in an IOBuffer with a NULL |data_|. | 513 // See if the user is passing in an IOBuffer with a NULL |data_|. |
| 513 CHECK(read_buf_->data()); | 514 CHECK(read_buf_->data()); |
| 514 | 515 |
| 515 return connection_->socket() | 516 return connection_->socket() |
| 516 ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_); | 517 ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_); |
| 517 } | 518 } |
| 518 | 519 |
| 519 int HttpStreamParser::DoReadHeadersComplete(int result) { | 520 int HttpStreamParser::DoReadHeadersComplete(int result) { |
| 521 DCHECK_EQ(0, read_buf_unused_offset_); | |
| 522 | |
| 520 if (result == 0) | 523 if (result == 0) |
| 521 result = ERR_CONNECTION_CLOSED; | 524 result = ERR_CONNECTION_CLOSED; |
| 522 | 525 |
| 523 if (result < 0 && result != ERR_CONNECTION_CLOSED) { | 526 if (result < 0 && result != ERR_CONNECTION_CLOSED) { |
| 524 io_state_ = STATE_DONE; | 527 io_state_ = STATE_DONE; |
| 525 return result; | 528 return result; |
| 526 } | 529 } |
| 527 // If we've used the connection before, then we know it is not a HTTP/0.9 | 530 // If we've used the connection before, then we know it is not a HTTP/0.9 |
| 528 // response and return ERR_CONNECTION_CLOSED. | 531 // response and return ERR_CONNECTION_CLOSED. |
| 529 if (result == ERR_CONNECTION_CLOSED && read_buf_->offset() == 0 && | 532 if (result == ERR_CONNECTION_CLOSED && read_buf_->offset() == 0 && |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 int end_of_header_offset = ParseResponseHeaders(); | 576 int end_of_header_offset = ParseResponseHeaders(); |
| 574 | 577 |
| 575 // Note: -1 is special, it indicates we haven't found the end of headers. | 578 // Note: -1 is special, it indicates we haven't found the end of headers. |
| 576 // Anything less than -1 is a net::Error, so we bail out. | 579 // Anything less than -1 is a net::Error, so we bail out. |
| 577 if (end_of_header_offset < -1) | 580 if (end_of_header_offset < -1) |
| 578 return end_of_header_offset; | 581 return end_of_header_offset; |
| 579 | 582 |
| 580 if (end_of_header_offset == -1) { | 583 if (end_of_header_offset == -1) { |
| 581 io_state_ = STATE_READ_HEADERS; | 584 io_state_ = STATE_READ_HEADERS; |
| 582 // Prevent growing the headers buffer indefinitely. | 585 // Prevent growing the headers buffer indefinitely. |
| 583 if (read_buf_->offset() - read_buf_unused_offset_ >= kMaxHeaderBufSize) { | 586 if (read_buf_->offset() >= kMaxHeaderBufSize) { |
| 584 io_state_ = STATE_DONE; | 587 io_state_ = STATE_DONE; |
| 585 return ERR_RESPONSE_HEADERS_TOO_BIG; | 588 return ERR_RESPONSE_HEADERS_TOO_BIG; |
| 586 } | 589 } |
| 587 } else { | 590 } else { |
| 591 CalculateResponseBodySize(); | |
| 592 // If the body is 0, the caller may not call ReadResponseBody, which | |
|
wtc
2013/10/01 18:12:57
1. Nit: "If the body is 0" isn't clear. I think it
agl
2013/10/01 19:53:18
Fixed.
| |
| 593 // is where any extra data is copied to read_buf_, so we move the | |
| 594 // data here. | |
| 595 if (response_body_length_ == 0) { | |
| 596 int extra_bytes = read_buf_->offset() - end_of_header_offset; | |
| 597 if (extra_bytes) { | |
| 598 CHECK_GT(extra_bytes, 0); | |
| 599 memmove(read_buf_->StartOfBuffer(), | |
|
wtc
2013/10/01 18:12:57
IMPORTANT: is it correct to move the extra data fo
agl
2013/10/01 19:53:18
(see bug.)
| |
| 600 read_buf_->StartOfBuffer() + end_of_header_offset, | |
| 601 extra_bytes); | |
| 602 } | |
| 603 read_buf_->SetCapacity(extra_bytes); | |
| 604 read_buf_unused_offset_ = 0; | |
|
wtc
2013/10/01 18:12:57
This is not necessary in the new code. (It was nec
agl
2013/10/01 19:53:18
Done.
| |
| 605 if (response_->headers->response_code() / 100 == 1) { | |
| 606 // After processing a 1xx response, the caller will ask for the next | |
| 607 // header, so reset state to support that. We don't completely ignore a | |
|
wtc
2013/10/01 18:12:57
Nit: delete "a" at the end of this line.
agl
2013/10/01 19:53:18
Done.
| |
| 608 // 1xx responses because they cannot be returned in reply to a CONNECT | |
| 609 // request so we return OK here, which lets the caller inspect the | |
| 610 // response and reject it in the event that we're setting up a CONNECT | |
| 611 // tunnel. | |
| 612 response_header_start_offset_ = -1; | |
| 613 response_body_length_ = -1; | |
|
wtc
2013/10/01 18:12:57
Why do we need to change response_body_length_ to
agl
2013/10/01 19:53:18
It will have been set to 0 by CalculateResponseBod
| |
| 614 io_state_ = STATE_REQUEST_SENT; | |
| 615 } else { | |
| 616 io_state_ = STATE_DONE; | |
| 617 } | |
| 618 return OK; | |
| 619 } | |
| 620 | |
| 588 // Note where the headers stop. | 621 // Note where the headers stop. |
| 589 read_buf_unused_offset_ = end_of_header_offset; | 622 read_buf_unused_offset_ = end_of_header_offset; |
| 590 | 623 io_state_ = STATE_BODY_PENDING; |
| 591 if (response_->headers->response_code() / 100 == 1) { | |
| 592 // After processing a 1xx response, the caller will ask for the next | |
| 593 // header, so reset state to support that. We don't just skip these | |
| 594 // completely because 1xx codes aren't acceptable when establishing a | |
| 595 // tunnel. | |
| 596 io_state_ = STATE_REQUEST_SENT; | |
| 597 response_header_start_offset_ = -1; | |
| 598 } else { | |
| 599 io_state_ = STATE_BODY_PENDING; | |
| 600 CalculateResponseBodySize(); | |
| 601 // If the body is 0, the caller may not call ReadResponseBody, which | |
| 602 // is where any extra data is copied to read_buf_, so we move the | |
| 603 // data here and transition to DONE. | |
| 604 if (response_body_length_ == 0) { | |
| 605 io_state_ = STATE_DONE; | |
| 606 int extra_bytes = read_buf_->offset() - read_buf_unused_offset_; | |
| 607 if (extra_bytes) { | |
| 608 CHECK_GT(extra_bytes, 0); | |
| 609 memmove(read_buf_->StartOfBuffer(), | |
| 610 read_buf_->StartOfBuffer() + read_buf_unused_offset_, | |
| 611 extra_bytes); | |
| 612 } | |
| 613 read_buf_->SetCapacity(extra_bytes); | |
| 614 read_buf_unused_offset_ = 0; | |
| 615 return OK; | |
| 616 } | |
| 617 } | |
| 618 } | 624 } |
| 619 return result; | 625 return result; |
| 620 } | 626 } |
| 621 | 627 |
| 622 int HttpStreamParser::DoReadBody() { | 628 int HttpStreamParser::DoReadBody() { |
| 623 io_state_ = STATE_READ_BODY_COMPLETE; | 629 io_state_ = STATE_READ_BODY_COMPLETE; |
| 624 | 630 |
| 625 // There may be some data left over from reading the response headers. | 631 // There may be some data left over from reading the response headers. |
| 626 if (read_buf_->offset()) { | 632 if (read_buf_->offset()) { |
| 627 int available = read_buf_->offset() - read_buf_unused_offset_; | 633 int available = read_buf_->offset() - read_buf_unused_offset_; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 744 io_state_ = STATE_BODY_PENDING; | 750 io_state_ = STATE_BODY_PENDING; |
| 745 user_read_buf_ = NULL; | 751 user_read_buf_ = NULL; |
| 746 user_read_buf_len_ = 0; | 752 user_read_buf_len_ = 0; |
| 747 } | 753 } |
| 748 | 754 |
| 749 return result; | 755 return result; |
| 750 } | 756 } |
| 751 | 757 |
| 752 int HttpStreamParser::ParseResponseHeaders() { | 758 int HttpStreamParser::ParseResponseHeaders() { |
| 753 int end_offset = -1; | 759 int end_offset = -1; |
| 760 DCHECK_EQ(0, read_buf_unused_offset_); | |
| 754 | 761 |
| 755 // Look for the start of the status line, if it hasn't been found yet. | 762 // Look for the start of the status line, if it hasn't been found yet. |
| 756 if (response_header_start_offset_ < 0) { | 763 if (response_header_start_offset_ < 0) { |
| 757 response_header_start_offset_ = HttpUtil::LocateStartOfStatusLine( | 764 response_header_start_offset_ = HttpUtil::LocateStartOfStatusLine( |
| 758 read_buf_->StartOfBuffer() + read_buf_unused_offset_, | 765 read_buf_->StartOfBuffer(), read_buf_->offset()); |
| 759 read_buf_->offset() - read_buf_unused_offset_); | |
| 760 } | 766 } |
| 761 | 767 |
| 762 if (response_header_start_offset_ >= 0) { | 768 if (response_header_start_offset_ >= 0) { |
| 763 end_offset = HttpUtil::LocateEndOfHeaders( | 769 end_offset = HttpUtil::LocateEndOfHeaders(read_buf_->StartOfBuffer(), |
| 764 read_buf_->StartOfBuffer() + read_buf_unused_offset_, | 770 read_buf_->offset(), |
| 765 read_buf_->offset() - read_buf_unused_offset_, | 771 response_header_start_offset_); |
| 766 response_header_start_offset_); | 772 } else if (read_buf_->offset() >= 8) { |
| 767 } else if (read_buf_->offset() - read_buf_unused_offset_ >= 8) { | |
| 768 // Enough data to decide that this is an HTTP/0.9 response. | 773 // Enough data to decide that this is an HTTP/0.9 response. |
| 769 // 8 bytes = (4 bytes of junk) + "http".length() | 774 // 8 bytes = (4 bytes of junk) + "http".length() |
| 770 end_offset = 0; | 775 end_offset = 0; |
| 771 } | 776 } |
| 772 | 777 |
| 773 if (end_offset == -1) | 778 if (end_offset == -1) |
| 774 return -1; | 779 return -1; |
| 775 | 780 |
| 776 int rv = DoParseResponseHeaders(end_offset); | 781 int rv = DoParseResponseHeaders(end_offset); |
| 777 if (rv < 0) | 782 if (rv < 0) |
| 778 return rv; | 783 return rv; |
| 779 return end_offset + read_buf_unused_offset_; | 784 return end_offset; |
| 780 } | 785 } |
| 781 | 786 |
| 782 int HttpStreamParser::DoParseResponseHeaders(int end_offset) { | 787 int HttpStreamParser::DoParseResponseHeaders(int end_offset) { |
| 783 scoped_refptr<HttpResponseHeaders> headers; | 788 scoped_refptr<HttpResponseHeaders> headers; |
| 789 DCHECK_EQ(0, read_buf_unused_offset_); | |
| 790 | |
| 784 if (response_header_start_offset_ >= 0) { | 791 if (response_header_start_offset_ >= 0) { |
| 785 headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders( | 792 headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders( |
| 786 read_buf_->StartOfBuffer() + read_buf_unused_offset_, end_offset)); | 793 read_buf_->StartOfBuffer(), end_offset)); |
| 787 } else { | 794 } else { |
| 788 // Enough data was read -- there is no status line. | 795 // Enough data was read -- there is no status line. |
| 789 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); | 796 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); |
| 790 } | 797 } |
| 791 | 798 |
| 792 // Check for multiple Content-Length headers with no Transfer-Encoding header. | 799 // Check for multiple Content-Length headers with no Transfer-Encoding header. |
| 793 // If they exist, and have distinct values, it's a potential response | 800 // If they exist, and have distinct values, it's a potential response |
| 794 // smuggling attack. | 801 // smuggling attack. |
| 795 if (!headers->HasHeader("Transfer-Encoding")) { | 802 if (!headers->HasHeader("Transfer-Encoding")) { |
| 796 if (HeadersContainMultipleCopiesOfField(*headers.get(), "Content-Length")) | 803 if (HeadersContainMultipleCopiesOfField(*headers.get(), "Content-Length")) |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 823 // RFC 2616 Section 4.3 Message Body: | 830 // RFC 2616 Section 4.3 Message Body: |
| 824 // | 831 // |
| 825 // For response messages, whether or not a message-body is included with | 832 // For response messages, whether or not a message-body is included with |
| 826 // a message is dependent on both the request method and the response | 833 // a message is dependent on both the request method and the response |
| 827 // status code (section 6.1.1). All responses to the HEAD request method | 834 // status code (section 6.1.1). All responses to the HEAD request method |
| 828 // MUST NOT include a message-body, even though the presence of entity- | 835 // MUST NOT include a message-body, even though the presence of entity- |
| 829 // header fields might lead one to believe they do. All 1xx | 836 // header fields might lead one to believe they do. All 1xx |
| 830 // (informational), 204 (no content), and 304 (not modified) responses | 837 // (informational), 204 (no content), and 304 (not modified) responses |
| 831 // MUST NOT include a message-body. All other responses do include a | 838 // MUST NOT include a message-body. All other responses do include a |
| 832 // message-body, although it MAY be of zero length. | 839 // message-body, although it MAY be of zero length. |
| 833 switch (response_->headers->response_code()) { | 840 if (response_->headers->response_code() / 100 == 1) { |
| 834 // Note that 1xx was already handled earlier. | 841 response_body_length_ = 0; |
| 835 case 204: // No Content | 842 } else { |
| 836 case 205: // Reset Content | 843 switch (response_->headers->response_code()) { |
| 837 case 304: // Not Modified | 844 case 204: // No Content |
| 838 response_body_length_ = 0; | 845 case 205: // Reset Content |
| 839 break; | 846 case 304: // Not Modified |
| 847 response_body_length_ = 0; | |
| 848 break; | |
| 849 } | |
| 840 } | 850 } |
| 841 if (request_->method == "HEAD") | 851 if (request_->method == "HEAD") |
| 842 response_body_length_ = 0; | 852 response_body_length_ = 0; |
| 843 | 853 |
| 844 if (response_body_length_ == -1) { | 854 if (response_body_length_ == -1) { |
| 845 // "Transfer-Encoding: chunked" trumps "Content-Length: N" | 855 // "Transfer-Encoding: chunked" trumps "Content-Length: N" |
| 846 if (response_->headers->IsChunkEncoded()) { | 856 if (response_->headers->IsChunkEncoded()) { |
| 847 chunked_decoder_.reset(new HttpChunkedDecoder()); | 857 chunked_decoder_.reset(new HttpChunkedDecoder()); |
| 848 } else { | 858 } else { |
| 849 response_body_length_ = response_->headers->GetContentLength(); | 859 response_body_length_ = response_->headers->GetContentLength(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 946 request_body->IsInMemory() && | 956 request_body->IsInMemory() && |
| 947 request_body->size() > 0) { | 957 request_body->size() > 0) { |
| 948 size_t merged_size = request_headers.size() + request_body->size(); | 958 size_t merged_size = request_headers.size() + request_body->size(); |
| 949 if (merged_size <= kMaxMergedHeaderAndBodySize) | 959 if (merged_size <= kMaxMergedHeaderAndBodySize) |
| 950 return true; | 960 return true; |
| 951 } | 961 } |
| 952 return false; | 962 return false; |
| 953 } | 963 } |
| 954 | 964 |
| 955 } // namespace net | 965 } // namespace net |
| OLD | NEW |