Chromium Code Reviews| Index: net/spdy/spdy_framer.cc |
| =================================================================== |
| --- net/spdy/spdy_framer.cc (revision 80449) |
| +++ net/spdy/spdy_framer.cc (working copy) |
| @@ -20,6 +20,10 @@ |
| #include "third_party/zlib/zlib.h" |
| #endif |
| +namespace net { |
| + |
|
Mike Belshe
2011/04/06 18:32:53
delete lines 22-25.
|
| +} // namespace net |
| + |
| namespace { |
| // The following compression setting are based on Brian Olson's analysis. See |
| @@ -29,7 +33,9 @@ |
| const int kCompressorWindowSizeInBits = 11; |
| const int kCompressorMemLevel = 1; |
| -uLong dictionary_id = 0; |
| +// TODO(jtl): Need to decide how to handle this. The array dimension must be as |
| +// large as the maximum SCTP stream ID we will ever use. |
| +uLong dictionary_ids[100] = {0}; |
| } // namespace |
| @@ -93,12 +99,7 @@ |
| } |
| SpdyFramer::~SpdyFramer() { |
| - if (header_compressor_.get()) { |
| - deflateEnd(header_compressor_.get()); |
| - } |
| - if (header_decompressor_.get()) { |
| - inflateEnd(header_decompressor_.get()); |
| - } |
| + CleanupHeaderCompressorsAndDecompressors(); |
| CleanupStreamCompressorsAndDecompressors(); |
| delete [] current_frame_buffer_; |
| } |
| @@ -800,54 +801,87 @@ |
| return original_len - len; |
| } |
| -z_stream* SpdyFramer::GetHeaderCompressor() { |
| - if (header_compressor_.get()) |
| - return header_compressor_.get(); // Already initialized. |
| +uint16 SpdyFramer::GetDictionaryIndex(const SpdyControlFrame& control_frame) { |
| + uint32 stream_id = 0; |
| + // TODO(jtl): Need to reconcile this with IsCompressible() which only returns |
| + // true for SYN_STREAM and SYN_REPLY control frames. |
| + switch (control_frame.type()) { |
| + case SYN_STREAM: |
| + stream_id = reinterpret_cast<const SpdySynStreamControlFrame&> |
| + (control_frame).stream_id(); |
| + break; |
| + case SYN_REPLY: |
| + stream_id = reinterpret_cast<const SpdySynReplyControlFrame&> |
| + (control_frame).stream_id(); |
| + break; |
| + case RST_STREAM: |
| + stream_id = reinterpret_cast<const SpdyRstStreamControlFrame&> |
| + (control_frame).stream_id(); |
| + break; |
| + case HEADERS: |
| + stream_id = reinterpret_cast<const SpdyHeadersControlFrame&> |
| + (control_frame).stream_id(); |
| + break; |
| + case WINDOW_UPDATE: |
| + stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame&> |
| + (control_frame).stream_id(); |
| + break; |
| + default: |
| + break; |
| + } |
| - header_compressor_.reset(new z_stream); |
| - memset(header_compressor_.get(), 0, sizeof(z_stream)); |
| + return stream_id ? MapSpdyToSctp(stream_id) : 0; |
| +} |
| - int success = deflateInit2(header_compressor_.get(), |
| +z_stream* SpdyFramer::GetHeaderCompressor(int index) { |
| + CompressorMap::iterator it = header_compressors_.find(index); |
| + if (it != header_compressors_.end()) |
| + return it->second; // Already initialized. |
| + |
| + scoped_ptr<z_stream> compressor(new z_stream); |
| + memset(compressor.get(), 0, sizeof(z_stream)); |
| + |
| + int success = deflateInit2(compressor.get(), |
| kCompressorLevel, |
| Z_DEFLATED, |
| kCompressorWindowSizeInBits, |
| kCompressorMemLevel, |
| Z_DEFAULT_STRATEGY); |
| if (success == Z_OK) |
| - success = deflateSetDictionary(header_compressor_.get(), |
| + success = deflateSetDictionary(compressor.get(), |
| reinterpret_cast<const Bytef*>(kDictionary), |
| kDictionarySize); |
| if (success != Z_OK) { |
| LOG(WARNING) << "deflateSetDictionary failure: " << success; |
| - header_compressor_.reset(NULL); |
| + compressor.reset(NULL); |
| return NULL; |
| } |
| - return header_compressor_.get(); |
| + return header_compressors_[index] = compressor.release(); |
| } |
| -z_stream* SpdyFramer::GetHeaderDecompressor() { |
| - if (header_decompressor_.get()) |
| - return header_decompressor_.get(); // Already initialized. |
| +z_stream* SpdyFramer::GetHeaderDecompressor(int index) { |
| + CompressorMap::iterator it = header_decompressors_.find(index); |
| + if (it != header_decompressors_.end()) |
| + return it->second; // Already initialized. |
| - header_decompressor_.reset(new z_stream); |
| - memset(header_decompressor_.get(), 0, sizeof(z_stream)); |
| + scoped_ptr<z_stream> decompressor(new z_stream); |
| + memset(decompressor.get(), 0, sizeof(z_stream)); |
| // Compute the id of our dictionary so that we know we're using the |
| // right one when asked for it. |
| - if (dictionary_id == 0) { |
| - dictionary_id = adler32(0L, Z_NULL, 0); |
| - dictionary_id = adler32(dictionary_id, |
| + if (dictionary_ids[index] == 0) { |
| + dictionary_ids[index] = adler32(0L, Z_NULL, 0); |
| + dictionary_ids[index] = adler32(dictionary_ids[index], |
| reinterpret_cast<const Bytef*>(kDictionary), |
| kDictionarySize); |
| } |
| - int success = inflateInit(header_decompressor_.get()); |
| + int success = inflateInit(decompressor.get()); |
| if (success != Z_OK) { |
| LOG(WARNING) << "inflateInit failure: " << success; |
| - header_decompressor_.reset(NULL); |
| return NULL; |
| } |
| - return header_decompressor_.get(); |
| + return header_decompressors_[index] = decompressor.release(); |
| } |
| z_stream* SpdyFramer::GetStreamCompressor(SpdyStreamId stream_id) { |
| @@ -889,7 +923,11 @@ |
| SpdyControlFrame* SpdyFramer::CompressControlFrame( |
| const SpdyControlFrame& frame) { |
| - z_stream* compressor = GetHeaderCompressor(); |
| + uint16 dictionary_index = 0; |
| + if (using_sctp() && !using_sctp_control_stream()) |
| + dictionary_index = GetDictionaryIndex(frame); |
| + z_stream* compressor = GetHeaderCompressor(dictionary_index); |
| + |
| if (!compressor) |
| return NULL; |
| return reinterpret_cast<SpdyControlFrame*>( |
| @@ -906,7 +944,11 @@ |
| SpdyControlFrame* SpdyFramer::DecompressControlFrame( |
| const SpdyControlFrame& frame) { |
| - z_stream* decompressor = GetHeaderDecompressor(); |
| + uint16 dictionary_index = 0; |
| + if (using_sctp() && !using_sctp_control_stream()) |
| + dictionary_index = GetDictionaryIndex(frame); |
| + z_stream* decompressor = GetHeaderDecompressor(dictionary_index); |
| + |
| if (!decompressor) |
| return NULL; |
| return reinterpret_cast<SpdyControlFrame*>( |
| @@ -1026,7 +1068,13 @@ |
| int rv = inflate(decompressor, Z_SYNC_FLUSH); |
| if (rv == Z_NEED_DICT) { |
| // Need to try again with the right dictionary. |
| - if (decompressor->adler == dictionary_id) { |
| + uint16 dictionary_index = 0; |
| + if (using_sctp() && !using_sctp_control_stream() && |
| + frame.is_control_frame()) { |
| + dictionary_index = GetDictionaryIndex( |
| + reinterpret_cast<const SpdyControlFrame&>(frame)); |
| + } |
| + if (decompressor->adler == dictionary_ids[dictionary_index]) { |
| rv = inflateSetDictionary(decompressor, (const Bytef*)kDictionary, |
| kDictionarySize); |
| if (rv == Z_OK) |
| @@ -1103,6 +1151,28 @@ |
| stream_decompressors_.clear(); |
| } |
| +void SpdyFramer::CleanupHeaderCompressorsAndDecompressors() { |
| + CompressorMap::iterator it; |
| + |
| + it = header_compressors_.begin(); |
| + while (it != header_compressors_.end()) { |
| + z_stream* compressor = it->second; |
| + deflateEnd(compressor); |
| + delete compressor; |
| + ++it; |
| + } |
| + header_compressors_.clear(); |
| + |
| + it = header_decompressors_.begin(); |
| + while (it != header_decompressors_.end()) { |
| + z_stream* decompressor = it->second; |
| + inflateEnd(decompressor); |
| + delete decompressor; |
| + ++it; |
| + } |
| + header_decompressors_.clear(); |
| +} |
| + |
| size_t SpdyFramer::BytesSafeToRead() const { |
| switch (state_) { |
| case SPDY_ERROR: |