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 10using std::string; 11 12namespace net { 13 14QuicSpdyCompressor::QuicSpdyCompressor() 15 : spdy_framer_(SPDY3), 16 header_sequence_id_(1) { 17 spdy_framer_.set_enable_compression(true); 18} 19 20QuicSpdyCompressor::~QuicSpdyCompressor() { 21} 22 23string QuicSpdyCompressor::CompressHeadersWithPriority( 24 QuicPriority priority, 25 const SpdyHeaderBlock& headers) { 26 return CompressHeadersInternal(priority, headers, true); 27} 28 29string QuicSpdyCompressor::CompressHeaders( 30 const SpdyHeaderBlock& headers) { 31 // CompressHeadersInternal ignores priority when write_priority is false. 32 return CompressHeadersInternal(0 /* ignored */, headers, false); 33} 34 35string 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