Index: net/spdy/spdy_framer.cc |
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc |
index f1ceaf6ec210e019eb7e616a7486fe359bf9a758..1b4972da738a8cc6dff78ad739b6e255daef928f 100644 |
--- a/net/spdy/spdy_framer.cc |
+++ b/net/spdy/spdy_framer.cc |
@@ -21,6 +21,7 @@ |
#include "net/spdy/spdy_bug_tracker.h" |
#include "net/spdy/spdy_frame_builder.h" |
#include "net/spdy/spdy_frame_reader.h" |
+#include "net/spdy/spdy_headers_block_parser.h" |
#include "third_party/zlib/zlib.h" |
using base::StringPiece; |
@@ -170,6 +171,7 @@ SpdyFramer::SpdyFramer(SpdyMajorVersion version) |
expect_continuation_(0), |
visitor_(NULL), |
debug_visitor_(NULL), |
+ header_handler_(nullptr), |
display_protocol_("SPDY"), |
protocol_version_(version), |
enable_compression_(true), |
@@ -448,6 +450,8 @@ const char* SpdyFramer::ErrorCodeToString(int error_code) { |
return "SPDY_INVALID_CONTROL_FRAME_FLAGS"; |
case SPDY_UNEXPECTED_FRAME: |
return "UNEXPECTED_FRAME"; |
+ case SPDY_INTERNAL_FRAMER_ERROR: |
+ return "SPDY_INTERNAL_FRAMER_ERROR"; |
} |
return "UNKNOWN_ERROR"; |
} |
@@ -1609,6 +1613,21 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, |
return original_len - len; |
#endif |
} |
+ |
+ if (current_frame_type_ != CONTINUATION) { |
+ header_handler_ = visitor_->OnHeaderFrameStart(current_frame_stream_id_); |
+ if (header_handler_ == nullptr) { |
+ SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; |
+ set_error(SPDY_INTERNAL_FRAMER_ERROR); |
+ return original_len - len; |
+ } |
+ if (protocol_version() == SPDY3) { |
+ header_parser_.reset( |
+ new SpdyHeadersBlockParser(protocol_version(), header_handler_)); |
+ } else { |
+ GetHpackDecoder()->HandleControlFrameHeadersStart(header_handler_); |
+ } |
+ } |
CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
} |
return original_len - len; |
@@ -1665,19 +1684,19 @@ size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, |
size_t compressed_len = 0; |
if (GetHpackDecoder()->HandleControlFrameHeadersComplete( |
&compressed_len)) { |
- // TODO(jgraettinger): To be removed with migration to |
- // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 |
- // block, delivered via reentrant call to |
- // ProcessControlFrameHeaderBlock(). |
- DeliverHpackBlockAsSpdy3Block(compressed_len); |
- return process_bytes; |
+ visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); |
+ if (state_ == SPDY_ERROR) { |
+ return data_len; |
+ } |
+ } else { |
+ set_error(SPDY_DECOMPRESS_FAILURE); |
+ processed_successfully = false; |
} |
- set_error(SPDY_DECOMPRESS_FAILURE); |
- processed_successfully = false; |
} else { |
- // The complete header block has been delivered. We send a zero-length |
- // OnControlFrameHeaderData() to indicate this. |
- visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0); |
+ visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); |
+ if (state_ == SPDY_ERROR) { |
+ return data_len; |
+ } |
} |
} |
if (processed_successfully) { |
@@ -3088,8 +3107,12 @@ bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( |
if ((rv == Z_OK) || input_exhausted) { |
size_t decompressed_len = arraysize(buffer) - decomp->avail_out; |
if (decompressed_len > 0) { |
- processed_successfully = visitor_->OnControlFrameHeaderData( |
+ processed_successfully = header_parser_->HandleControlFrameHeadersData( |
stream_id, buffer, decompressed_len); |
+ if (header_parser_->get_error() == |
+ SpdyHeadersBlockParser::NEED_MORE_DATA) { |
+ processed_successfully = true; |
+ } |
} |
if (!processed_successfully) { |
// Assume that the problem was the header block was too large for the |
@@ -3110,8 +3133,11 @@ bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( |
bool read_successfully = true; |
while (read_successfully && len > 0) { |
size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); |
- read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, |
- bytes_to_deliver); |
+ read_successfully = header_parser_->HandleControlFrameHeadersData( |
+ stream_id, data, bytes_to_deliver); |
+ if (header_parser_->get_error() == SpdyHeadersBlockParser::NEED_MORE_DATA) { |
+ read_successfully = true; |
+ } |
data += bytes_to_deliver; |
len -= bytes_to_deliver; |
if (!read_successfully) { |