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 |