spdy_framer.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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// TODO(rtenhove) clean up frame buffer size calculations so that we aren't
6// constantly adding and subtracting header sizes; this is ugly and error-
7// prone.
8
9#include "net/spdy/spdy_framer.h"
10
11#include "base/lazy_instance.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/metrics/stats_counters.h"
14#include "base/third_party/valgrind/memcheck.h"
15#include "net/spdy/spdy_frame_builder.h"
16#include "net/spdy/spdy_frame_reader.h"
17#include "net/spdy/spdy_bitmasks.h"
18
19#if defined(USE_SYSTEM_ZLIB)
20#include <zlib.h>
21#else
22#include "third_party/zlib/zlib.h"
23#endif
24
25using std::vector;
26
27namespace net {
28
29namespace {
30
31// Compute the id of our dictionary so that we know we're using the
32// right one when asked for it.
33uLong CalculateDictionaryId(const char* dictionary,
34                            const size_t dictionary_size) {
35  uLong initial_value = adler32(0L, Z_NULL, 0);
36  return adler32(initial_value,
37                 reinterpret_cast<const Bytef*>(dictionary),
38                 dictionary_size);
39}
40
41struct DictionaryIds {
42  DictionaryIds()
43    : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
44      v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
45  {}
46  const uLong v2_dictionary_id;
47  const uLong v3_dictionary_id;
48};
49
50// Adler ID for the SPDY header compressor dictionaries. Note that they are
51// initialized lazily to avoid static initializers.
52base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
53
54}  // namespace
55
56const int SpdyFramer::kMinSpdyVersion = 2;
57const int SpdyFramer::kMaxSpdyVersion = 3;
58const SpdyStreamId SpdyFramer::kInvalidStream = -1;
59const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
60const size_t SpdyFramer::kControlFrameBufferSize =
61    sizeof(SpdySynStreamControlFrameBlock);
62const size_t SpdyFramer::kMaxControlFrameSize = 16 * 1024;
63
64#ifdef DEBUG_SPDY_STATE_CHANGES
65#define CHANGE_STATE(newstate)                                  \
66  do {                                                          \
67    LOG(INFO) << "Changing state from: "                        \
68              << StateToString(state_)                          \
69              << " to " << StateToString(newstate) << "\n";     \
70    DCHECK(state_ != SPDY_ERROR);                               \
71    DCHECK_EQ(previous_state_, state_);                         \
72    previous_state_ = state_;                                   \
73    state_ = newstate;                                          \
74  } while (false)
75#else
76#define CHANGE_STATE(newstate)                                  \
77  do {                                                          \
78    DCHECK(state_ != SPDY_ERROR);                               \
79    DCHECK_EQ(previous_state_, state_);                         \
80    previous_state_ = state_;                                   \
81    state_ = newstate;                                          \
82  } while (false)
83#endif
84
85SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version,
86                                                      uint32 wire) {
87  if (version < 3) {
88    ConvertFlagsAndIdForSpdy2(&wire);
89  }
90  return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
91}
92
93SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
94    : flags_(flags), id_(id & 0x00ffffff) {
95  DCHECK_GT(1u << 24, id) << "SPDY setting ID too large.";
96}
97
98uint32 SettingsFlagsAndId::GetWireFormat(int version) const {
99  uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
100  if (version < 3) {
101    ConvertFlagsAndIdForSpdy2(&wire);
102  }
103  return wire;
104}
105
106// SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
107// This method is used to preserve buggy behavior and works on both
108// little-endian and big-endian hosts.
109// This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
110// as well as vice versa).
111void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
112    uint8* wire_array = reinterpret_cast<uint8*>(val);
113    std::swap(wire_array[0], wire_array[3]);
114    std::swap(wire_array[1], wire_array[2]);
115}
116
117SpdyCredential::SpdyCredential() : slot(0) {}
118SpdyCredential::~SpdyCredential() {}
119
120SpdyFramer::SpdyFramer(int version)
121    : state_(SPDY_RESET),
122      previous_state_(SPDY_RESET),
123      error_code_(SPDY_NO_ERROR),
124      remaining_data_(0),
125      remaining_control_payload_(0),
126      remaining_control_header_(0),
127      current_frame_buffer_(new char[kControlFrameBufferSize]),
128      current_frame_len_(0),
129      enable_compression_(true),
130      visitor_(NULL),
131      display_protocol_("SPDY"),
132      spdy_version_(version),
133      syn_frame_processed_(false),
134      probable_http_response_(false) {
135  DCHECK_GE(kMaxSpdyVersion, version);
136  DCHECK_LE(kMinSpdyVersion, version);
137}
138
139SpdyFramer::~SpdyFramer() {
140  if (header_compressor_.get()) {
141    deflateEnd(header_compressor_.get());
142  }
143  if (header_decompressor_.get()) {
144    inflateEnd(header_decompressor_.get());
145  }
146}
147
148void SpdyFramer::Reset() {
149  state_ = SPDY_RESET;
150  previous_state_ = SPDY_RESET;
151  error_code_ = SPDY_NO_ERROR;
152  remaining_data_ = 0;
153  remaining_control_payload_ = 0;
154  remaining_control_header_ = 0;
155  current_frame_len_ = 0;
156  settings_scratch_.Reset();
157}
158
159const char* SpdyFramer::StateToString(int state) {
160  switch (state) {
161    case SPDY_ERROR:
162      return "ERROR";
163    case SPDY_DONE:
164      return "DONE";
165    case SPDY_AUTO_RESET:
166      return "AUTO_RESET";
167    case SPDY_RESET:
168      return "RESET";
169    case SPDY_READING_COMMON_HEADER:
170      return "READING_COMMON_HEADER";
171    case SPDY_CONTROL_FRAME_PAYLOAD:
172      return "CONTROL_FRAME_PAYLOAD";
173    case SPDY_IGNORE_REMAINING_PAYLOAD:
174      return "IGNORE_REMAINING_PAYLOAD";
175    case SPDY_FORWARD_STREAM_FRAME:
176      return "FORWARD_STREAM_FRAME";
177    case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
178      return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
179    case SPDY_CONTROL_FRAME_HEADER_BLOCK:
180      return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
181    case SPDY_CREDENTIAL_FRAME_PAYLOAD:
182      return "SPDY_CREDENTIAL_FRAME_PAYLOAD";
183    case SPDY_SETTINGS_FRAME_PAYLOAD:
184      return "SPDY_SETTINGS_FRAME_PAYLOAD";
185  }
186  return "UNKNOWN_STATE";
187}
188
189void SpdyFramer::set_error(SpdyError error) {
190  DCHECK(visitor_);
191  error_code_ = error;
192  CHANGE_STATE(SPDY_ERROR);
193  visitor_->OnError(this);
194}
195
196const char* SpdyFramer::ErrorCodeToString(int error_code) {
197  switch (error_code) {
198    case SPDY_NO_ERROR:
199      return "NO_ERROR";
200    case SPDY_INVALID_CONTROL_FRAME:
201      return "INVALID_CONTROL_FRAME";
202    case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
203      return "CONTROL_PAYLOAD_TOO_LARGE";
204    case SPDY_ZLIB_INIT_FAILURE:
205      return "ZLIB_INIT_FAILURE";
206    case SPDY_UNSUPPORTED_VERSION:
207      return "UNSUPPORTED_VERSION";
208    case SPDY_DECOMPRESS_FAILURE:
209      return "DECOMPRESS_FAILURE";
210    case SPDY_COMPRESS_FAILURE:
211      return "COMPRESS_FAILURE";
212    case SPDY_INVALID_DATA_FRAME_FLAGS:
213      return "SPDY_INVALID_DATA_FRAME_FLAGS";
214  }
215  return "UNKNOWN_ERROR";
216}
217
218const char* SpdyFramer::StatusCodeToString(int status_code) {
219  switch (status_code) {
220    case INVALID:
221      return "INVALID";
222    case PROTOCOL_ERROR:
223      return "PROTOCOL_ERROR";
224    case INVALID_STREAM:
225      return "INVALID_STREAM";
226    case REFUSED_STREAM:
227      return "REFUSED_STREAM";
228    case UNSUPPORTED_VERSION:
229      return "UNSUPPORTED_VERSION";
230    case CANCEL:
231      return "CANCEL";
232    case INTERNAL_ERROR:
233      return "INTERNAL_ERROR";
234    case FLOW_CONTROL_ERROR:
235      return "FLOW_CONTROL_ERROR";
236    case STREAM_IN_USE:
237      return "STREAM_IN_USE";
238    case STREAM_ALREADY_CLOSED:
239      return "STREAM_ALREADY_CLOSED";
240    case INVALID_CREDENTIALS:
241      return "INVALID_CREDENTIALS";
242    case FRAME_TOO_LARGE:
243      return "FRAME_TOO_LARGE";
244  }
245  return "UNKNOWN_STATUS";
246}
247
248const char* SpdyFramer::ControlTypeToString(SpdyControlType type) {
249  switch (type) {
250    case SYN_STREAM:
251      return "SYN_STREAM";
252    case SYN_REPLY:
253      return "SYN_REPLY";
254    case RST_STREAM:
255      return "RST_STREAM";
256    case SETTINGS:
257      return "SETTINGS";
258    case NOOP:
259      return "NOOP";
260    case PING:
261      return "PING";
262    case GOAWAY:
263      return "GOAWAY";
264    case HEADERS:
265      return "HEADERS";
266    case WINDOW_UPDATE:
267      return "WINDOW_UPDATE";
268    case CREDENTIAL:
269      return "CREDENTIAL";
270    case NUM_CONTROL_FRAME_TYPES:
271      break;
272  }
273  return "UNKNOWN_CONTROL_TYPE";
274}
275
276size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
277  DCHECK(visitor_);
278  DCHECK(data);
279
280  size_t original_len = len;
281  do {
282    previous_state_ = state_;
283    switch (state_) {
284      case SPDY_ERROR:
285      case SPDY_DONE:
286        goto bottom;
287
288      case SPDY_AUTO_RESET:
289      case SPDY_RESET:
290        Reset();
291        if (len > 0) {
292          CHANGE_STATE(SPDY_READING_COMMON_HEADER);
293        }
294        break;
295
296      case SPDY_READING_COMMON_HEADER: {
297        size_t bytes_read = ProcessCommonHeader(data, len);
298        len -= bytes_read;
299        data += bytes_read;
300        break;
301      }
302
303      case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
304        // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY,
305        // HEADERS) take a different path through the state machine - they
306        // will go:
307        //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
308        //   2. SPDY_CONTROL_FRAME_HEADER_BLOCK
309        //
310        // SETTINGS frames take a slightly modified route:
311        //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
312        //   2. SPDY_SETTINGS_FRAME_PAYLOAD
313        //
314        //  All other control frames will use the alternate route directly to
315        //  SPDY_CONTROL_FRAME_PAYLOAD
316        int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
317        len -= bytes_read;
318        data += bytes_read;
319        break;
320      }
321
322      case SPDY_SETTINGS_FRAME_PAYLOAD: {
323        int bytes_read = ProcessSettingsFramePayload(data, len);
324        len -= bytes_read;
325        data += bytes_read;
326        break;
327      }
328
329      case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
330        int bytes_read = ProcessControlFrameHeaderBlock(data, len);
331        len -= bytes_read;
332        data += bytes_read;
333        break;
334      }
335
336      case SPDY_CREDENTIAL_FRAME_PAYLOAD: {
337        size_t bytes_read = ProcessCredentialFramePayload(data, len);
338        len -= bytes_read;
339        data += bytes_read;
340        break;
341      }
342
343      case SPDY_CONTROL_FRAME_PAYLOAD: {
344        size_t bytes_read = ProcessControlFramePayload(data, len);
345        len -= bytes_read;
346        data += bytes_read;
347        break;
348      }
349
350      case SPDY_IGNORE_REMAINING_PAYLOAD:
351        // control frame has too-large payload
352        // intentional fallthrough
353      case SPDY_FORWARD_STREAM_FRAME: {
354        size_t bytes_read = ProcessDataFramePayload(data, len);
355        len -= bytes_read;
356        data += bytes_read;
357        break;
358      }
359      default:
360        LOG(DFATAL) << "Invalid value for " << display_protocol_
361                    << " framer state: " << state_;
362        // This ensures that we don't infinite-loop if state_ gets an
363        // invalid value somehow, such as due to a SpdyFramer getting deleted
364        // from a callback it calls.
365        goto bottom;
366    }
367  } while (state_ != previous_state_);
368 bottom:
369  DCHECK(len == 0 || state_ == SPDY_ERROR);
370  if (current_frame_len_ == 0 &&
371      remaining_data_ == 0 &&
372      remaining_control_payload_ == 0 &&
373      remaining_control_header_ == 0) {
374    DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR)
375        << "State: " << StateToString(state_);
376  }
377
378  return original_len - len;
379}
380
381size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
382  // This should only be called when we're in the SPDY_READING_COMMON_HEADER
383  // state.
384  DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);
385
386  size_t original_len = len;
387  SpdyFrame current_frame(current_frame_buffer_.get(), false);
388
389  // Update current frame buffer as needed.
390  if (current_frame_len_ < SpdyFrame::kHeaderSize) {
391    size_t bytes_desired = SpdyFrame::kHeaderSize - current_frame_len_;
392    UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
393  }
394
395  if (current_frame_len_ < SpdyFrame::kHeaderSize) {
396    // TODO(rch): remove this empty block
397    // Do nothing.
398  } else {
399    remaining_data_ = current_frame.length();
400
401    // This is just a sanity check for help debugging early frame errors.
402    if (remaining_data_ > 1000000u) {
403      // The strncmp for 5 is safe because we only hit this point if we
404      // have SpdyFrame::kHeaderSize (8) bytes
405      if (!syn_frame_processed_ &&
406          strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
407        LOG(WARNING) << "Unexpected HTTP response to spdy request";
408        probable_http_response_ = true;
409      } else {
410        LOG(WARNING) << "Unexpectedly large frame.  " << display_protocol_
411                     << " session is likely corrupt.";
412      }
413    }
414
415    // if we're here, then we have the common header all received.
416    if (!current_frame.is_control_frame()) {
417      SpdyDataFrame data_frame(current_frame_buffer_.get(), false);
418      visitor_->OnDataFrameHeader(&data_frame);
419
420      if (current_frame.length() > 0) {
421        CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
422      } else {
423        // Empty data frame.
424        if (current_frame.flags() & DATA_FLAG_FIN) {
425          visitor_->OnStreamFrameData(data_frame.stream_id(),
426                                      NULL, 0, DATA_FLAG_FIN);
427        }
428        CHANGE_STATE(SPDY_AUTO_RESET);
429      }
430    } else {
431      ProcessControlFrameHeader();
432    }
433  }
434  return original_len - len;
435}
436
437void SpdyFramer::ProcessControlFrameHeader() {
438  DCHECK_EQ(SPDY_NO_ERROR, error_code_);
439  DCHECK_LE(static_cast<size_t>(SpdyFrame::kHeaderSize), current_frame_len_);
440  SpdyControlFrame current_control_frame(current_frame_buffer_.get(), false);
441
442  // We check version before we check validity: version can never be 'invalid',
443  // it can only be unsupported.
444  if (current_control_frame.version() != spdy_version_) {
445    DLOG(INFO) << "Unsupported SPDY version " << current_control_frame.version()
446               << " (expected " << spdy_version_ << ")";
447    set_error(SPDY_UNSUPPORTED_VERSION);
448    return;
449  }
450
451  // Next up, check to see if we have valid data.  This should be after version
452  // checking (otherwise if the the type were out of bounds due to a version
453  // upgrade we would misclassify the error) and before checking the type
454  // (type can definitely be out of bounds)
455  if (!current_control_frame.AppearsToBeAValidControlFrame()) {
456    set_error(SPDY_INVALID_CONTROL_FRAME);
457    return;
458  }
459
460  if (current_control_frame.type() == NOOP) {
461    DLOG(INFO) << "NOOP control frame found. Ignoring.";
462    CHANGE_STATE(SPDY_AUTO_RESET);
463    return;
464  }
465
466  // Do some sanity checking on the control frame sizes.
467  switch (current_control_frame.type()) {
468    case SYN_STREAM:
469      if (current_control_frame.length() <
470          SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize)
471        set_error(SPDY_INVALID_CONTROL_FRAME);
472      break;
473    case SYN_REPLY:
474      if (current_control_frame.length() <
475          SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize)
476        set_error(SPDY_INVALID_CONTROL_FRAME);
477      break;
478    case RST_STREAM:
479      if (current_control_frame.length() !=
480          SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize)
481        set_error(SPDY_INVALID_CONTROL_FRAME);
482      break;
483    case SETTINGS:
484      // Make sure that we have an integral number of 8-byte key/value pairs,
485      // plus a 4-byte length field.
486      if (current_control_frame.length() <
487          SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize ||
488          (current_control_frame.length() % 8 != 4)) {
489        DLOG(WARNING) << "Invalid length for SETTINGS frame: "
490                      << current_control_frame.length();
491        set_error(SPDY_INVALID_CONTROL_FRAME);
492      }
493      break;
494    case GOAWAY:
495      {
496        // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account
497        // for this difference via a separate offset variable, since
498        // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
499        const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
500        if (current_control_frame.length() + goaway_offset !=
501            SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize)
502          set_error(SPDY_INVALID_CONTROL_FRAME);
503        break;
504      }
505    case HEADERS:
506      if (current_control_frame.length() <
507          SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize)
508        set_error(SPDY_INVALID_CONTROL_FRAME);
509      break;
510    case WINDOW_UPDATE:
511      if (current_control_frame.length() !=
512          SpdyWindowUpdateControlFrame::size() -
513          SpdyControlFrame::kHeaderSize)
514        set_error(SPDY_INVALID_CONTROL_FRAME);
515      break;
516    case PING:
517      if (current_control_frame.length() !=
518          SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize)
519        set_error(SPDY_INVALID_CONTROL_FRAME);
520      break;
521    case CREDENTIAL:
522      if (current_control_frame.length() <
523          SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize)
524        set_error(SPDY_INVALID_CONTROL_FRAME);
525      break;
526    default:
527      LOG(WARNING) << "Valid " << display_protocol_
528                   << " control frame with unhandled type: "
529                   << current_control_frame.type();
530      DLOG(FATAL);
531      set_error(SPDY_INVALID_CONTROL_FRAME);
532      break;
533  }
534
535  if (state_ == SPDY_ERROR) {
536    return;
537  }
538
539  remaining_control_payload_ = current_control_frame.length();
540  const size_t total_frame_size =
541      remaining_control_payload_ + SpdyFrame::kHeaderSize;
542  if (total_frame_size > kMaxControlFrameSize) {
543    DLOG(WARNING) << "Received control frame with way too big of a payload: "
544                  << total_frame_size;
545    set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
546    return;
547  }
548
549  if (current_control_frame.type() == CREDENTIAL) {
550    CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD);
551    return;
552  }
553
554  // Determine the frame size without variable-length data.
555  int32 frame_size_without_variable_data;
556  switch (current_control_frame.type()) {
557    case SYN_STREAM:
558      syn_frame_processed_ = true;
559      frame_size_without_variable_data = SpdySynStreamControlFrame::size();
560      break;
561    case SYN_REPLY:
562      syn_frame_processed_ = true;
563      frame_size_without_variable_data = SpdySynReplyControlFrame::size();
564      // SPDY 2 had two bytes of unused space preceeding payload.
565      if (spdy_version_ < 3) {
566        frame_size_without_variable_data += 2;
567      }
568      break;
569    case HEADERS:
570      frame_size_without_variable_data = SpdyHeadersControlFrame::size();
571      // SPDY 2 had two bytes of unused space preceeding payload.
572      if (spdy_version_ < 3) {
573        frame_size_without_variable_data += 2;
574      }
575      break;
576    case SETTINGS:
577      frame_size_without_variable_data = SpdySettingsControlFrame::size();
578      break;
579    default:
580      frame_size_without_variable_data = -1;
581      break;
582  }
583
584  if ((frame_size_without_variable_data == -1) &&
585      (total_frame_size > kControlFrameBufferSize)) {
586    // We should already be in an error state. Double-check.
587    DCHECK_EQ(SPDY_ERROR, state_);
588    if (state_ != SPDY_ERROR) {
589      LOG(DFATAL) << display_protocol_
590                  << " control frame buffer too small for fixed-length frame.";
591      set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
592    }
593    return;
594  }
595  if (frame_size_without_variable_data > 0) {
596    // We have a control frame with a header block. We need to parse the
597    // remainder of the control frame's header before we can parse the header
598    // block. The start of the header block varies with the control type.
599    DCHECK_GE(frame_size_without_variable_data,
600              static_cast<int32>(current_frame_len_));
601    remaining_control_header_ = frame_size_without_variable_data -
602        current_frame_len_;
603    remaining_control_payload_ += SpdyFrame::kHeaderSize -
604        frame_size_without_variable_data;
605    CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
606    return;
607  }
608
609  CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
610}
611
612size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
613                                            size_t max_bytes) {
614  size_t bytes_to_read = std::min(*len, max_bytes);
615  DCHECK_GE(kControlFrameBufferSize, current_frame_len_ + bytes_to_read);
616  memcpy(current_frame_buffer_.get() + current_frame_len_,
617         *data,
618         bytes_to_read);
619  current_frame_len_ += bytes_to_read;
620  *data += bytes_to_read;
621  *len -= bytes_to_read;
622  return bytes_to_read;
623}
624
625size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock* headers) const {
626  const size_t num_name_value_pairs_size
627      = (spdy_version_ < 3) ? sizeof(uint16) : sizeof(uint32);
628  const size_t length_of_name_size = num_name_value_pairs_size;
629  const size_t length_of_value_size = num_name_value_pairs_size;
630
631  size_t total_length = num_name_value_pairs_size;
632  for (SpdyHeaderBlock::const_iterator it = headers->begin();
633       it != headers->end();
634       ++it) {
635    // We add space for the length of the name and the length of the value as
636    // well as the length of the name and the length of the value.
637    total_length += length_of_name_size + it->first.size() +
638                    length_of_value_size + it->second.size();
639  }
640  return total_length;
641}
642
643void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
644                                  const SpdyHeaderBlock* headers) const {
645  if (spdy_version_ < 3) {
646    frame->WriteUInt16(headers->size());  // Number of headers.
647  } else {
648    frame->WriteUInt32(headers->size());  // Number of headers.
649  }
650  SpdyHeaderBlock::const_iterator it;
651  for (it = headers->begin(); it != headers->end(); ++it) {
652    bool wrote_header;
653    if (spdy_version_ < 3) {
654      wrote_header = frame->WriteString(it->first);
655      wrote_header &= frame->WriteString(it->second);
656    } else {
657      wrote_header = frame->WriteStringPiece32(it->first);
658      wrote_header &= frame->WriteStringPiece32(it->second);
659    }
660    DCHECK(wrote_header);
661  }
662}
663
664// TODO(phajdan.jr): Clean up after we no longer need
665// to workaround http://crbug.com/139744.
666#if !defined(USE_SYSTEM_ZLIB)
667
668// These constants are used by zlib to differentiate between normal data and
669// cookie data. Cookie data is handled specially by zlib when compressing.
670enum ZDataClass {
671  // kZStandardData is compressed normally, save that it will never match
672  // against any other class of data in the window.
673  kZStandardData = Z_CLASS_STANDARD,
674  // kZCookieData is compressed in its own Huffman blocks and only matches in
675  // its entirety and only against other kZCookieData blocks. Any matches must
676  // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
677  // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
678  // prefix matches.
679  kZCookieData = Z_CLASS_COOKIE,
680  // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
681  // against the window.
682  kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
683};
684
685// WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
686// needed when switching between classes of data.
687static void WriteZ(const base::StringPiece& data,
688                   ZDataClass clas,
689                   z_stream* out) {
690  int rv;
691
692  // If we are switching from standard to non-standard data then we need to end
693  // the current Huffman context to avoid it leaking between them.
694  if (out->clas == kZStandardData &&
695      clas != kZStandardData) {
696    out->avail_in = 0;
697    rv = deflate(out, Z_PARTIAL_FLUSH);
698    DCHECK_EQ(Z_OK, rv);
699    DCHECK_EQ(0u, out->avail_in);
700    DCHECK_LT(0u, out->avail_out);
701  }
702
703  out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
704  out->avail_in = data.size();
705  out->clas = clas;
706  if (clas == kZStandardData) {
707    rv = deflate(out, Z_NO_FLUSH);
708  } else {
709    rv = deflate(out, Z_PARTIAL_FLUSH);
710  }
711  DCHECK_EQ(Z_OK, rv);
712  DCHECK_EQ(0u, out->avail_in);
713  DCHECK_LT(0u, out->avail_out);
714}
715
716// WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
717static void WriteLengthZ(size_t n,
718                         unsigned length,
719                         ZDataClass clas,
720                         z_stream* out) {
721  char buf[4];
722  DCHECK_LE(length, sizeof(buf));
723  for (unsigned i = 1; i <= length; i++) {
724    buf[length - i] = n;
725    n >>= 8;
726  }
727  WriteZ(base::StringPiece(buf, length), clas, out);
728}
729
730// WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
731// manner that resists the length of the compressed data from compromising
732// cookie data.
733void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
734                                     z_stream* z) const {
735  unsigned length_length = 4;
736  if (spdy_version_ < 3)
737    length_length = 2;
738
739  WriteLengthZ(headers->size(), length_length, kZStandardData, z);
740
741  std::map<std::string, std::string>::const_iterator it;
742  for (it = headers->begin(); it != headers->end(); ++it) {
743    WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
744    WriteZ(it->first, kZStandardData, z);
745
746    if (it->first == "cookie") {
747      // We require the cookie values (save for the last) to end with a
748      // semicolon and (save for the first) to start with a space. This is
749      // typically the format that we are given them in but we reserialize them
750      // to be sure.
751
752      std::vector<base::StringPiece> cookie_values;
753      size_t cookie_length = 0;
754      base::StringPiece cookie_data(it->second);
755
756      for (;;) {
757        while (!cookie_data.empty() &&
758               (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
759          cookie_data.remove_prefix(1);
760        }
761        if (cookie_data.empty())
762          break;
763
764        size_t i;
765        for (i = 0; i < cookie_data.size(); i++) {
766          if (cookie_data[i] == ';')
767            break;
768        }
769        if (i < cookie_data.size()) {
770          cookie_values.push_back(cookie_data.substr(0, i));
771          cookie_length += i + 2 /* semicolon and space */;
772          cookie_data.remove_prefix(i + 1);
773        } else {
774          cookie_values.push_back(cookie_data);
775          cookie_length += cookie_data.size();
776          cookie_data.remove_prefix(i);
777        }
778      }
779
780      WriteLengthZ(cookie_length, length_length, kZStandardData, z);
781      for (size_t i = 0; i < cookie_values.size(); i++) {
782        std::string cookie;
783        // Since zlib will only back-reference complete cookies, a cookie that
784        // is currently last (and so doesn't have a trailing semicolon) won't
785        // match if it's later in a non-final position. The same is true of
786        // the first cookie.
787        if (i == 0 && cookie_values.size() == 1) {
788          cookie = cookie_values[i].as_string();
789        } else if (i == 0) {
790          cookie = cookie_values[i].as_string() + ";";
791        } else if (i < cookie_values.size() - 1) {
792          cookie = " " + cookie_values[i].as_string() + ";";
793        } else {
794          cookie = " " + cookie_values[i].as_string();
795        }
796        WriteZ(cookie, kZCookieData, z);
797      }
798    } else if (it->first == "accept" ||
799               it->first == "accept-charset" ||
800               it->first == "accept-encoding" ||
801               it->first == "accept-language" ||
802               it->first == "host" ||
803               it->first == "version" ||
804               it->first == "method" ||
805               it->first == "scheme" ||
806               it->first == ":host" ||
807               it->first == ":version" ||
808               it->first == ":method" ||
809               it->first == ":scheme" ||
810               it->first == "user-agent") {
811      WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
812      WriteZ(it->second, kZStandardData, z);
813    } else {
814      // Non-whitelisted headers are Huffman compressed in their own block, but
815      // don't match against the window.
816      WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
817      WriteZ(it->second, kZHuffmanOnlyData, z);
818    }
819  }
820
821  z->avail_in = 0;
822  int rv = deflate(z, Z_SYNC_FLUSH);
823  DCHECK_EQ(Z_OK, rv);
824  z->clas = kZStandardData;
825}
826#endif  // !defined(USE_SYSTEM_ZLIB)
827
828size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
829                                                        size_t len) {
830  DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
831  size_t original_len = len;
832
833  if (remaining_control_header_ > 0) {
834    size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
835                                                 remaining_control_header_);
836    remaining_control_header_ -= bytes_read;
837  }
838
839  if (remaining_control_header_ == 0) {
840    SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
841    switch (control_frame.type()) {
842      case SYN_STREAM:
843        {
844          SpdySynStreamControlFrame* syn_stream_frame =
845              reinterpret_cast<SpdySynStreamControlFrame*>(&control_frame);
846          // TODO(hkhalil): Check that invalid flag bits are unset?
847          visitor_->OnSynStream(
848              syn_stream_frame->stream_id(),
849              syn_stream_frame->associated_stream_id(),
850              syn_stream_frame->priority(),
851              syn_stream_frame->credential_slot(),
852              (syn_stream_frame->flags() & CONTROL_FLAG_FIN) != 0,
853              (syn_stream_frame->flags() & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
854        }
855        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
856        break;
857      case SYN_REPLY:
858        {
859          SpdySynReplyControlFrame* syn_reply_frame =
860              reinterpret_cast<SpdySynReplyControlFrame*>(&control_frame);
861          visitor_->OnSynReply(
862              syn_reply_frame->stream_id(),
863              (syn_reply_frame->flags() & CONTROL_FLAG_FIN) != 0);
864        }
865        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
866        break;
867      case HEADERS:
868        {
869          SpdyHeadersControlFrame* headers_frame =
870              reinterpret_cast<SpdyHeadersControlFrame*>(&control_frame);
871          visitor_->OnHeaders(
872              headers_frame->stream_id(),
873              (headers_frame->flags() & CONTROL_FLAG_FIN) != 0);
874        }
875        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
876        break;
877      case SETTINGS:
878        CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
879        break;
880      default:
881        DCHECK(false);
882    }
883  }
884  return original_len - len;
885}
886
887// Does not buffer the control payload. Instead, either passes directly to the
888// visitor or decompresses and then passes directly to the visitor, via
889// IncrementallyDeliverControlFrameHeaderData() or
890// IncrementallyDecompressControlFrameHeaderData() respectively.
891size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
892                                                  size_t data_len) {
893  DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
894  SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
895
896  bool processed_successfully = true;
897  DCHECK(control_frame.type() == SYN_STREAM ||
898         control_frame.type() == SYN_REPLY ||
899         control_frame.type() == HEADERS);
900  size_t process_bytes = std::min(data_len, remaining_control_payload_);
901  if (process_bytes > 0) {
902    if (enable_compression_) {
903      processed_successfully = IncrementallyDecompressControlFrameHeaderData(
904          &control_frame, data, process_bytes);
905    } else {
906      processed_successfully = IncrementallyDeliverControlFrameHeaderData(
907          &control_frame, data, process_bytes);
908    }
909
910    remaining_control_payload_ -= process_bytes;
911    remaining_data_ -= process_bytes;
912  }
913
914  // Handle the case that there is no futher data in this frame.
915  if (remaining_control_payload_ == 0 && processed_successfully) {
916    // The complete header block has been delivered. We send a zero-length
917    // OnControlFrameHeaderData() to indicate this.
918    visitor_->OnControlFrameHeaderData(
919        GetControlFrameStreamId(&control_frame), NULL, 0);
920
921    // If this is a FIN, tell the caller.
922    if (control_frame.flags() & CONTROL_FLAG_FIN) {
923      visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame),
924                                  NULL, 0, DATA_FLAG_FIN);
925    }
926
927    CHANGE_STATE(SPDY_AUTO_RESET);
928  }
929
930  // Handle error.
931  if (!processed_successfully) {
932    return data_len;
933  }
934
935  // Return amount processed.
936  return process_bytes;
937}
938
939size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
940                                               size_t data_len) {
941  DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
942  SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
943  DCHECK_EQ(SETTINGS, control_frame.type());
944  size_t unprocessed_bytes = std::min(data_len, remaining_control_payload_);
945  size_t processed_bytes = 0;
946
947  // Loop over our incoming data.
948  while (unprocessed_bytes > 0) {
949    // Process up to one setting at a time.
950    size_t processing = std::min(
951        unprocessed_bytes,
952        static_cast<size_t>(8 - settings_scratch_.setting_buf_len));
953
954    // Check if we have a complete setting in our input.
955    if (processing == 8) {
956      // Parse the setting directly out of the input without buffering.
957      if (!ProcessSetting(data + processed_bytes)) {
958        set_error(SPDY_INVALID_CONTROL_FRAME);
959        return processed_bytes;
960      }
961    } else {
962      // Continue updating settings_scratch_.setting_buf.
963      memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
964             data + processed_bytes,
965             processing);
966      settings_scratch_.setting_buf_len += processing;
967
968      // Check if we have a complete setting buffered.
969      if (settings_scratch_.setting_buf_len == 8) {
970        if (!ProcessSetting(settings_scratch_.setting_buf)) {
971          set_error(SPDY_INVALID_CONTROL_FRAME);
972          return processed_bytes;
973        }
974        // Reset settings_scratch_.setting_buf for our next setting.
975        settings_scratch_.setting_buf_len = 0;
976      }
977    }
978
979    // Iterate.
980    unprocessed_bytes -= processing;
981    processed_bytes += processing;
982  }
983
984  // Check if we're done handling this SETTINGS frame.
985  remaining_control_payload_ -= processed_bytes;
986  if (remaining_control_payload_ == 0) {
987    CHANGE_STATE(SPDY_AUTO_RESET);
988  }
989
990  return processed_bytes;
991}
992
993bool SpdyFramer::ProcessSetting(const char* data) {
994  // Extract fields.
995  // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
996  const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
997  SettingsFlagsAndId id_and_flags =
998      SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire);
999  uint8 flags = id_and_flags.flags();
1000  uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
1001
1002  // Validate id.
1003  switch (id_and_flags.id()) {
1004    case SETTINGS_UPLOAD_BANDWIDTH:
1005    case SETTINGS_DOWNLOAD_BANDWIDTH:
1006    case SETTINGS_ROUND_TRIP_TIME:
1007    case SETTINGS_MAX_CONCURRENT_STREAMS:
1008    case SETTINGS_CURRENT_CWND:
1009    case SETTINGS_DOWNLOAD_RETRANS_RATE:
1010    case SETTINGS_INITIAL_WINDOW_SIZE:
1011      // Valid values.
1012      break;
1013    default:
1014      DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id();
1015      return false;
1016  }
1017  SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id());
1018
1019  // Detect duplciates.
1020  if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) {
1021    DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
1022                  << " in " << display_protocol_ << " SETTINGS frame "
1023                  << "(last settikng id was "
1024                  << settings_scratch_.last_setting_id << ").";
1025    return false;
1026  }
1027  settings_scratch_.last_setting_id = id;
1028
1029  // Validate flags.
1030  uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
1031  if ((flags & ~(kFlagsMask)) != 0) {
1032    DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
1033                  << flags;
1034    return false;
1035  }
1036
1037  // Validation succeeded. Pass on to visitor.
1038  visitor_->OnSetting(id, flags, value);
1039  return true;
1040}
1041
1042size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
1043  size_t original_len = len;
1044  if (remaining_control_payload_) {
1045    size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
1046                                                 remaining_control_payload_);
1047    remaining_control_payload_ -= bytes_read;
1048    remaining_data_ -= bytes_read;
1049    if (remaining_control_payload_ == 0) {
1050      SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
1051      DCHECK(!control_frame.has_header_block());
1052      // Use frame-specific handlers.
1053      switch (control_frame.type()) {
1054        case PING: {
1055            SpdyPingControlFrame* ping_frame =
1056                reinterpret_cast<SpdyPingControlFrame*>(&control_frame);
1057            visitor_->OnPing(ping_frame->unique_id());
1058          }
1059          break;
1060        case WINDOW_UPDATE: {
1061            SpdyWindowUpdateControlFrame *window_update_frame =
1062                reinterpret_cast<SpdyWindowUpdateControlFrame*>(&control_frame);
1063            visitor_->OnWindowUpdate(window_update_frame->stream_id(),
1064                                     window_update_frame->delta_window_size());
1065          }
1066          break;
1067        case RST_STREAM: {
1068            SpdyRstStreamControlFrame* rst_stream_frame =
1069                reinterpret_cast<SpdyRstStreamControlFrame*>(&control_frame);
1070            visitor_->OnRstStream(rst_stream_frame->stream_id(),
1071                                  rst_stream_frame->status());
1072          }
1073          break;
1074        case GOAWAY: {
1075            SpdyGoAwayControlFrame* go_away_frame =
1076                reinterpret_cast<SpdyGoAwayControlFrame*>(&control_frame);
1077            if (spdy_version_ < 3) {
1078              visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(),
1079                                 GOAWAY_OK);
1080            } else {
1081              visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(),
1082                                 go_away_frame->status());
1083            }
1084          }
1085          break;
1086        default:
1087          // Unreachable.
1088          LOG(FATAL) << "Unhandled control frame " << control_frame.type();
1089      }
1090
1091      CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
1092    }
1093  }
1094  return original_len - len;
1095}
1096
1097size_t SpdyFramer::ProcessCredentialFramePayload(const char* data, size_t len) {
1098  if (len > 0) {
1099    // Process only up to the end of this CREDENTIAL frame.
1100    len = std::min(len, remaining_control_payload_);
1101    bool processed_succesfully = visitor_->OnCredentialFrameData(data, len);
1102    remaining_control_payload_ -= len;
1103    remaining_data_ -= len;
1104    if (!processed_succesfully) {
1105      set_error(SPDY_CREDENTIAL_FRAME_CORRUPT);
1106    } else if (remaining_control_payload_ == 0) {
1107      visitor_->OnCredentialFrameData(NULL, 0);
1108      CHANGE_STATE(SPDY_AUTO_RESET);
1109    }
1110  }
1111  return len;
1112}
1113
1114size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
1115  size_t original_len = len;
1116
1117  SpdyDataFrame current_data_frame(current_frame_buffer_.get(), false);
1118  if (remaining_data_ > 0) {
1119    size_t amount_to_forward = std::min(remaining_data_, len);
1120    if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
1121      // Only inform the visitor if there is data.
1122      if (amount_to_forward) {
1123        visitor_->OnStreamFrameData(current_data_frame.stream_id(),
1124                                    data, amount_to_forward, SpdyDataFlags());
1125      }
1126    }
1127    data += amount_to_forward;
1128    len -= amount_to_forward;
1129    remaining_data_ -= amount_to_forward;
1130
1131    // If the FIN flag is set, and there is no more data in this data
1132    // frame, inform the visitor of EOF via a 0-length data frame.
1133    if (!remaining_data_ &&
1134        current_data_frame.flags() & DATA_FLAG_FIN) {
1135      visitor_->OnStreamFrameData(current_data_frame.stream_id(),
1136                                  NULL, 0, DATA_FLAG_FIN);
1137    }
1138  }
1139
1140  if (remaining_data_ == 0) {
1141    CHANGE_STATE(SPDY_AUTO_RESET);
1142  }
1143  return original_len - len;
1144}
1145
1146bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
1147                                          size_t header_length,
1148                                          SpdyHeaderBlock* block) const {
1149  SpdyFrameReader reader(header_data, header_length);
1150
1151  // Read number of headers.
1152  uint32 num_headers;
1153  if (spdy_version_ < 3) {
1154    uint16 temp;
1155    if (!reader.ReadUInt16(&temp)) {
1156      DLOG(INFO) << "Unable to read number of headers.";
1157      return false;
1158    }
1159    num_headers = temp;
1160  } else {
1161    if (!reader.ReadUInt32(&num_headers)) {
1162      DLOG(INFO) << "Unable to read number of headers.";
1163      return false;
1164    }
1165  }
1166
1167  // Read each header.
1168  for (uint32 index = 0; index < num_headers; ++index) {
1169    base::StringPiece temp;
1170
1171    // Read header name.
1172    if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
1173                            : !reader.ReadStringPiece32(&temp)) {
1174      DLOG(INFO) << "Unable to read header name (" << index + 1 << " of "
1175                 << num_headers << ").";
1176      return false;
1177    }
1178    std::string name = temp.as_string();
1179
1180    // Read header value.
1181    if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
1182                            : !reader.ReadStringPiece32(&temp)) {
1183      DLOG(INFO) << "Unable to read header value (" << index + 1 << " of "
1184                 << num_headers << ").";
1185      return false;
1186    }
1187    std::string value = temp.as_string();
1188
1189    // Ensure no duplicates.
1190    if (block->find(name) != block->end()) {
1191      DLOG(INFO) << "Duplicate header '" << name << "' (" << index + 1 << " of "
1192                 << num_headers << ").";
1193      return false;
1194    }
1195
1196    // Store header.
1197    (*block)[name] = value;
1198  }
1199  return true;
1200}
1201
1202// TODO(hkhalil): Remove, or move to test utils kit.
1203/* static */
1204bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame,
1205                               SettingsMap* settings) {
1206  DCHECK_EQ(frame->type(), SETTINGS);
1207  DCHECK(settings);
1208
1209  SpdyFrameReader parser(frame->header_block(), frame->header_block_len());
1210  for (size_t index = 0; index < frame->num_entries(); ++index) {
1211    uint32 id_and_flags_wire;
1212    uint32 value;
1213    // SettingsFlagsAndId accepts off-the-wire (network byte order) data, so we
1214    // use ReadBytes() instead of ReadUInt32() as the latter calls ntohl().
1215    if (!parser.ReadBytes(&id_and_flags_wire, 4)) {
1216      return false;
1217    }
1218    if (!parser.ReadUInt32(&value))
1219      return false;
1220    SettingsFlagsAndId flags_and_id =
1221        SettingsFlagsAndId::FromWireFormat(frame->version(), id_and_flags_wire);
1222    SpdySettingsIds id = static_cast<SpdySettingsIds>(flags_and_id.id());
1223    SpdySettingsFlags flags =
1224        static_cast<SpdySettingsFlags>(flags_and_id.flags());
1225    (*settings)[id] = SettingsFlagsAndValue(flags, value);
1226  }
1227  return true;
1228}
1229
1230/* static */
1231bool SpdyFramer::ParseCredentialData(const char* data, size_t len,
1232                                     SpdyCredential* credential) {
1233  DCHECK(credential);
1234
1235  SpdyFrameReader parser(data, len);
1236  base::StringPiece temp;
1237  if (!parser.ReadUInt16(&credential->slot)) {
1238    return false;
1239  }
1240
1241  if (!parser.ReadStringPiece32(&temp)) {
1242    return false;
1243  }
1244  credential->proof = temp.as_string();
1245
1246  while (!parser.IsDoneReading()) {
1247    if (!parser.ReadStringPiece32(&temp)) {
1248      return false;
1249    }
1250    credential->certs.push_back(temp.as_string());
1251  }
1252  return true;
1253}
1254
1255SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
1256    SpdyStreamId stream_id,
1257    SpdyStreamId associated_stream_id,
1258    SpdyPriority priority,
1259    uint8 credential_slot,
1260    SpdyControlFlags flags,
1261    bool compressed,
1262    const SpdyHeaderBlock* headers) {
1263  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1264  DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask);
1265
1266  // Find our length.
1267  size_t frame_size = SpdySynStreamControlFrame::size() +
1268                      GetSerializedLength(headers);
1269
1270  SpdyFrameBuilder frame(SYN_STREAM, flags, spdy_version_, frame_size);
1271  frame.WriteUInt32(stream_id);
1272  frame.WriteUInt32(associated_stream_id);
1273  // Cap as appropriate.
1274  if (priority > GetLowestPriority()) {
1275    DLOG(DFATAL) << "Priority out-of-bounds.";
1276    priority = GetLowestPriority();
1277  }
1278  // Priority is 2 bits for <spdy3, 3 bits otherwise.
1279  frame.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
1280  frame.WriteUInt8((spdy_version_ < 3) ? 0 : credential_slot);
1281  WriteHeaderBlock(&frame, headers);
1282  DCHECK_EQ(frame.length(), frame_size);
1283
1284  scoped_ptr<SpdySynStreamControlFrame> syn_frame(
1285      reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
1286  if (compressed) {
1287    return reinterpret_cast<SpdySynStreamControlFrame*>(
1288        CompressControlFrame(*syn_frame.get(), headers));
1289  }
1290  return syn_frame.release();
1291}
1292
1293SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
1294    SpdyStreamId stream_id,
1295    SpdyControlFlags flags,
1296    bool compressed,
1297    const SpdyHeaderBlock* headers) {
1298  DCHECK_GT(stream_id, 0u);
1299  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1300
1301  // Find our length.
1302  size_t frame_size = SpdySynReplyControlFrame::size() +
1303                      GetSerializedLength(headers);
1304  // In SPDY 2, there were 2 unused bytes before payload.
1305  if (spdy_version_ < 3) {
1306    frame_size += 2;
1307  }
1308
1309  SpdyFrameBuilder frame(SYN_REPLY, flags, spdy_version_, frame_size);
1310  frame.WriteUInt32(stream_id);
1311  if (spdy_version_ < 3) {
1312    frame.WriteUInt16(0);  // Unused
1313  }
1314  WriteHeaderBlock(&frame, headers);
1315  DCHECK_EQ(frame.length(), frame_size);
1316
1317  scoped_ptr<SpdySynReplyControlFrame> reply_frame(
1318      reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
1319  if (compressed) {
1320    return reinterpret_cast<SpdySynReplyControlFrame*>(
1321        CompressControlFrame(*reply_frame.get(), headers));
1322  }
1323  return reply_frame.release();
1324}
1325
1326SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(
1327    SpdyStreamId stream_id,
1328    SpdyStatusCodes status) const {
1329  DCHECK_GT(stream_id, 0u);
1330  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1331  DCHECK_NE(status, INVALID);
1332  DCHECK_LT(status, NUM_STATUS_CODES);
1333
1334  size_t frame_size = SpdyRstStreamControlFrame::size();
1335  SpdyFrameBuilder frame(RST_STREAM, CONTROL_FLAG_NONE, spdy_version_,
1336                         frame_size);
1337  frame.WriteUInt32(stream_id);
1338  frame.WriteUInt32(status);
1339  DCHECK_EQ(frame.length(), frame_size);
1340  return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take());
1341}
1342
1343SpdySettingsControlFrame* SpdyFramer::CreateSettings(
1344    const SettingsMap& values) const {
1345  size_t frame_size = SpdySettingsControlFrame::size() + 8 * values.size();
1346  SpdyFrameBuilder frame(SETTINGS, CONTROL_FLAG_NONE, spdy_version_,
1347                         frame_size);
1348  frame.WriteUInt32(values.size());
1349  for (SettingsMap::const_iterator it = values.begin();
1350       it != values.end();
1351       it++) {
1352    SettingsFlagsAndId flags_and_id(it->second.first, it->first);
1353    uint32 id_and_flags_wire = flags_and_id.GetWireFormat(spdy_version_);
1354    frame.WriteBytes(&id_and_flags_wire, 4);
1355    frame.WriteUInt32(it->second.second);
1356  }
1357  DCHECK_EQ(frame.length(), frame_size);
1358  return reinterpret_cast<SpdySettingsControlFrame*>(frame.take());
1359}
1360
1361SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
1362  size_t frame_size = SpdyPingControlFrame::size();
1363  SpdyFrameBuilder frame(PING, CONTROL_FLAG_NONE, spdy_version_, frame_size);
1364  frame.WriteUInt32(unique_id);
1365  DCHECK_EQ(frame.length(), frame_size);
1366  return reinterpret_cast<SpdyPingControlFrame*>(frame.take());
1367}
1368
1369SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway(
1370    SpdyStreamId last_accepted_stream_id,
1371    SpdyGoAwayStatus status) const {
1372  DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask);
1373
1374  // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account for
1375  // this difference via a separate offset variable, since
1376  // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
1377  const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
1378  size_t frame_size = SpdyGoAwayControlFrame::size() - goaway_offset;
1379  SpdyFrameBuilder frame(GOAWAY, CONTROL_FLAG_NONE, spdy_version_, frame_size);
1380  frame.WriteUInt32(last_accepted_stream_id);
1381  if (protocol_version() >= 3) {
1382    frame.WriteUInt32(status);
1383  }
1384  DCHECK_EQ(frame.length(), frame_size);
1385  return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take());
1386}
1387
1388SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(
1389    SpdyStreamId stream_id,
1390    SpdyControlFlags flags,
1391    bool compressed,
1392    const SpdyHeaderBlock* headers) {
1393  // Basically the same as CreateSynReply().
1394  DCHECK_GT(stream_id, 0u);
1395  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1396
1397  // Find our length.
1398  size_t frame_size = SpdyHeadersControlFrame::size() +
1399                      GetSerializedLength(headers);
1400  // In SPDY 2, there were 2 unused bytes before payload.
1401  if (spdy_version_ < 3) {
1402    frame_size += 2;
1403  }
1404
1405  SpdyFrameBuilder frame(HEADERS, flags, spdy_version_, frame_size);
1406  frame.WriteUInt32(stream_id);
1407  if (spdy_version_ < 3) {
1408    frame.WriteUInt16(0);  // Unused
1409  }
1410  WriteHeaderBlock(&frame, headers);
1411  DCHECK_EQ(frame.length(), frame_size);
1412
1413  scoped_ptr<SpdyHeadersControlFrame> headers_frame(
1414      reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
1415  if (compressed) {
1416    return reinterpret_cast<SpdyHeadersControlFrame*>(
1417        CompressControlFrame(*headers_frame.get(), headers));
1418  }
1419  return headers_frame.release();
1420}
1421
1422SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate(
1423    SpdyStreamId stream_id,
1424    uint32 delta_window_size) const {
1425  DCHECK_GT(stream_id, 0u);
1426  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1427  DCHECK_GT(delta_window_size, 0u);
1428  DCHECK_LE(delta_window_size,
1429            static_cast<uint32>(kSpdyStreamMaximumWindowSize));
1430
1431  size_t frame_size = SpdyWindowUpdateControlFrame::size();
1432  SpdyFrameBuilder frame(WINDOW_UPDATE, CONTROL_FLAG_NONE, spdy_version_,
1433                         frame_size);
1434  frame.WriteUInt32(stream_id);
1435  frame.WriteUInt32(delta_window_size);
1436  DCHECK_EQ(frame.length(), frame_size);
1437  return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take());
1438}
1439
1440SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame(
1441    const SpdyCredential& credential) const {
1442  // Calculate the size of the frame by adding the size of the
1443  // variable length data to the size of the fixed length data.
1444  size_t frame_size =  SpdyCredentialControlFrame::size() +
1445      credential.proof.length();
1446  DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u);
1447  for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
1448       cert != credential.certs.end();
1449       ++cert) {
1450    frame_size += sizeof(uint32);  // size of the cert_length field
1451    frame_size += cert->length();     // size of the cert_data field
1452  }
1453
1454  SpdyFrameBuilder frame(CREDENTIAL, CONTROL_FLAG_NONE, spdy_version_,
1455                         frame_size);
1456  frame.WriteUInt16(credential.slot);
1457  frame.WriteUInt32(credential.proof.size());
1458  frame.WriteBytes(credential.proof.c_str(), credential.proof.size());
1459  for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
1460       cert != credential.certs.end();
1461       ++cert) {
1462    frame.WriteUInt32(cert->length());
1463    frame.WriteBytes(cert->c_str(), cert->length());
1464  }
1465  DCHECK_EQ(frame.length(), frame_size);
1466  return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take());
1467}
1468
1469SpdyDataFrame* SpdyFramer::CreateDataFrame(
1470    SpdyStreamId stream_id,
1471                                           const char* data,
1472    uint32 len, SpdyDataFlags flags) const {
1473  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1474  size_t frame_size = SpdyDataFrame::size() + len;
1475  SpdyFrameBuilder frame(stream_id, flags, frame_size);
1476  frame.WriteBytes(data, len);
1477  DCHECK_EQ(frame.length(), frame_size);
1478  return reinterpret_cast<SpdyDataFrame*>(frame.take());
1479}
1480
1481// The following compression setting are based on Brian Olson's analysis. See
1482// https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792
1483// for more details.
1484#if defined(USE_SYSTEM_ZLIB)
1485// System zlib is not expected to have workaround for http://crbug.com/139744,
1486// so disable compression in that case.
1487// TODO(phajdan.jr): Remove the special case when it's no longer necessary.
1488static const int kCompressorLevel = 0;
1489#else  // !defined(USE_SYSTEM_ZLIB)
1490static const int kCompressorLevel = 9;
1491#endif  // !defined(USE_SYSTEM_ZLIB)
1492static const int kCompressorWindowSizeInBits = 11;
1493static const int kCompressorMemLevel = 1;
1494
1495z_stream* SpdyFramer::GetHeaderCompressor() {
1496  if (header_compressor_.get())
1497    return header_compressor_.get();  // Already initialized.
1498
1499  header_compressor_.reset(new z_stream);
1500  memset(header_compressor_.get(), 0, sizeof(z_stream));
1501
1502  int success = deflateInit2(header_compressor_.get(),
1503                             kCompressorLevel,
1504                             Z_DEFLATED,
1505                             kCompressorWindowSizeInBits,
1506                             kCompressorMemLevel,
1507                             Z_DEFAULT_STRATEGY);
1508  if (success == Z_OK) {
1509    const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
1510                                                 : kV3Dictionary;
1511    const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
1512                                                    : kV3DictionarySize;
1513    success = deflateSetDictionary(header_compressor_.get(),
1514                                   reinterpret_cast<const Bytef*>(dictionary),
1515                                   dictionary_size);
1516  }
1517  if (success != Z_OK) {
1518    LOG(WARNING) << "deflateSetDictionary failure: " << success;
1519    header_compressor_.reset(NULL);
1520    return NULL;
1521  }
1522  return header_compressor_.get();
1523}
1524
1525z_stream* SpdyFramer::GetHeaderDecompressor() {
1526  if (header_decompressor_.get())
1527    return header_decompressor_.get();  // Already initialized.
1528
1529  header_decompressor_.reset(new z_stream);
1530  memset(header_decompressor_.get(), 0, sizeof(z_stream));
1531
1532  int success = inflateInit(header_decompressor_.get());
1533  if (success != Z_OK) {
1534    LOG(WARNING) << "inflateInit failure: " << success;
1535    header_decompressor_.reset(NULL);
1536    return NULL;
1537  }
1538  return header_decompressor_.get();
1539}
1540
1541bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame,
1542                                    int* payload_length,
1543                                    int* header_length,
1544                                    const char** payload) const {
1545  size_t frame_size;
1546  if (frame.is_control_frame()) {
1547    const SpdyControlFrame& control_frame =
1548        reinterpret_cast<const SpdyControlFrame&>(frame);
1549    switch (control_frame.type()) {
1550      case SYN_STREAM:
1551        {
1552          const SpdySynStreamControlFrame& syn_frame =
1553              reinterpret_cast<const SpdySynStreamControlFrame&>(frame);
1554          frame_size = SpdySynStreamControlFrame::size();
1555          *payload_length = syn_frame.header_block_len();
1556          *header_length = frame_size;
1557          *payload = frame.data() + *header_length;
1558        }
1559        break;
1560      case SYN_REPLY:
1561        {
1562          const SpdySynReplyControlFrame& syn_frame =
1563              reinterpret_cast<const SpdySynReplyControlFrame&>(frame);
1564          frame_size = SpdySynReplyControlFrame::size();
1565          *payload_length = syn_frame.header_block_len();
1566          *header_length = frame_size;
1567          *payload = frame.data() + *header_length;
1568          // SPDY 2 had two bytes of unused space preceeding payload.
1569          if (spdy_version_ < 3) {
1570            *header_length += 2;
1571            *payload += 2;
1572          }
1573        }
1574        break;
1575      case HEADERS:
1576        {
1577          const SpdyHeadersControlFrame& headers_frame =
1578              reinterpret_cast<const SpdyHeadersControlFrame&>(frame);
1579          frame_size = SpdyHeadersControlFrame::size();
1580          *payload_length = headers_frame.header_block_len();
1581          *header_length = frame_size;
1582          *payload = frame.data() + *header_length;
1583          // SPDY 2 had two bytes of unused space preceeding payload.
1584          if (spdy_version_ < 3) {
1585            *header_length += 2;
1586            *payload += 2;
1587          }
1588        }
1589        break;
1590      default:
1591        // TODO(mbelshe): set an error?
1592        return false;  // We can't compress this frame!
1593    }
1594  } else {
1595    frame_size = SpdyFrame::kHeaderSize;
1596    *header_length = frame_size;
1597    *payload_length = frame.length();
1598    *payload = frame.data() + SpdyFrame::kHeaderSize;
1599  }
1600  return true;
1601}
1602
1603SpdyControlFrame* SpdyFramer::CompressControlFrame(
1604    const SpdyControlFrame& frame,
1605    const SpdyHeaderBlock* headers) {
1606  z_stream* compressor = GetHeaderCompressor();
1607  if (!compressor)
1608    return NULL;
1609
1610  int payload_length;
1611  int header_length;
1612  const char* payload;
1613
1614  base::StatsCounter compressed_frames("spdy.CompressedFrames");
1615  base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
1616  base::StatsCounter post_compress_bytes("spdy.PostCompressSize");
1617
1618  if (!enable_compression_)
1619    return reinterpret_cast<SpdyControlFrame*>(DuplicateFrame(frame));
1620
1621  if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload))
1622    return NULL;
1623
1624  // Create an output frame.
1625  int compressed_max_size = deflateBound(compressor, payload_length);
1626  // Since we'll be performing lots of flushes when compressing the data,
1627  // zlib's lower bounds may be insufficient.
1628  compressed_max_size *= 2;
1629
1630  size_t new_frame_size = header_length + compressed_max_size;
1631  if ((frame.type() == SYN_REPLY || frame.type() == HEADERS) &&
1632      spdy_version_ < 3) {
1633    new_frame_size += 2;
1634  }
1635  DCHECK_GE(new_frame_size, frame.length() + SpdyFrame::kHeaderSize);
1636  scoped_ptr<SpdyControlFrame> new_frame(new SpdyControlFrame(new_frame_size));
1637  memcpy(new_frame->data(), frame.data(),
1638         frame.length() + SpdyFrame::kHeaderSize);
1639
1640  // TODO(phajdan.jr): Clean up after we no longer need
1641  // to workaround http://crbug.com/139744.
1642#if defined(USE_SYSTEM_ZLIB)
1643  compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
1644  compressor->avail_in = payload_length;
1645#endif  // defined(USE_SYSTEM_ZLIB)
1646  compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) +
1647                          header_length;
1648  compressor->avail_out = compressed_max_size;
1649  // TODO(phajdan.jr): Clean up after we no longer need
1650  // to workaround http://crbug.com/139744.
1651#if defined(USE_SYSTEM_ZLIB)
1652  int rv = deflate(compressor, Z_SYNC_FLUSH);
1653  if (rv != Z_OK) {  // How can we know that it compressed everything?
1654    // This shouldn't happen, right?
1655    LOG(WARNING) << "deflate failure: " << rv;
1656    return NULL;
1657  }
1658#else  // !defined(USE_SYSTEM_ZLIB)
1659  WriteHeaderBlockToZ(headers, compressor);
1660#endif  // !defined(USE_SYSTEM_ZLIB)
1661  int compressed_size = compressed_max_size - compressor->avail_out;
1662
1663  // We trust zlib. Also, we can't do anything about it.
1664  // See http://www.zlib.net/zlib_faq.html#faq36
1665  (void)VALGRIND_MAKE_MEM_DEFINED(new_frame->data() + header_length,
1666                                  compressed_size);
1667
1668  new_frame->set_length(
1669      header_length + compressed_size - SpdyFrame::kHeaderSize);
1670
1671  pre_compress_bytes.Add(payload_length);
1672  post_compress_bytes.Add(new_frame->length());
1673
1674  compressed_frames.Increment();
1675
1676  if (visitor_)
1677    visitor_->OnControlFrameCompressed(frame, *new_frame);
1678
1679  return new_frame.release();
1680}
1681
1682// Incrementally decompress the control frame's header block, feeding the
1683// result to the visitor in chunks. Continue this until the visitor
1684// indicates that it cannot process any more data, or (more commonly) we
1685// run out of data to deliver.
1686bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
1687    const SpdyControlFrame* control_frame,
1688    const char* data,
1689    size_t len) {
1690  // Get a decompressor or set error.
1691  z_stream* decomp = GetHeaderDecompressor();
1692  if (decomp == NULL) {
1693    LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
1694    set_error(SPDY_DECOMPRESS_FAILURE);
1695    return false;
1696  }
1697
1698  bool processed_successfully = true;
1699  char buffer[kHeaderDataChunkMaxSize];
1700
1701  decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
1702  decomp->avail_in = len;
1703  const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1704  DCHECK_LT(0u, stream_id);
1705  while (decomp->avail_in > 0 && processed_successfully) {
1706    decomp->next_out = reinterpret_cast<Bytef*>(buffer);
1707    decomp->avail_out = arraysize(buffer);
1708
1709    int rv = inflate(decomp, Z_SYNC_FLUSH);
1710    if (rv == Z_NEED_DICT) {
1711      const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
1712                                                   : kV3Dictionary;
1713      const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
1714                                                      : kV3DictionarySize;
1715      const DictionaryIds& ids = g_dictionary_ids.Get();
1716      const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id
1717                                                      : ids.v3_dictionary_id;
1718      // Need to try again with the right dictionary.
1719      if (decomp->adler == dictionary_id) {
1720        rv = inflateSetDictionary(decomp,
1721                                  reinterpret_cast<const Bytef*>(dictionary),
1722                                  dictionary_size);
1723        if (rv == Z_OK)
1724          rv = inflate(decomp, Z_SYNC_FLUSH);
1725      }
1726    }
1727
1728    // Inflate will generate a Z_BUF_ERROR if it runs out of input
1729    // without producing any output.  The input is consumed and
1730    // buffered internally by zlib so we can detect this condition by
1731    // checking if avail_in is 0 after the call to inflate.
1732    bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
1733    if ((rv == Z_OK) || input_exhausted) {
1734      size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
1735      if (decompressed_len > 0) {
1736        processed_successfully = visitor_->OnControlFrameHeaderData(
1737            stream_id, buffer, decompressed_len);
1738      }
1739      if (!processed_successfully) {
1740        // Assume that the problem was the header block was too large for the
1741        // visitor.
1742        set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1743      }
1744    } else {
1745      DLOG(WARNING) << "inflate failure: " << rv << " " << len;
1746      set_error(SPDY_DECOMPRESS_FAILURE);
1747      processed_successfully = false;
1748    }
1749  }
1750  return processed_successfully;
1751}
1752
1753bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
1754    const SpdyControlFrame* control_frame, const char* data, size_t len) {
1755  bool read_successfully = true;
1756  const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1757  while (read_successfully && len > 0) {
1758    size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
1759    read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
1760                                                           bytes_to_deliver);
1761    data += bytes_to_deliver;
1762    len -= bytes_to_deliver;
1763    if (!read_successfully) {
1764      // Assume that the problem was the header block was too large for the
1765      // visitor.
1766      set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1767    }
1768  }
1769  return read_successfully;
1770}
1771
1772SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame& frame) {
1773  int size = SpdyFrame::kHeaderSize + frame.length();
1774  SpdyFrame* new_frame = new SpdyFrame(size);
1775  memcpy(new_frame->data(), frame.data(), size);
1776  return new_frame;
1777}
1778
1779bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const {
1780  // The important frames to compress are those which contain large
1781  // amounts of compressible data - namely the headers in the SYN_STREAM
1782  // and SYN_REPLY.
1783  if (frame.is_control_frame()) {
1784    const SpdyControlFrame& control_frame =
1785        reinterpret_cast<const SpdyControlFrame&>(frame);
1786    return control_frame.type() == SYN_STREAM ||
1787        control_frame.type() == SYN_REPLY ||
1788        control_frame.type() == HEADERS;
1789  }
1790
1791  // We don't compress Data frames.
1792  return false;
1793}
1794
1795size_t SpdyFramer::GetMinimumControlFrameSize(int version,
1796                                              SpdyControlType type) {
1797  switch (type) {
1798    case SYN_STREAM:
1799      return SpdySynStreamControlFrame::size();
1800    case SYN_REPLY:
1801      return SpdySynReplyControlFrame::size();
1802    case RST_STREAM:
1803      return SpdyRstStreamControlFrame::size();
1804    case SETTINGS:
1805      return SpdySettingsControlFrame::size();
1806    case NOOP:
1807      // Even though NOOP is no longer supported, we still correctly report its
1808      // size so that it can be handled correctly as incoming data if
1809      // implementations so desire.
1810      return SpdyFrame::kHeaderSize;
1811    case PING:
1812      return SpdyPingControlFrame::size();
1813    case GOAWAY:
1814      if (version < 3) {
1815        // SPDY 2 GOAWAY is smaller by 32 bits. Since
1816        // SpdyGoAwayControlFrame::size() returns the size for SPDY 3, we adjust
1817        // before returning here.
1818        return SpdyGoAwayControlFrame::size() - 4;
1819      } else {
1820        return SpdyGoAwayControlFrame::size();
1821      }
1822    case HEADERS:
1823      return SpdyHeadersControlFrame::size();
1824    case WINDOW_UPDATE:
1825      return SpdyWindowUpdateControlFrame::size();
1826    case CREDENTIAL:
1827      return SpdyCredentialControlFrame::size();
1828    case NUM_CONTROL_FRAME_TYPES:
1829      break;
1830  }
1831  LOG(ERROR) << "Unknown control frame type " << type;
1832  return std::numeric_limits<size_t>::max();
1833}
1834
1835/* static */
1836SpdyStreamId SpdyFramer::GetControlFrameStreamId(
1837    const SpdyControlFrame* control_frame) {
1838  SpdyStreamId stream_id = kInvalidStream;
1839  if (control_frame != NULL) {
1840    switch (control_frame->type()) {
1841      case SYN_STREAM:
1842        stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>(
1843            control_frame)->stream_id();
1844        break;
1845      case SYN_REPLY:
1846        stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>(
1847            control_frame)->stream_id();
1848        break;
1849      case HEADERS:
1850        stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>(
1851            control_frame)->stream_id();
1852        break;
1853      case RST_STREAM:
1854        stream_id = reinterpret_cast<const SpdyRstStreamControlFrame*>(
1855            control_frame)->stream_id();
1856        break;
1857      case WINDOW_UPDATE:
1858        stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame*>(
1859            control_frame)->stream_id();
1860        break;
1861      // All of the following types are not part of a particular stream.
1862      // They all fall through to the invalid control frame type case.
1863      // (The default case isn't used so that the compile will break if a new
1864      // control frame type is added but not included here.)
1865      case SETTINGS:
1866      case NOOP:
1867      case PING:
1868      case GOAWAY:
1869      case CREDENTIAL:
1870      case NUM_CONTROL_FRAME_TYPES:  // makes compiler happy
1871        break;
1872    }
1873  }
1874  return stream_id;
1875}
1876
1877void SpdyFramer::set_enable_compression(bool value) {
1878  enable_compression_ = value;
1879}
1880
1881}  // namespace net
1882