15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/spdy/hpack_decoder.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/spdy/hpack_constants.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/spdy/hpack_output_stream.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::StringPiece;
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using std::string;
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kCookieKey[] = "cookie";
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)HpackDecoder::HpackDecoder(const HpackHuffmanTable& table)
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : max_string_literal_size_(kDefaultMaxStringLiteralSize),
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      regular_header_seen_(false),
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      huffman_table_(table) {}
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)HpackDecoder::~HpackDecoder() {}
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id,
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                 const char* headers_data,
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                 size_t headers_data_length) {
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  decoded_block_.clear();
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t new_size = headers_block_buffer_.size() + headers_data_length;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (new_size > kMaxDecodeBufferSize) {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  headers_block_buffer_.insert(headers_block_buffer_.end(),
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               headers_data,
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               headers_data + headers_data_length);
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HpackDecoder::HandleControlFrameHeadersComplete(SpdyStreamId id) {
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HpackInputStream input_stream(max_string_literal_size_,
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                headers_block_buffer_);
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  regular_header_seen_ = false;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (input_stream.HasMoreData()) {
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!DecodeNextOpcode(&input_stream)) {
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      headers_block_buffer_.clear();
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  headers_block_buffer_.clear();
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Emit the Cookie header, if any crumbles were encountered.
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!cookie_value_.empty()) {
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    decoded_block_[kCookieKey] = cookie_value_;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    cookie_value_.clear();
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool HpackDecoder::HandleHeaderRepresentation(StringPiece name,
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              StringPiece value) {
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef std::pair<std::map<string, string>::iterator, bool> InsertResult;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Fail if pseudo-header follows regular header.
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (name.size() > 0) {
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (name[0] == kPseudoHeaderPrefix) {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (regular_header_seen_) return false;
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      regular_header_seen_ = true;
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (name == kCookieKey) {
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (cookie_value_.empty()) {
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      cookie_value_.assign(value.data(), value.size());
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else {
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      cookie_value_ += "; ";
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      cookie_value_.insert(cookie_value_.end(), value.begin(), value.end());
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    InsertResult result = decoded_block_.insert(
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::make_pair(name.as_string(), value.as_string()));
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!result.second) {
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      result.first->second.push_back('\0');
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      result.first->second.insert(result.first->second.end(),
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  value.begin(),
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  value.end());
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) {
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Implements 7.1: Indexed Header Field Representation.
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) {
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return DecodeNextIndexedHeader(input_stream);
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Implements 7.2.1: Literal Header Field with Incremental Indexing.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) {
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return DecodeNextLiteralHeader(input_stream, true);
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Implements 7.2.2: Literal Header Field without Indexing.
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (input_stream->MatchPrefixAndConsume(kLiteralNoIndexOpcode)) {
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return DecodeNextLiteralHeader(input_stream, false);
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Implements 7.2.3: Literal Header Field never Indexed.
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(jgraettinger): Preserve the never-indexed bit.
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (input_stream->MatchPrefixAndConsume(kLiteralNeverIndexOpcode)) {
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return DecodeNextLiteralHeader(input_stream, false);
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Implements 7.3: Header Table Size Update.
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (input_stream->MatchPrefixAndConsume(kHeaderTableSizeUpdateOpcode)) {
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return DecodeNextHeaderTableSizeUpdate(input_stream);
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Unrecognized opcode.
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return false;
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool HpackDecoder::DecodeNextHeaderTableSizeUpdate(
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    HpackInputStream* input_stream) {
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 size = 0;
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!input_stream->DecodeNextUint32(&size)) {
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (size > header_table_.settings_size_bound()) {
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  header_table_.SetMaxSize(size);
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) {
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  uint32 index = 0;
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!input_stream->DecodeNextUint32(&index))
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const HpackEntry* entry = header_table_.GetByIndex(index);
1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (entry == NULL)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return HandleHeaderRepresentation(entry->name(), entry->value());
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream,
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                           bool should_index) {
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StringPiece name;
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!DecodeNextName(input_stream, &name))
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StringPiece value;
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!DecodeNextStringLiteral(input_stream, false, &value))
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!HandleHeaderRepresentation(name, value)) return false;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!should_index)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ignore_result(header_table_.TryAddEntry(name, value));
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool HpackDecoder::DecodeNextName(
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HpackInputStream* input_stream, StringPiece* next_name) {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 index_or_zero = 0;
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!input_stream->DecodeNextUint32(&index_or_zero))
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (index_or_zero == 0)
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return DecodeNextStringLiteral(input_stream, true, next_name);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const HpackEntry* entry = header_table_.GetByIndex(index_or_zero);
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (entry == NULL) {
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else if (entry->IsStatic()) {
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *next_name = entry->name();
1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // |entry| could be evicted as part of this insertion. Preemptively copy.
1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    key_buffer_.assign(entry->name());
1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *next_name = key_buffer_;
1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HpackDecoder::DecodeNextStringLiteral(HpackInputStream* input_stream,
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                           bool is_key,
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                           StringPiece* output) {
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (input_stream->MatchPrefixAndConsume(kStringLiteralHuffmanEncoded)) {
1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    string* buffer = is_key ? &key_buffer_ : &value_buffer_;
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool result = input_stream->DecodeNextHuffmanString(huffman_table_, buffer);
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *output = StringPiece(*buffer);
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return result;
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else if (input_stream->MatchPrefixAndConsume(
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kStringLiteralIdentityEncoded)) {
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return input_stream->DecodeNextIdentityString(output);
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
207