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