14 #include <boost/asio/detail/socket_ops.hpp>
15 #include <pion/spdy/decompressor.hpp>
24 const char decompressor::SPDY_ZLIB_DICTIONARY[] =
25 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
26 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
27 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
28 "-agent10010120020120220320420520630030130230330430530630740040140240340440"
29 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
30 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
31 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
32 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
33 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
34 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
35 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
36 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
43 : m_request_zstream(NULL), m_response_zstream(NULL)
45 m_request_zstream = (z_streamp)malloc(
sizeof(z_stream));
46 BOOST_ASSERT(m_request_zstream);
48 m_request_zstream->zalloc = Z_NULL;
49 m_request_zstream->zfree = Z_NULL;
50 m_request_zstream->opaque = Z_NULL;
51 m_request_zstream->next_in = Z_NULL;
52 m_request_zstream->next_out = Z_NULL;
53 m_request_zstream->avail_in = 0;
54 m_request_zstream->avail_out = 0;
56 m_response_zstream = (z_streamp)malloc(
sizeof(z_stream));
57 BOOST_ASSERT(m_response_zstream);
59 m_response_zstream->zalloc = Z_NULL;
60 m_response_zstream->zfree = Z_NULL;
61 m_response_zstream->opaque = Z_NULL;
62 m_response_zstream->next_in = Z_NULL;
63 m_response_zstream->next_out = Z_NULL;
64 m_response_zstream->avail_in = 0;
65 m_response_zstream->avail_out = 0;
67 int retcode = inflateInit2(m_request_zstream, MAX_WBITS);
68 if (retcode == Z_OK) {
69 retcode = inflateInit2(m_response_zstream, MAX_WBITS);
70 if (retcode == Z_OK) {
72 m_dictionary_id = adler32(0L, Z_NULL, 0);
74 m_dictionary_id = adler32(m_dictionary_id,
75 (
const Bytef *)SPDY_ZLIB_DICTIONARY,
76 sizeof(SPDY_ZLIB_DICTIONARY));
83 inflateEnd(m_request_zstream);
84 inflateEnd(m_response_zstream);
85 free(m_request_zstream);
86 free(m_response_zstream);
90 boost::uint32_t stream_id,
92 boost::uint32_t header_block_length)
95 z_streamp decomp = NULL;
96 if (stream_id % 2 == 0) {
99 decomp = m_response_zstream;
100 }
else if (frame.type == SPDY_HEADERS) {
104 decomp = m_response_zstream;
105 }
else if (frame.type == SPDY_SYN_STREAM) {
106 decomp = m_request_zstream;
107 }
else if (frame.type == SPDY_SYN_REPLY) {
108 decomp = m_response_zstream;
113 BOOST_ASSERT(decomp);
116 boost::uint32_t uncomp_length = 0;
120 header_block_length, uncomp_length))
128 return reinterpret_cast<char*
>(m_uncompressed_header);
133 boost::uint32_t length,
134 boost::uint32_t& uncomp_length) {
136 const boost::uint8_t *hptr = (boost::uint8_t *)compressed_data_ptr;
138 decomp->next_in = (Bytef *)hptr;
139 decomp->avail_in = length;
140 decomp->next_out = m_uncompressed_header;
143 retcode = inflate(decomp, Z_SYNC_FLUSH);
145 if (retcode == Z_NEED_DICT) {
146 if (decomp->adler != m_dictionary_id) {
149 retcode = inflateSetDictionary(decomp,
150 (
const Bytef *)SPDY_ZLIB_DICTIONARY,
151 sizeof(SPDY_ZLIB_DICTIONARY));
152 if (retcode == Z_OK) {
153 retcode = inflate(decomp, Z_SYNC_FLUSH);
159 if (retcode != Z_OK) {
168 if (decomp->avail_in != 0) {
char * decompress(const char *compressed_data_ptr, boost::uint32_t stream_id, const spdy_control_frame_info &frame, boost::uint32_t header_block_length)
maximum size of an uncompressed spdy header
~decompressor()
destructor
bool spdy_decompress_header(const char *compressed_data_ptr, z_streamp decomp, boost::uint32_t length, boost::uint32_t &uncomp_length)
This structure will be tied to each SPDY frame.
decompressor()
constructs a new decompressor object (default constructor)