diff options
Diffstat (limited to 'net/spdy/spdy_framer.cc')
-rw-r--r-- | net/spdy/spdy_framer.cc | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index e001d86..2d9ea98 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc @@ -237,7 +237,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { // This is just a sanity check for help debugging early frame errors. if (remaining_payload_ > 1000000u) { - LOG(ERROR) << + LOG(WARNING) << "Unexpectedly large frame. Spdy session is likely corrupt."; } @@ -293,10 +293,14 @@ void SpdyFramer::ProcessControlFrameHeader() { // NOOP. Swallow it. CHANGE_STATE(SPDY_AUTO_RESET); return; + case GOAWAY: + if (current_control_frame.length() != + SpdyGoAwayControlFrame::size() - SpdyFrame::size()) + set_error(SPDY_INVALID_CONTROL_FRAME); + break; default: LOG(WARNING) << "Valid spdy control frame with unknown type: " - << current_control_frame.type() - << ". This should never happen"; + << current_control_frame.type(); DCHECK(false); set_error(SPDY_INVALID_CONTROL_FRAME); break; @@ -338,8 +342,11 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { // If this is a FIN, tell the caller. if (control_frame.type() == SYN_REPLY && - control_frame.flags() & CONTROL_FLAG_FIN) - visitor_->OnStreamFrameData(control_frame.stream_id(), NULL, 0); + control_frame.flags() & CONTROL_FLAG_FIN) { + visitor_->OnStreamFrameData(reinterpret_cast<SpdySynReplyControlFrame*>( + &control_frame)->stream_id(), + NULL, 0); + } CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); } while (false); @@ -518,6 +525,18 @@ SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(SpdyStreamId stream_id, return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); } +/* static */ +SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( + SpdyStreamId last_accepted_stream_id) { + SpdyFrameBuilder frame; + frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion); + frame.WriteUInt16(GOAWAY); + size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::size(); + frame.WriteUInt32(go_away_size); + frame.WriteUInt32(last_accepted_stream_id); + return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); +} + SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(SpdyStreamId stream_id, SpdyControlFlags flags, bool compressed, SpdyHeaderBlock* headers) { @@ -582,7 +601,13 @@ SpdyControlFrame* SpdyFramer::CreateNopFrame() { return reinterpret_cast<SpdyControlFrame*>(frame.take()); } -static const int kCompressorLevel = Z_DEFAULT_COMPRESSION; +// The following compression setting are based on Brian Olson's analysis. See +// https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792 +// for more details. +static const int kCompressorLevel = 9; +static const int kCompressorWindowSizeInBits = 11; +static const int kCompressorMemLevel = 1; + // This is just a hacked dictionary to use for shrinking HTTP-like headers. // TODO(mbelshe): Use a scientific methodology for computing the dictionary. const char SpdyFramer::kDictionary[] = @@ -610,7 +635,12 @@ bool SpdyFramer::InitializeCompressor() { compressor_.reset(new z_stream); memset(compressor_.get(), 0, sizeof(z_stream)); - int success = deflateInit(compressor_.get(), kCompressorLevel); + int success = deflateInit2(compressor_.get(), + kCompressorLevel, + Z_DEFLATED, + kCompressorWindowSizeInBits, + kCompressorMemLevel, + Z_DEFAULT_STRATEGY); if (success == Z_OK) success = deflateSetDictionary(compressor_.get(), reinterpret_cast<const Bytef*>(kDictionary), |