| 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/spdy/spdy_framer.h" | 5 #include "net/spdy/spdy_framer.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <ios> | 10 #include <ios> |
| 11 #include <iterator> | 11 #include <iterator> |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 17 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
| 18 #include "net/quic/quic_flags.h" | 18 #include "net/quic/quic_flags.h" |
| 19 #include "net/spdy/hpack/hpack_constants.h" | 19 #include "net/spdy/hpack/hpack_constants.h" |
| 20 #include "net/spdy/spdy_bitmasks.h" | 20 #include "net/spdy/spdy_bitmasks.h" |
| 21 #include "net/spdy/spdy_bug_tracker.h" | 21 #include "net/spdy/spdy_bug_tracker.h" |
| 22 #include "net/spdy/spdy_frame_builder.h" | 22 #include "net/spdy/spdy_frame_builder.h" |
| 23 #include "net/spdy/spdy_frame_reader.h" | 23 #include "net/spdy/spdy_frame_reader.h" |
| 24 #include "net/spdy/spdy_headers_block_parser.h" | |
| 25 #include "third_party/zlib/zlib.h" | 24 #include "third_party/zlib/zlib.h" |
| 26 | 25 |
| 27 using base::StringPiece; | 26 using base::StringPiece; |
| 28 using std::hex; | 27 using std::hex; |
| 29 using std::string; | 28 using std::string; |
| 30 using std::vector; | 29 using std::vector; |
| 31 | 30 |
| 32 namespace net { | 31 namespace net { |
| 33 | 32 |
| 34 namespace { | 33 namespace { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 const char* rst_stream_data, | 163 const char* rst_stream_data, |
| 165 size_t len) { | 164 size_t len) { |
| 166 return true; | 165 return true; |
| 167 } | 166 } |
| 168 | 167 |
| 169 SpdyFramer::SpdyFramer(SpdyMajorVersion version) | 168 SpdyFramer::SpdyFramer(SpdyMajorVersion version) |
| 170 : current_frame_buffer_(kControlFrameBufferSize), | 169 : current_frame_buffer_(kControlFrameBufferSize), |
| 171 expect_continuation_(0), | 170 expect_continuation_(0), |
| 172 visitor_(NULL), | 171 visitor_(NULL), |
| 173 debug_visitor_(NULL), | 172 debug_visitor_(NULL), |
| 174 header_handler_(nullptr), | |
| 175 display_protocol_("SPDY"), | 173 display_protocol_("SPDY"), |
| 176 protocol_version_(version), | 174 protocol_version_(version), |
| 177 enable_compression_(true), | 175 enable_compression_(true), |
| 178 syn_frame_processed_(false), | 176 syn_frame_processed_(false), |
| 179 probable_http_response_(false), | 177 probable_http_response_(false), |
| 180 end_stream_when_done_(false) { | 178 end_stream_when_done_(false) { |
| 181 DCHECK(protocol_version_ == SPDY3 || protocol_version_ == HTTP2); | 179 DCHECK(protocol_version_ == SPDY3 || protocol_version_ == HTTP2); |
| 182 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it | 180 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it |
| 183 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. | 181 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. |
| 184 // Therefore this assertion is unnecessarily strict. | 182 // Therefore this assertion is unnecessarily strict. |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 case SPDY_COMPRESS_FAILURE: | 441 case SPDY_COMPRESS_FAILURE: |
| 444 return "COMPRESS_FAILURE"; | 442 return "COMPRESS_FAILURE"; |
| 445 case SPDY_INVALID_PADDING: | 443 case SPDY_INVALID_PADDING: |
| 446 return "SPDY_INVALID_PADDING"; | 444 return "SPDY_INVALID_PADDING"; |
| 447 case SPDY_INVALID_DATA_FRAME_FLAGS: | 445 case SPDY_INVALID_DATA_FRAME_FLAGS: |
| 448 return "SPDY_INVALID_DATA_FRAME_FLAGS"; | 446 return "SPDY_INVALID_DATA_FRAME_FLAGS"; |
| 449 case SPDY_INVALID_CONTROL_FRAME_FLAGS: | 447 case SPDY_INVALID_CONTROL_FRAME_FLAGS: |
| 450 return "SPDY_INVALID_CONTROL_FRAME_FLAGS"; | 448 return "SPDY_INVALID_CONTROL_FRAME_FLAGS"; |
| 451 case SPDY_UNEXPECTED_FRAME: | 449 case SPDY_UNEXPECTED_FRAME: |
| 452 return "UNEXPECTED_FRAME"; | 450 return "UNEXPECTED_FRAME"; |
| 453 case SPDY_INTERNAL_FRAMER_ERROR: | |
| 454 return "SPDY_INTERNAL_FRAMER_ERROR"; | |
| 455 } | 451 } |
| 456 return "UNKNOWN_ERROR"; | 452 return "UNKNOWN_ERROR"; |
| 457 } | 453 } |
| 458 | 454 |
| 459 const char* SpdyFramer::StatusCodeToString(int status_code) { | 455 const char* SpdyFramer::StatusCodeToString(int status_code) { |
| 460 switch (status_code) { | 456 switch (status_code) { |
| 461 case RST_STREAM_INVALID: | 457 case RST_STREAM_INVALID: |
| 462 return "INVALID"; | 458 return "INVALID"; |
| 463 case RST_STREAM_PROTOCOL_ERROR: | 459 case RST_STREAM_PROTOCOL_ERROR: |
| 464 return "PROTOCOL_ERROR"; | 460 return "PROTOCOL_ERROR"; |
| (...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1606 } | 1602 } |
| 1607 break; | 1603 break; |
| 1608 default: | 1604 default: |
| 1609 #ifndef NDEBUG | 1605 #ifndef NDEBUG |
| 1610 LOG(FATAL) << "Invalid control frame type: " << current_frame_type_; | 1606 LOG(FATAL) << "Invalid control frame type: " << current_frame_type_; |
| 1611 #else | 1607 #else |
| 1612 set_error(SPDY_INVALID_CONTROL_FRAME); | 1608 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1613 return original_len - len; | 1609 return original_len - len; |
| 1614 #endif | 1610 #endif |
| 1615 } | 1611 } |
| 1616 | |
| 1617 if (current_frame_type_ != CONTINUATION) { | |
| 1618 header_handler_ = visitor_->OnHeaderFrameStart(current_frame_stream_id_); | |
| 1619 if (header_handler_ == nullptr) { | |
| 1620 SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; | |
| 1621 set_error(SPDY_INTERNAL_FRAMER_ERROR); | |
| 1622 return original_len - len; | |
| 1623 } | |
| 1624 if (protocol_version() == SPDY3) { | |
| 1625 header_parser_.reset( | |
| 1626 new SpdyHeadersBlockParser(protocol_version(), header_handler_)); | |
| 1627 } else { | |
| 1628 GetHpackDecoder()->HandleControlFrameHeadersStart(header_handler_); | |
| 1629 } | |
| 1630 } | |
| 1631 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1612 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
| 1632 } | 1613 } |
| 1633 return original_len - len; | 1614 return original_len - len; |
| 1634 } | 1615 } |
| 1635 | 1616 |
| 1636 // Does not buffer the control payload. Instead, either passes directly to the | 1617 // Does not buffer the control payload. Instead, either passes directly to the |
| 1637 // visitor or decompresses and then passes directly to the visitor, via | 1618 // visitor or decompresses and then passes directly to the visitor, via |
| 1638 // IncrementallyDeliverControlFrameHeaderData() or | 1619 // IncrementallyDeliverControlFrameHeaderData() or |
| 1639 // IncrementallyDecompressControlFrameHeaderData() respectively. | 1620 // IncrementallyDecompressControlFrameHeaderData() respectively. |
| 1640 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, | 1621 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1677 remaining_data_length_ -= process_bytes; | 1658 remaining_data_length_ -= process_bytes; |
| 1678 | 1659 |
| 1679 // Handle the case that there is no futher data in this frame. | 1660 // Handle the case that there is no futher data in this frame. |
| 1680 if (remaining_data_length_ == remaining_padding_payload_length_ && | 1661 if (remaining_data_length_ == remaining_padding_payload_length_ && |
| 1681 processed_successfully) { | 1662 processed_successfully) { |
| 1682 if (expect_continuation_ == 0) { | 1663 if (expect_continuation_ == 0) { |
| 1683 if (is_hpack_header_block) { | 1664 if (is_hpack_header_block) { |
| 1684 size_t compressed_len = 0; | 1665 size_t compressed_len = 0; |
| 1685 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( | 1666 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( |
| 1686 &compressed_len)) { | 1667 &compressed_len)) { |
| 1687 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); | 1668 // TODO(jgraettinger): To be removed with migration to |
| 1688 if (state_ == SPDY_ERROR) { | 1669 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 |
| 1689 return data_len; | 1670 // block, delivered via reentrant call to |
| 1690 } | 1671 // ProcessControlFrameHeaderBlock(). |
| 1691 } else { | 1672 DeliverHpackBlockAsSpdy3Block(compressed_len); |
| 1692 set_error(SPDY_DECOMPRESS_FAILURE); | 1673 return process_bytes; |
| 1693 processed_successfully = false; | |
| 1694 } | 1674 } |
| 1675 set_error(SPDY_DECOMPRESS_FAILURE); |
| 1676 processed_successfully = false; |
| 1695 } else { | 1677 } else { |
| 1696 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); | 1678 // The complete header block has been delivered. We send a zero-length |
| 1697 if (state_ == SPDY_ERROR) { | 1679 // OnControlFrameHeaderData() to indicate this. |
| 1698 return data_len; | 1680 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0); |
| 1699 } | |
| 1700 } | 1681 } |
| 1701 } | 1682 } |
| 1702 if (processed_successfully) { | 1683 if (processed_successfully) { |
| 1703 CHANGE_STATE(SPDY_CONSUME_PADDING); | 1684 CHANGE_STATE(SPDY_CONSUME_PADDING); |
| 1704 } | 1685 } |
| 1705 } | 1686 } |
| 1706 | 1687 |
| 1707 // Handle error. | 1688 // Handle error. |
| 1708 if (!processed_successfully) { | 1689 if (!processed_successfully) { |
| 1709 return data_len; | 1690 return data_len; |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3100 } | 3081 } |
| 3101 | 3082 |
| 3102 // Inflate will generate a Z_BUF_ERROR if it runs out of input | 3083 // Inflate will generate a Z_BUF_ERROR if it runs out of input |
| 3103 // without producing any output. The input is consumed and | 3084 // without producing any output. The input is consumed and |
| 3104 // buffered internally by zlib so we can detect this condition by | 3085 // buffered internally by zlib so we can detect this condition by |
| 3105 // checking if avail_in is 0 after the call to inflate. | 3086 // checking if avail_in is 0 after the call to inflate. |
| 3106 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0)); | 3087 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0)); |
| 3107 if ((rv == Z_OK) || input_exhausted) { | 3088 if ((rv == Z_OK) || input_exhausted) { |
| 3108 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; | 3089 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; |
| 3109 if (decompressed_len > 0) { | 3090 if (decompressed_len > 0) { |
| 3110 processed_successfully = header_parser_->HandleControlFrameHeadersData( | 3091 processed_successfully = visitor_->OnControlFrameHeaderData( |
| 3111 stream_id, buffer, decompressed_len); | 3092 stream_id, buffer, decompressed_len); |
| 3112 if (header_parser_->get_error() == | |
| 3113 SpdyHeadersBlockParser::NEED_MORE_DATA) { | |
| 3114 processed_successfully = true; | |
| 3115 } | |
| 3116 } | 3093 } |
| 3117 if (!processed_successfully) { | 3094 if (!processed_successfully) { |
| 3118 // Assume that the problem was the header block was too large for the | 3095 // Assume that the problem was the header block was too large for the |
| 3119 // visitor. | 3096 // visitor. |
| 3120 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); | 3097 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); |
| 3121 } | 3098 } |
| 3122 } else { | 3099 } else { |
| 3123 DLOG(WARNING) << "inflate failure: " << rv << " " << len; | 3100 DLOG(WARNING) << "inflate failure: " << rv << " " << len; |
| 3124 set_error(SPDY_DECOMPRESS_FAILURE); | 3101 set_error(SPDY_DECOMPRESS_FAILURE); |
| 3125 processed_successfully = false; | 3102 processed_successfully = false; |
| 3126 } | 3103 } |
| 3127 } | 3104 } |
| 3128 return processed_successfully; | 3105 return processed_successfully; |
| 3129 } | 3106 } |
| 3130 | 3107 |
| 3131 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( | 3108 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( |
| 3132 SpdyStreamId stream_id, const char* data, size_t len) { | 3109 SpdyStreamId stream_id, const char* data, size_t len) { |
| 3133 bool read_successfully = true; | 3110 bool read_successfully = true; |
| 3134 while (read_successfully && len > 0) { | 3111 while (read_successfully && len > 0) { |
| 3135 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); | 3112 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); |
| 3136 read_successfully = header_parser_->HandleControlFrameHeadersData( | 3113 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, |
| 3137 stream_id, data, bytes_to_deliver); | 3114 bytes_to_deliver); |
| 3138 if (header_parser_->get_error() == SpdyHeadersBlockParser::NEED_MORE_DATA) { | |
| 3139 read_successfully = true; | |
| 3140 } | |
| 3141 data += bytes_to_deliver; | 3115 data += bytes_to_deliver; |
| 3142 len -= bytes_to_deliver; | 3116 len -= bytes_to_deliver; |
| 3143 if (!read_successfully) { | 3117 if (!read_successfully) { |
| 3144 // Assume that the problem was the header block was too large for the | 3118 // Assume that the problem was the header block was too large for the |
| 3145 // visitor. | 3119 // visitor. |
| 3146 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); | 3120 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); |
| 3147 } | 3121 } |
| 3148 } | 3122 } |
| 3149 return read_successfully; | 3123 return read_successfully; |
| 3150 } | 3124 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3226 #else | 3200 #else |
| 3227 WriteHeaderBlockToZ(&frame.header_block(), compressor); | 3201 WriteHeaderBlockToZ(&frame.header_block(), compressor); |
| 3228 #endif // defined(USE_SYSTEM_ZLIB) | 3202 #endif // defined(USE_SYSTEM_ZLIB) |
| 3229 | 3203 |
| 3230 int compressed_size = compressed_max_size - compressor->avail_out; | 3204 int compressed_size = compressed_max_size - compressor->avail_out; |
| 3231 builder->Seek(compressed_size); | 3205 builder->Seek(compressed_size); |
| 3232 builder->RewriteLength(*this); | 3206 builder->RewriteLength(*this); |
| 3233 } | 3207 } |
| 3234 | 3208 |
| 3235 } // namespace net | 3209 } // namespace net |
| OLD | NEW |