1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_spdy_compressor.h" 6 7 #include "base/basictypes.h" 8 #include "base/memory/scoped_ptr.h" 9 10 using std::string; 11 12 namespace net { 13 14 QuicSpdyCompressor::QuicSpdyCompressor() 15 : spdy_framer_(SPDY3), 16 header_sequence_id_(1) { 17 spdy_framer_.set_enable_compression(true); 18 } 19 20 QuicSpdyCompressor::~QuicSpdyCompressor() { 21 } 22 23 string QuicSpdyCompressor::CompressHeadersWithPriority( 24 QuicPriority priority, 25 const SpdyHeaderBlock& headers) { 26 return CompressHeadersInternal(priority, headers, true); 27 } 28 29 string QuicSpdyCompressor::CompressHeaders( 30 const SpdyHeaderBlock& headers) { 31 // CompressHeadersInternal ignores priority when write_priority is false. 32 return CompressHeadersInternal(0 /* ignored */, headers, false); 33 } 34 35 string QuicSpdyCompressor::CompressHeadersInternal( 36 QuicPriority priority, 37 const SpdyHeaderBlock& headers, 38 bool write_priority) { 39 // TODO(rch): Modify the SpdyFramer to expose a 40 // CreateCompressedHeaderBlock method, or some such. 41 SpdyStreamId stream_id = 3; // unused. 42 scoped_ptr<SpdyFrame> frame(spdy_framer_.CreateHeaders( 43 stream_id, CONTROL_FLAG_NONE, &headers)); 44 45 // The size of the spdy HEADER frame's fixed prefix which 46 // needs to be stripped off from the resulting frame. 47 const size_t header_frame_prefix_len = 12; 48 string serialized = string(frame->data() + header_frame_prefix_len, 49 frame->size() - header_frame_prefix_len); 50 uint32 serialized_len = serialized.length(); 51 char priority_str[sizeof(priority)]; 52 memcpy(&priority_str, &priority, sizeof(priority)); 53 char id_str[sizeof(header_sequence_id_)]; 54 memcpy(&id_str, &header_sequence_id_, sizeof(header_sequence_id_)); 55 char len_str[sizeof(serialized_len)]; 56 memcpy(&len_str, &serialized_len, sizeof(serialized_len)); 57 string compressed; 58 int priority_len = write_priority ? arraysize(priority_str) : 0; 59 compressed.reserve( 60 priority_len + arraysize(id_str) + arraysize(len_str) + serialized_len); 61 if (write_priority) { 62 compressed.append(priority_str, arraysize(priority_str)); 63 } 64 compressed.append(id_str, arraysize(id_str)); 65 compressed.append(len_str, arraysize(len_str)); 66 compressed.append(serialized); 67 ++header_sequence_id_; 68 return compressed; 69 } 70 71 } // namespace net 72