diff --git a/src/net/spdy/buffered_spdy_framer.cc b/src/net/spdy/buffered_spdy_framer.cc
new file mode 100644
index 0000000..50a0d93
--- /dev/null
+++ b/src/net/spdy/buffered_spdy_framer.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/buffered_spdy_framer.h"
+
+#include "base/logging.h"
+
+namespace net {
+
+BufferedSpdyFramer::BufferedSpdyFramer(int version, bool enable_compression)
+    : spdy_framer_(version),
+      visitor_(NULL),
+      header_buffer_used_(0),
+      header_buffer_valid_(false),
+      header_stream_id_(SpdyFramer::kInvalidStream),
+      frames_received_(0) {
+  spdy_framer_.set_enable_compression(enable_compression);
+  memset(header_buffer_, 0, sizeof(header_buffer_));
+}
+
+BufferedSpdyFramer::~BufferedSpdyFramer() {
+}
+
+void BufferedSpdyFramer::set_visitor(
+    BufferedSpdyFramerVisitorInterface* visitor) {
+  visitor_ = visitor;
+  spdy_framer_.set_visitor(this);
+}
+
+void BufferedSpdyFramer::OnError(SpdyFramer* spdy_framer) {
+  DCHECK(spdy_framer);
+  visitor_->OnError(spdy_framer->error_code());
+}
+
+void BufferedSpdyFramer::OnSynStream(SpdyStreamId stream_id,
+                                     SpdyStreamId associated_stream_id,
+                                     SpdyPriority priority,
+                                     uint8 credential_slot,
+                                     bool fin,
+                                     bool unidirectional) {
+  frames_received_++;
+  DCHECK(!control_frame_fields_.get());
+  control_frame_fields_.reset(new ControlFrameFields());
+  control_frame_fields_->type = SYN_STREAM;
+  control_frame_fields_->stream_id = stream_id;
+  control_frame_fields_->associated_stream_id = associated_stream_id;
+  control_frame_fields_->priority = priority;
+  control_frame_fields_->credential_slot = credential_slot;
+  control_frame_fields_->fin = fin;
+  control_frame_fields_->unidirectional = unidirectional;
+
+  InitHeaderStreaming(stream_id);
+}
+
+void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id,
+                                   bool fin) {
+  frames_received_++;
+  DCHECK(!control_frame_fields_.get());
+  control_frame_fields_.reset(new ControlFrameFields());
+  control_frame_fields_->type = HEADERS;
+  control_frame_fields_->stream_id = stream_id;
+  control_frame_fields_->fin = fin;
+
+  InitHeaderStreaming(stream_id);
+}
+
+void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id,
+                                    bool fin) {
+  frames_received_++;
+  DCHECK(!control_frame_fields_.get());
+  control_frame_fields_.reset(new ControlFrameFields());
+  control_frame_fields_->type = SYN_REPLY;
+  control_frame_fields_->stream_id = stream_id;
+  control_frame_fields_->fin = fin;
+
+  InitHeaderStreaming(stream_id);
+}
+
+bool BufferedSpdyFramer::OnCredentialFrameData(const char* frame_data,
+                                               size_t len) {
+  DCHECK(false);
+  return false;
+}
+
+bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
+                                                  const char* header_data,
+                                                  size_t len) {
+  CHECK_EQ(header_stream_id_, stream_id);
+
+  if (len == 0) {
+    // Indicates end-of-header-block.
+    CHECK(header_buffer_valid_);
+
+    SpdyHeaderBlock headers;
+    bool parsed_headers = spdy_framer_.ParseHeaderBlockInBuffer(
+        header_buffer_, header_buffer_used_, &headers);
+    if (!parsed_headers) {
+      visitor_->OnStreamError(
+          stream_id, "Could not parse Spdy Control Frame Header.");
+      return false;
+    }
+    DCHECK(control_frame_fields_.get());
+    switch (control_frame_fields_->type) {
+      case SYN_STREAM:
+        visitor_->OnSynStream(control_frame_fields_->stream_id,
+                              control_frame_fields_->associated_stream_id,
+                              control_frame_fields_->priority,
+                              control_frame_fields_->credential_slot,
+                              control_frame_fields_->fin,
+                              control_frame_fields_->unidirectional,
+                              headers);
+        break;
+      case SYN_REPLY:
+        visitor_->OnSynReply(control_frame_fields_->stream_id,
+                             control_frame_fields_->fin,
+                             headers);
+        break;
+      case HEADERS:
+        visitor_->OnHeaders(control_frame_fields_->stream_id,
+                            control_frame_fields_->fin,
+                            headers);
+        break;
+      default:
+        DCHECK(false) << "Unexpect control frame type: "
+                      << control_frame_fields_->type;
+        break;
+    }
+    control_frame_fields_.reset(NULL);
+    return true;
+  }
+
+  const size_t available = kHeaderBufferSize - header_buffer_used_;
+  if (len > available) {
+    header_buffer_valid_ = false;
+    visitor_->OnStreamError(
+        stream_id, "Received more data than the allocated size.");
+    return false;
+  }
+  memcpy(header_buffer_ + header_buffer_used_, header_data, len);
+  header_buffer_used_ += len;
+  return true;
+}
+
+void BufferedSpdyFramer::OnDataFrameHeader(const SpdyDataFrame* frame) {
+  frames_received_++;
+  header_stream_id_ = frame->stream_id();
+}
+
+void BufferedSpdyFramer::OnStreamFrameData(SpdyStreamId stream_id,
+                                           const char* data,
+                                           size_t len,
+                                           SpdyDataFlags flags) {
+  visitor_->OnStreamFrameData(stream_id, data, len, flags);
+}
+
+void BufferedSpdyFramer::OnSetting(SpdySettingsIds id,
+                                   uint8 flags,
+                                   uint32 value) {
+  visitor_->OnSetting(id, flags, value);
+}
+
+void BufferedSpdyFramer::OnPing(uint32 unique_id) {
+  visitor_->OnPing(unique_id);
+}
+
+void BufferedSpdyFramer::OnRstStream(SpdyStreamId stream_id,
+                                     SpdyStatusCodes status) {
+  visitor_->OnRstStream(stream_id, status);
+}
+void BufferedSpdyFramer::OnGoAway(SpdyStreamId last_accepted_stream_id,
+                                  SpdyGoAwayStatus status) {
+  visitor_->OnGoAway(last_accepted_stream_id, status);
+}
+
+void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id,
+                                        int delta_window_size) {
+  visitor_->OnWindowUpdate(stream_id, delta_window_size);
+}
+
+void BufferedSpdyFramer::OnControlFrameCompressed(
+    const SpdyControlFrame& uncompressed_frame,
+    const SpdyControlFrame& compressed_frame) {
+  visitor_->OnControlFrameCompressed(uncompressed_frame, compressed_frame);
+}
+
+
+int BufferedSpdyFramer::protocol_version() {
+  return spdy_framer_.protocol_version();
+}
+
+size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) {
+  return spdy_framer_.ProcessInput(data, len);
+}
+
+void BufferedSpdyFramer::Reset() {
+  spdy_framer_.Reset();
+}
+
+SpdyFramer::SpdyError BufferedSpdyFramer::error_code() const {
+  return spdy_framer_.error_code();
+}
+
+SpdyFramer::SpdyState BufferedSpdyFramer::state() const {
+  return spdy_framer_.state();
+}
+
+bool BufferedSpdyFramer::MessageFullyRead() {
+  return spdy_framer_.MessageFullyRead();
+}
+
+bool BufferedSpdyFramer::HasError() {
+  return spdy_framer_.HasError();
+}
+
+SpdySynStreamControlFrame* BufferedSpdyFramer::CreateSynStream(
+    SpdyStreamId stream_id,
+    SpdyStreamId associated_stream_id,
+    SpdyPriority priority,
+    uint8 credential_slot,
+    SpdyControlFlags flags,
+    bool compressed,
+    const SpdyHeaderBlock* headers) {
+  return spdy_framer_.CreateSynStream(stream_id, associated_stream_id, priority,
+                                      credential_slot, flags, compressed,
+                                      headers);
+}
+
+SpdySynReplyControlFrame* BufferedSpdyFramer::CreateSynReply(
+    SpdyStreamId stream_id,
+    SpdyControlFlags flags,
+    bool compressed,
+    const SpdyHeaderBlock* headers) {
+  return spdy_framer_.CreateSynReply(stream_id, flags, compressed, headers);
+}
+
+SpdyRstStreamControlFrame* BufferedSpdyFramer::CreateRstStream(
+    SpdyStreamId stream_id,
+    SpdyStatusCodes status) const {
+  return spdy_framer_.CreateRstStream(stream_id, status);
+}
+
+SpdySettingsControlFrame* BufferedSpdyFramer::CreateSettings(
+    const SettingsMap& values) const {
+  return spdy_framer_.CreateSettings(values);
+}
+
+SpdyPingControlFrame* BufferedSpdyFramer::CreatePingFrame(
+    uint32 unique_id) const {
+  return spdy_framer_.CreatePingFrame(unique_id);
+}
+
+SpdyGoAwayControlFrame* BufferedSpdyFramer::CreateGoAway(
+    SpdyStreamId last_accepted_stream_id,
+    SpdyGoAwayStatus status) const {
+  return spdy_framer_.CreateGoAway(last_accepted_stream_id, status);
+}
+
+SpdyHeadersControlFrame* BufferedSpdyFramer::CreateHeaders(
+    SpdyStreamId stream_id,
+    SpdyControlFlags flags,
+    bool compressed,
+    const SpdyHeaderBlock* headers) {
+  return spdy_framer_.CreateHeaders(stream_id, flags, compressed, headers);
+}
+
+SpdyWindowUpdateControlFrame* BufferedSpdyFramer::CreateWindowUpdate(
+    SpdyStreamId stream_id,
+    uint32 delta_window_size) const {
+  return spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size);
+}
+
+SpdyCredentialControlFrame* BufferedSpdyFramer::CreateCredentialFrame(
+    const SpdyCredential& credential) const {
+  return spdy_framer_.CreateCredentialFrame(credential);
+}
+
+SpdyDataFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
+                                                   const char* data,
+                                                   uint32 len,
+                                                   SpdyDataFlags flags) {
+  return spdy_framer_.CreateDataFrame(stream_id, data, len, flags);
+}
+
+SpdyPriority BufferedSpdyFramer::GetHighestPriority() const {
+  return spdy_framer_.GetHighestPriority();
+}
+
+bool BufferedSpdyFramer::IsCompressible(const SpdyFrame& frame) const {
+  return spdy_framer_.IsCompressible(frame);
+}
+
+void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) {
+  memset(header_buffer_, 0, kHeaderBufferSize);
+  header_buffer_used_ = 0;
+  header_buffer_valid_ = true;
+  header_stream_id_ = stream_id;
+  DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/buffered_spdy_framer.h b/src/net/spdy/buffered_spdy_framer.h
new file mode 100644
index 0000000..ea64151
--- /dev/null
+++ b/src/net/spdy/buffered_spdy_framer.h
@@ -0,0 +1,219 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_BUFFERED_SPDY_FRAMER_H_
+#define NET_SPDY_BUFFERED_SPDY_FRAMER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+#include "net/spdy/spdy_framer.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_protocol.h"
+
+namespace net {
+
+class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
+ public:
+  BufferedSpdyFramerVisitorInterface() {}
+
+  // Called if an error is detected in the SpdyFrame protocol.
+  virtual void OnError(SpdyFramer::SpdyError error_code) = 0;
+
+  // Called if an error is detected in a SPDY stream.
+  virtual void OnStreamError(SpdyStreamId stream_id,
+                             const std::string& description) = 0;
+
+  // Called after all the header data for SYN_STREAM control frame is received.
+  virtual void OnSynStream(SpdyStreamId stream_id,
+                           SpdyStreamId associated_stream_id,
+                           SpdyPriority priority,
+                           uint8 credential_slot,
+                           bool fin,
+                           bool unidirectional,
+                           const SpdyHeaderBlock& headers) = 0;
+
+  // Called after all the header data for SYN_REPLY control frame is received.
+  virtual void OnSynReply(SpdyStreamId stream_id,
+                          bool fin,
+                          const SpdyHeaderBlock& headers) = 0;
+
+  // Called after all the header data for HEADERS control frame is received.
+  virtual void OnHeaders(SpdyStreamId stream_id,
+                         bool fin,
+                         const SpdyHeaderBlock& headers) = 0;
+
+  // Called when data is received.
+  // |stream_id| The stream receiving data.
+  // |data| A buffer containing the data received.
+  // |len| The length of the data buffer.
+  // When the other side has finished sending data on this stream,
+  // this method will be called with a zero-length buffer.
+  virtual void OnStreamFrameData(SpdyStreamId stream_id,
+                                 const char* data,
+                                 size_t len,
+                                 SpdyDataFlags flags) = 0;
+
+  // Called when an individual setting within a SETTINGS frame has been parsed
+  // and validated.
+  virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
+
+  // Called when a PING frame has been parsed.
+  virtual void OnPing(uint32 unique_id) = 0;
+
+  // Called when a RST_STREAM frame has been parsed.
+  virtual void OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) = 0;
+
+  // Called when a GOAWAY frame has been parsed.
+  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                        SpdyGoAwayStatus status) = 0;
+
+  // Called when a WINDOW_UPDATE frame has been parsed.
+  virtual void OnWindowUpdate(SpdyStreamId stream_id,
+                              int delta_window_size) = 0;
+
+  // Called after a control frame has been compressed to allow the visitor
+  // to record compression statistics.
+  virtual void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) = 0;
+
+ protected:
+  virtual ~BufferedSpdyFramerVisitorInterface() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface);
+};
+
+class NET_EXPORT_PRIVATE BufferedSpdyFramer
+    : public SpdyFramerVisitorInterface {
+ public:
+  BufferedSpdyFramer(int version,
+                     bool enable_compression);
+  virtual ~BufferedSpdyFramer();
+
+  // Sets callbacks to be called from the buffered spdy framer.  A visitor must
+  // be set, or else the framer will likely crash.  It is acceptable for the
+  // visitor to do nothing.  If this is called multiple times, only the last
+  // visitor will be used.
+  void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);
+
+  // SpdyFramerVisitorInterface
+  virtual void OnError(SpdyFramer* spdy_framer) OVERRIDE;
+  virtual void OnSynStream(SpdyStreamId stream_id,
+                           SpdyStreamId associated_stream_id,
+                           SpdyPriority priority,
+                           uint8 credential_slot,
+                           bool fin,
+                           bool unidirectional) OVERRIDE;
+  virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE;
+  virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE;
+  virtual bool OnCredentialFrameData(const char* frame_data,
+                                     size_t len) OVERRIDE;
+  virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
+                                        const char* header_data,
+                                        size_t len) OVERRIDE;
+  virtual void OnStreamFrameData(SpdyStreamId stream_id,
+                                 const char* data,
+                                 size_t len,
+                                 SpdyDataFlags flags) OVERRIDE;
+  virtual void OnSetting(
+      SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE;
+  virtual void OnPing(uint32 unique_id) OVERRIDE;
+  virtual void OnRstStream(SpdyStreamId stream_id,
+                           SpdyStatusCodes status) OVERRIDE;
+  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                        SpdyGoAwayStatus status) OVERRIDE;
+  virtual void OnWindowUpdate(SpdyStreamId stream_id,
+                              int delta_window_size) OVERRIDE;
+  virtual void OnDataFrameHeader(const SpdyDataFrame* frame) OVERRIDE;
+
+  // Called after a control frame has been compressed to allow the visitor
+  // to record compression statistics.
+  virtual void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) OVERRIDE;
+
+  // SpdyFramer methods.
+  size_t ProcessInput(const char* data, size_t len);
+  int protocol_version();
+  void Reset();
+  SpdyFramer::SpdyError error_code() const;
+  SpdyFramer::SpdyState state() const;
+  bool MessageFullyRead();
+  bool HasError();
+  SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id,
+                                             SpdyStreamId associated_stream_id,
+                                             SpdyPriority priority,
+                                             uint8 credential_slot,
+                                             SpdyControlFlags flags,
+                                             bool compressed,
+                                             const SpdyHeaderBlock* headers);
+  SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id,
+                                           SpdyControlFlags flags,
+                                           bool compressed,
+                                           const SpdyHeaderBlock* headers);
+  SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id,
+                                             SpdyStatusCodes status) const;
+  SpdySettingsControlFrame* CreateSettings(const SettingsMap& values) const;
+  SpdyPingControlFrame* CreatePingFrame(uint32 unique_id) const;
+  SpdyGoAwayControlFrame* CreateGoAway(
+      SpdyStreamId last_accepted_stream_id,
+      SpdyGoAwayStatus status) const;
+  SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id,
+                                         SpdyControlFlags flags,
+                                         bool compressed,
+                                         const SpdyHeaderBlock* headers);
+  SpdyWindowUpdateControlFrame* CreateWindowUpdate(
+      SpdyStreamId stream_id,
+      uint32 delta_window_size) const;
+  SpdyCredentialControlFrame* CreateCredentialFrame(
+      const SpdyCredential& credential) const;
+  SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id,
+                                 const char* data,
+                                 uint32 len,
+                                 SpdyDataFlags flags);
+  SpdyPriority GetHighestPriority() const;
+  bool IsCompressible(const SpdyFrame& frame) const;
+
+  int frames_received() const { return frames_received_; }
+
+ private:
+  // The size of the header_buffer_.
+  enum { kHeaderBufferSize = 32 * 1024 };
+
+  void InitHeaderStreaming(SpdyStreamId stream_id);
+
+  SpdyFramer spdy_framer_;
+  BufferedSpdyFramerVisitorInterface* visitor_;
+
+  // Header block streaming state:
+  char header_buffer_[kHeaderBufferSize];
+  size_t header_buffer_used_;
+  bool header_buffer_valid_;
+  SpdyStreamId header_stream_id_;
+  int frames_received_;
+
+  // Collection of fields from control frames that we need to
+  // buffer up from the spdy framer.
+  struct ControlFrameFields {
+    SpdyControlType type;
+    SpdyStreamId stream_id;
+    SpdyStreamId associated_stream_id;
+    SpdyPriority priority;
+    uint8 credential_slot;
+    bool fin;
+    bool unidirectional;
+  };
+  scoped_ptr<ControlFrameFields> control_frame_fields_;
+
+  DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
diff --git a/src/net/spdy/buffered_spdy_framer_spdy2_unittest.cc b/src/net/spdy/buffered_spdy_framer_spdy2_unittest.cc
new file mode 100644
index 0000000..4bbdf6e
--- /dev/null
+++ b/src/net/spdy/buffered_spdy_framer_spdy2_unittest.cc
@@ -0,0 +1,268 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/buffered_spdy_framer.h"
+
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy2;
+
+namespace net {
+
+namespace {
+
+class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
+ public:
+  TestBufferedSpdyVisitor()
+      : buffered_spdy_framer_(2, true),
+        error_count_(0),
+        setting_count_(0),
+        syn_frame_count_(0),
+        syn_reply_frame_count_(0),
+        headers_frame_count_(0),
+        header_stream_id_(-1) {
+  }
+
+  void OnError(SpdyFramer::SpdyError error_code) {
+    LOG(INFO) << "SpdyFramer Error: " << error_code;
+    error_count_++;
+  }
+
+  void OnStreamError(SpdyStreamId stream_id,
+                     const std::string& description) {
+    LOG(INFO) << "SpdyFramer Error on stream: " << stream_id  << " "
+              << description;
+    error_count_++;
+  }
+
+  void OnSynStream(SpdyStreamId stream_id,
+                   SpdyStreamId associated_stream_id,
+                   SpdyPriority priority,
+                   uint8 credential_slot,
+                   bool fin,
+                   bool unidirectional,
+                   const SpdyHeaderBlock& headers) {
+    header_stream_id_ = stream_id;
+    EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+    syn_frame_count_++;
+    headers_ = headers;
+  }
+
+  void OnSynReply(SpdyStreamId stream_id,
+                  bool fin,
+                  const SpdyHeaderBlock& headers) {
+    header_stream_id_ = stream_id;
+    EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+    syn_reply_frame_count_++;
+    headers_ = headers;
+  }
+
+  void OnHeaders(SpdyStreamId stream_id,
+                 bool fin,
+                 const SpdyHeaderBlock& headers) {
+    header_stream_id_ = stream_id;
+    EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+    headers_frame_count_++;
+    headers_ = headers;
+  }
+
+  void OnStreamFrameData(SpdyStreamId stream_id,
+                         const char* data,
+                         size_t len,
+                         SpdyDataFlags flags) {
+    LOG(FATAL) << "Unexpected OnStreamFrameData call.";
+  }
+
+  void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
+    setting_count_++;
+  }
+
+  void OnPing(uint32 unique_id) {}
+
+  void OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) {}
+
+  void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                SpdyGoAwayStatus status) {}
+
+  void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) {
+  }
+
+  bool OnCredentialFrameData(const char*, size_t) {
+    LOG(FATAL) << "Unexpected OnCredentialFrameData call.";
+    return false;
+  }
+
+  void OnDataFrameHeader(const SpdyDataFrame* frame) {
+    LOG(FATAL) << "Unexpected OnDataFrameHeader call.";
+  }
+
+  void OnRstStream(const SpdyRstStreamControlFrame& frame) {}
+  void OnGoAway(const SpdyGoAwayControlFrame& frame) {}
+  void OnPing(const SpdyPingControlFrame& frame) {}
+  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) {}
+  void OnCredential(const SpdyCredentialControlFrame& frame) {}
+
+  // Convenience function which runs a framer simulation with particular input.
+  void SimulateInFramer(const unsigned char* input, size_t size) {
+    buffered_spdy_framer_.set_visitor(this);
+    size_t input_remaining = size;
+    const char* input_ptr = reinterpret_cast<const char*>(input);
+    while (input_remaining > 0 &&
+           buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) {
+      // To make the tests more interesting, we feed random (amd small) chunks
+      // into the framer.  This simulates getting strange-sized reads from
+      // the socket.
+      const size_t kMaxReadSize = 32;
+      size_t bytes_read =
+          (rand() % std::min(input_remaining, kMaxReadSize)) + 1;
+      size_t bytes_processed =
+          buffered_spdy_framer_.ProcessInput(input_ptr, bytes_read);
+      input_remaining -= bytes_processed;
+      input_ptr += bytes_processed;
+      if (buffered_spdy_framer_.state() == SpdyFramer::SPDY_DONE)
+        buffered_spdy_framer_.Reset();
+    }
+  }
+
+  BufferedSpdyFramer buffered_spdy_framer_;
+
+  // Counters from the visitor callbacks.
+  int error_count_;
+  int setting_count_;
+  int syn_frame_count_;
+  int syn_reply_frame_count_;
+  int headers_frame_count_;
+
+  // Header block streaming state:
+  SpdyStreamId header_stream_id_;
+
+  // Headers from OnSyn, OnSynReply and OnHeaders for verification.
+  SpdyHeaderBlock headers_;
+};
+
+}  // namespace
+
+class BufferedSpdyFramerSpdy2Test : public PlatformTest {
+ protected:
+  // Returns true if the two header blocks have equivalent content.
+  bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
+                           const SpdyHeaderBlock* actual) {
+    if (expected->size() != actual->size()) {
+      LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
+                 << actual->size() << ".";
+      return false;
+    }
+    for (SpdyHeaderBlock::const_iterator it = expected->begin();
+         it != expected->end();
+         ++it) {
+      SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
+      if (it2 == actual->end()) {
+        LOG(ERROR) << "Expected header name '" << it->first << "'.";
+        return false;
+      }
+      if (it->second.compare(it2->second) != 0) {
+        LOG(ERROR) << "Expected header named '" << it->first
+                   << "' to have a value of '" << it->second
+                   << "'. The actual value received was '" << it2->second
+                   << "'.";
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+TEST_F(BufferedSpdyFramerSpdy2Test, OnSetting) {
+  SpdyFramer framer(2);
+  SettingsMap settings;
+  settings[SETTINGS_UPLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0x00000002);
+  settings[SETTINGS_DOWNLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0x00000003);
+
+  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+  TestBufferedSpdyVisitor visitor;
+
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.setting_count_);
+}
+
+TEST_F(BufferedSpdyFramerSpdy2Test, ReadSynStreamHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["aa"] = "vv";
+  headers["bb"] = "ww";
+  BufferedSpdyFramer framer(2, true);
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                        // stream_id
+                             0,                        // associated_stream_id
+                             1,                        // priority
+                             0,                        // credential_slot
+                             CONTROL_FLAG_NONE,
+                             true,                     // compress
+                             &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+
+  TestBufferedSpdyVisitor visitor;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.get()->data()),
+      control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_F(BufferedSpdyFramerSpdy2Test, ReadSynReplyHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  BufferedSpdyFramer framer(2, true);
+  scoped_ptr<SpdySynReplyControlFrame> control_frame(
+      framer.CreateSynReply(1,                        // stream_id
+                            CONTROL_FLAG_NONE,
+                            true,                     // compress
+                            &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+
+  TestBufferedSpdyVisitor visitor;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.get()->data()),
+       control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(0, visitor.syn_frame_count_);
+  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_F(BufferedSpdyFramerSpdy2Test, ReadHeadersHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  BufferedSpdyFramer framer(2, true);
+  scoped_ptr<SpdyHeadersControlFrame> control_frame(
+      framer.CreateHeaders(1,                        // stream_id
+                           CONTROL_FLAG_NONE,
+                           true,                    // compress
+                           &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+
+  TestBufferedSpdyVisitor visitor;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.get()->data()),
+       control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(0, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+}  // namespace net
diff --git a/src/net/spdy/buffered_spdy_framer_spdy3_unittest.cc b/src/net/spdy/buffered_spdy_framer_spdy3_unittest.cc
new file mode 100644
index 0000000..ca9edf3
--- /dev/null
+++ b/src/net/spdy/buffered_spdy_framer_spdy3_unittest.cc
@@ -0,0 +1,269 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/buffered_spdy_framer.h"
+
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy3;
+
+namespace net {
+
+namespace {
+
+class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
+ public:
+  TestBufferedSpdyVisitor()
+      : buffered_spdy_framer_(3, true),
+        error_count_(0),
+        setting_count_(0),
+        syn_frame_count_(0),
+        syn_reply_frame_count_(0),
+        headers_frame_count_(0),
+        header_stream_id_(-1) {
+  }
+
+  void OnError(SpdyFramer::SpdyError error_code) {
+    LOG(INFO) << "SpdyFramer Error: " << error_code;
+    error_count_++;
+  }
+
+  void OnStreamError(SpdyStreamId stream_id,
+                     const std::string& description) {
+    LOG(INFO) << "SpdyFramer Error on stream: " << stream_id  << " "
+              << description;
+    error_count_++;
+  }
+
+  void OnSynStream(SpdyStreamId stream_id,
+                   SpdyStreamId associated_stream_id,
+                   SpdyPriority priority,
+                   uint8 credential_slot,
+                   bool fin,
+                   bool unidirectional,
+                   const SpdyHeaderBlock& headers) {
+    header_stream_id_ = stream_id;
+    EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+    syn_frame_count_++;
+    headers_ = headers;
+  }
+
+  void OnSynReply(SpdyStreamId stream_id,
+                  bool fin,
+                  const SpdyHeaderBlock& headers) {
+    header_stream_id_ = stream_id;
+    EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+    syn_reply_frame_count_++;
+    headers_ = headers;
+  }
+
+  void OnHeaders(SpdyStreamId stream_id,
+                 bool fin,
+                 const SpdyHeaderBlock& headers) {
+    header_stream_id_ = stream_id;
+    EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+    headers_frame_count_++;
+    headers_ = headers;
+  }
+
+  void OnStreamFrameData(SpdyStreamId stream_id,
+                         const char* data,
+                         size_t len,
+                         SpdyDataFlags flags) {
+    LOG(FATAL) << "Unexpected OnStreamFrameData call.";
+  }
+
+  void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
+    setting_count_++;
+  }
+
+  void OnPing(uint32 unique_id) {}
+
+  void OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) {}
+
+  void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                SpdyGoAwayStatus status) {}
+
+  void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) {
+  }
+
+  bool OnCredentialFrameData(const char*, size_t) {
+    LOG(FATAL) << "Unexpected OnCredentialFrameData call.";
+    return false;
+  }
+
+  void OnDataFrameHeader(const SpdyDataFrame* frame) {
+    LOG(FATAL) << "Unexpected OnDataFrameHeader call.";
+  }
+
+  void OnRstStream(const SpdyRstStreamControlFrame& frame) {}
+  void OnGoAway(const SpdyGoAwayControlFrame& frame) {}
+  void OnPing(const SpdyPingControlFrame& frame) {}
+  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) {}
+  void OnCredential(const SpdyCredentialControlFrame& frame) {}
+
+  // Convenience function which runs a framer simulation with particular input.
+  void SimulateInFramer(const unsigned char* input, size_t size) {
+    buffered_spdy_framer_.set_visitor(this);
+    size_t input_remaining = size;
+    const char* input_ptr = reinterpret_cast<const char*>(input);
+    while (input_remaining > 0 &&
+           buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) {
+      // To make the tests more interesting, we feed random (amd small) chunks
+      // into the framer.  This simulates getting strange-sized reads from
+      // the socket.
+      const size_t kMaxReadSize = 32;
+      size_t bytes_read =
+          (rand() % std::min(input_remaining, kMaxReadSize)) + 1;
+      size_t bytes_processed =
+          buffered_spdy_framer_.ProcessInput(input_ptr, bytes_read);
+      input_remaining -= bytes_processed;
+      input_ptr += bytes_processed;
+      if (buffered_spdy_framer_.state() == SpdyFramer::SPDY_DONE)
+        buffered_spdy_framer_.Reset();
+    }
+  }
+
+  BufferedSpdyFramer buffered_spdy_framer_;
+
+  // Counters from the visitor callbacks.
+  int error_count_;
+  int setting_count_;
+  int syn_frame_count_;
+  int syn_reply_frame_count_;
+  int headers_frame_count_;
+
+  // Header block streaming state:
+  SpdyStreamId header_stream_id_;
+
+  // Headers from OnSyn, OnSynReply and OnHeaders for verification.
+  SpdyHeaderBlock headers_;
+};
+
+}  // namespace
+
+class BufferedSpdyFramerSpdy3Test : public PlatformTest {
+ protected:
+  // Returns true if the two header blocks have equivalent content.
+  bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
+                           const SpdyHeaderBlock* actual) {
+    if (expected->size() != actual->size()) {
+      LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
+                 << actual->size() << ".";
+      return false;
+    }
+    for (SpdyHeaderBlock::const_iterator it = expected->begin();
+         it != expected->end();
+         ++it) {
+      SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
+      if (it2 == actual->end()) {
+        LOG(ERROR) << "Expected header name '" << it->first << "'.";
+        return false;
+      }
+      if (it->second.compare(it2->second) != 0) {
+        LOG(ERROR) << "Expected header named '" << it->first
+                   << "' to have a value of '" << it->second
+                   << "'. The actual value received was '" << it2->second
+                   << "'.";
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+TEST_F(BufferedSpdyFramerSpdy3Test, OnSetting) {
+  SpdyFramer framer(3);
+  framer.set_enable_compression(false);
+  SettingsMap settings;
+  settings[SETTINGS_UPLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0x00000002);
+  settings[SETTINGS_DOWNLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0x00000003);
+
+  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+  TestBufferedSpdyVisitor visitor;
+
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.setting_count_);
+}
+
+TEST_F(BufferedSpdyFramerSpdy3Test, ReadSynStreamHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["aa"] = "vv";
+  headers["bb"] = "ww";
+  BufferedSpdyFramer framer(3, true);
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                        // stream_id
+                             0,                        // associated_stream_id
+                             1,                        // priority
+                             0,                        // credential_slot
+                             CONTROL_FLAG_NONE,
+                             true,                     // compress
+                             &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+
+  TestBufferedSpdyVisitor visitor;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.get()->data()),
+      control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_F(BufferedSpdyFramerSpdy3Test, ReadSynReplyHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  BufferedSpdyFramer framer(3, true);
+  scoped_ptr<SpdySynReplyControlFrame> control_frame(
+      framer.CreateSynReply(1,                        // stream_id
+                            CONTROL_FLAG_NONE,
+                            true,                     // compress
+                            &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+
+  TestBufferedSpdyVisitor visitor;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.get()->data()),
+       control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(0, visitor.syn_frame_count_);
+  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_F(BufferedSpdyFramerSpdy3Test, ReadHeadersHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  BufferedSpdyFramer framer(3, true);
+  scoped_ptr<SpdyHeadersControlFrame> control_frame(
+      framer.CreateHeaders(1,                        // stream_id
+                           CONTROL_FLAG_NONE,
+                           true,                    // compress
+                           &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+
+  TestBufferedSpdyVisitor visitor;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.get()->data()),
+       control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(0, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+}  // namespace net
diff --git a/src/net/spdy/spdy_bitmasks.h b/src/net/spdy/spdy_bitmasks.h
new file mode 100644
index 0000000..72fb948
--- /dev/null
+++ b/src/net/spdy/spdy_bitmasks.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_BITMASKS_H_
+#define NET_SPDY_SPDY_BITMASKS_H_
+
+namespace net {
+
+// StreamId mask from the SpdyHeader
+const unsigned int kStreamIdMask = 0x7fffffff;
+
+// Control flag mask from the SpdyHeader
+const unsigned int kControlFlagMask = 0x8000;
+
+// Priority mask from the SYN_FRAME
+const unsigned int kSpdy3PriorityMask = 0xe0;
+const unsigned int kSpdy2PriorityMask = 0xc0;
+
+// Mask the lower 24 bits.
+const unsigned int kLengthMask = 0xffffff;
+
+// Legal flags on data packets.
+const int kDataFlagsMask = 0x01;
+
+// Legal flags on control packets.
+const int kControlFlagsMask = 0x03;
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_BITMASKS_H_
diff --git a/src/net/spdy/spdy_credential_builder.cc b/src/net/spdy/spdy_credential_builder.cc
new file mode 100644
index 0000000..8ddda97
--- /dev/null
+++ b/src/net/spdy/spdy_credential_builder.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_credential_builder.h"
+
+#include "base/logging.h"
+#include "base/string_piece.h"
+#include "crypto/ec_private_key.h"
+#include "crypto/ec_signature_creator.h"
+#include "net/base/asn1_util.h"
+#include "net/base/server_bound_cert_service.h"
+#include "net/base/net_errors.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/spdy/spdy_framer.h"
+
+namespace net {
+
+namespace {
+
+std::vector<uint8> ToVector(base::StringPiece piece) {
+  return std::vector<uint8>(piece.data(), piece.data() + piece.length());
+}
+
+}  // namespace
+
+// static
+int SpdyCredentialBuilder::Build(const std::string& tls_unique,
+                                 SSLClientCertType type,
+                                 const std::string& key,
+                                 const std::string& cert,
+                                 size_t slot,
+                                 SpdyCredential* credential) {
+  if (type != CLIENT_CERT_ECDSA_SIGN)
+    return ERR_BAD_SSL_CLIENT_AUTH_CERT;
+
+  std::string secret = SpdyCredentialBuilder::GetCredentialSecret(tls_unique);
+
+  // Extract the SubjectPublicKeyInfo from the certificate.
+  base::StringPiece public_key_info;
+  if(!asn1::ExtractSPKIFromDERCert(cert, &public_key_info))
+    return ERR_BAD_SSL_CLIENT_AUTH_CERT;
+
+  // Next, extract the SubjectPublicKey data, which will actually
+  // be stored in the cert field of the credential frame.
+  base::StringPiece public_key;
+  if (!asn1::ExtractSubjectPublicKeyFromSPKI(public_key_info, &public_key))
+    return ERR_BAD_SSL_CLIENT_AUTH_CERT;
+  // Drop one byte of padding bits count from the BIT STRING
+  // (this will always be zero).  Drop one byte of X9.62 format specification
+  // (this will always be 4 to indicated an uncompressed point).
+  DCHECK_GT(public_key.length(), 2u);
+  DCHECK_EQ(0, static_cast<int>(public_key[0]));
+  DCHECK_EQ(4, static_cast<int>(public_key[1]));
+  public_key = public_key.substr(2, public_key.length());
+
+  // Convert the strings into a vector<unit8>
+  std::vector<uint8> der_signature;
+  scoped_ptr<crypto::ECPrivateKey> private_key(
+      crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
+          ServerBoundCertService::kEPKIPassword,
+          ToVector(key), ToVector(public_key_info)));
+  scoped_ptr<crypto::ECSignatureCreator> creator(
+      crypto::ECSignatureCreator::Create(private_key.get()));
+  creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()),
+                secret.length(), &der_signature);
+
+  std::vector<uint8> proof_vector;
+  if (!creator->DecodeSignature(der_signature, &proof_vector)) {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  credential->slot = slot;
+  credential->certs.push_back(public_key.as_string());
+  credential->proof.assign(proof_vector.begin(), proof_vector.end());
+  return OK;
+}
+
+// static
+std::string SpdyCredentialBuilder::GetCredentialSecret(
+    const std::string& tls_unique) {
+  const char prefix[] = "SPDY CREDENTIAL ChannelID\0client -> server";
+  std::string secret(prefix, arraysize(prefix));
+  secret.append(tls_unique);
+
+  return secret;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_credential_builder.h b/src/net/spdy/spdy_credential_builder.h
new file mode 100644
index 0000000..278d239
--- /dev/null
+++ b/src/net/spdy/spdy_credential_builder.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_CREDENTIAL_BUILDER_H_
+#define NET_SPDY_SPDY_CREDENTIAL_BUILDER_H_
+
+#include <string>
+
+#include "net/base/net_export.h"
+#include "net/base/ssl_client_cert_type.h"
+
+namespace net {
+
+class SSLClientSocket;
+struct SpdyCredential;
+
+// This class provides facilities for building the various fields of
+// SPDY CREDENTIAL frames.
+class NET_EXPORT_PRIVATE SpdyCredentialBuilder {
+ public:
+  static int Build(const std::string& tls_unique,
+                   SSLClientCertType type,
+                   const std::string& key,
+                   const std::string& cert,
+                   size_t slot,
+                   SpdyCredential* credential);
+
+ private:
+  friend class SpdyCredentialBuilderTest;
+
+  // Returns the secret data to be signed as part of a credential frame.
+  static std::string GetCredentialSecret(const std::string& tls_unique);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_CREDENTIAL_BUILDER_H_
diff --git a/src/net/spdy/spdy_credential_builder_unittest.cc b/src/net/spdy/spdy_credential_builder_unittest.cc
new file mode 100644
index 0000000..067fdb7
--- /dev/null
+++ b/src/net/spdy/spdy_credential_builder_unittest.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_credential_builder.h"
+
+#include "base/threading/sequenced_worker_pool.h"
+#include "crypto/ec_signature_creator.h"
+#include "crypto/ec_private_key.h"
+#include "net/base/asn1_util.h"
+#include "net/base/default_server_bound_cert_store.h"
+#include "net/base/server_bound_cert_service.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy3;
+
+namespace net {
+
+namespace {
+
+const static size_t kSlot = 2;
+const static char kSecretPrefix[] =
+    "SPDY CREDENTIAL ChannelID\0client -> server";
+
+void CreateCertAndKey(std::string* cert, std::string* key) {
+  // TODO(rch): Share this code with ServerBoundCertServiceTest.
+  scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool =
+      new base::SequencedWorkerPool(1, "CreateCertAndKey");
+  scoped_ptr<ServerBoundCertService> server_bound_cert_service(
+      new ServerBoundCertService(new DefaultServerBoundCertStore(NULL),
+                                 sequenced_worker_pool));
+
+  TestCompletionCallback callback;
+  std::vector<uint8> requested_cert_types;
+  requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN);
+  SSLClientCertType cert_type;
+  ServerBoundCertService::RequestHandle request_handle;
+  int rv = server_bound_cert_service->GetDomainBoundCert(
+      "https://www.google.com", requested_cert_types, &cert_type, key, cert,
+      callback.callback(), &request_handle);
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  EXPECT_EQ(OK, callback.WaitForResult());
+  EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type);
+
+  sequenced_worker_pool->Shutdown();
+}
+
+}  // namespace
+
+class SpdyCredentialBuilderTest : public testing::Test {
+ public:
+  SpdyCredentialBuilderTest() {
+    CreateCertAndKey(&cert_, &key_);
+  }
+
+ protected:
+  int BuildWithType(SSLClientCertType type) {
+    return SpdyCredentialBuilder::Build(
+        MockClientSocket::kTlsUnique, type, key_, cert_, kSlot, &credential_);
+  }
+
+  int Build() {
+    return BuildWithType(CLIENT_CERT_ECDSA_SIGN);
+  }
+
+  std::string GetCredentialSecret() {
+    return SpdyCredentialBuilder::GetCredentialSecret(
+        MockClientSocket::kTlsUnique);
+  }
+
+  std::string cert_;
+  std::string key_;
+  SpdyCredential credential_;
+  MockECSignatureCreatorFactory ec_signature_creator_factory_;
+};
+
+// http://crbug.com/142833, http://crbug.com/140991. The following tests fail
+// with OpenSSL due to the unimplemented ec_private_key_openssl.cc.
+#if defined(USE_OPENSSL)
+#define MAYBE_GetCredentialSecret DISABLED_GetCredentialSecret
+#else
+#define MAYBE_GetCredentialSecret GetCredentialSecret
+#endif
+
+TEST_F(SpdyCredentialBuilderTest, MAYBE_GetCredentialSecret) {
+  std::string secret_str(kSecretPrefix, arraysize(kSecretPrefix));
+  secret_str.append(MockClientSocket::kTlsUnique);
+
+  EXPECT_EQ(secret_str, GetCredentialSecret());
+}
+
+#if defined(USE_OPENSSL)
+#define MAYBE_SucceedsWithECDSACert DISABLED_SucceedsWithECDSACert
+#else
+#define MAYBE_SucceedsWithECDSACert SucceedsWithECDSACert
+#endif
+
+TEST_F(SpdyCredentialBuilderTest, MAYBE_SucceedsWithECDSACert) {
+  EXPECT_EQ(OK, BuildWithType(CLIENT_CERT_ECDSA_SIGN));
+}
+
+#if defined(USE_OPENSSL)
+#define MAYBE_FailsWithRSACert DISABLED_FailsWithRSACert
+#else
+#define MAYBE_FailsWithRSACert FailsWithRSACert
+#endif
+
+TEST_F(SpdyCredentialBuilderTest, MAYBE_FailsWithRSACert) {
+  EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT,
+            BuildWithType(CLIENT_CERT_RSA_SIGN));
+}
+
+#if defined(USE_OPENSSL)
+#define MAYBE_SetsSlotCorrectly DISABLED_SetsSlotCorrectly
+#else
+#define MAYBE_SetsSlotCorrectly SetsSlotCorrectly
+#endif
+
+TEST_F(SpdyCredentialBuilderTest, MAYBE_SetsSlotCorrectly) {
+  ASSERT_EQ(OK, Build());
+  EXPECT_EQ(kSlot, credential_.slot);
+}
+
+#if defined(USE_OPENSSL)
+#define MAYBE_SetsCertCorrectly DISABLED_SetsCertCorrectly
+#else
+#define MAYBE_SetsCertCorrectly SetsCertCorrectly
+#endif
+
+TEST_F(SpdyCredentialBuilderTest, MAYBE_SetsCertCorrectly) {
+  ASSERT_EQ(OK, Build());
+  base::StringPiece spki;
+  ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki));
+  base::StringPiece spk;
+  ASSERT_TRUE(asn1::ExtractSubjectPublicKeyFromSPKI(spki, &spk));
+  EXPECT_EQ(1u, credential_.certs.size());
+  EXPECT_EQ(0, (int)spk[0]);
+  EXPECT_EQ(4, (int)spk[1]);
+  EXPECT_EQ(spk.substr(2, spk.length()).as_string(), credential_.certs[0]);
+}
+
+#if defined(USE_OPENSSL)
+#define MAYBE_SetsProofCorrectly DISABLED_SetsProofCorrectly
+#else
+#define MAYBE_SetsProofCorrectly SetsProofCorrectly
+#endif
+
+TEST_F(SpdyCredentialBuilderTest, MAYBE_SetsProofCorrectly) {
+  ASSERT_EQ(OK, Build());
+  base::StringPiece spki;
+  ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki));
+  std::vector<uint8> spki_data(spki.data(),
+                               spki.data() + spki.size());
+  std::vector<uint8> key_data(key_.data(),
+                              key_.data() + key_.length());
+  std::vector<uint8> proof_data;
+  scoped_ptr<crypto::ECPrivateKey> private_key(
+      crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
+          ServerBoundCertService::kEPKIPassword, key_data, spki_data));
+  scoped_ptr<crypto::ECSignatureCreator> creator(
+      crypto::ECSignatureCreator::Create(private_key.get()));
+  std::string secret = GetCredentialSecret();
+  creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()),
+                secret.length(), &proof_data);
+
+  std::string proof(proof_data.begin(), proof_data.end());
+  EXPECT_EQ(proof, credential_.proof);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_credential_state.cc b/src/net/spdy/spdy_credential_state.cc
new file mode 100644
index 0000000..943d732
--- /dev/null
+++ b/src/net/spdy/spdy_credential_state.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_credential_state.h"
+
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "net/base/server_bound_cert_service.h"
+
+namespace net {
+
+namespace {
+
+GURL GetCanonicalOrigin(const GURL& url) {
+  std::string domain =
+      ServerBoundCertService::GetDomainForHost(url.host());
+  DCHECK(!domain.empty());
+  if (domain == url.host())
+    return url.GetOrigin();
+  return GURL(url.scheme() + "://" + domain + ":" + url.port());
+}
+
+}  // namespace
+
+const size_t SpdyCredentialState::kDefaultNumSlots = 8;
+const size_t SpdyCredentialState::kNoEntry = 0;
+
+SpdyCredentialState::SpdyCredentialState(size_t num_slots)
+  : slots_(num_slots),
+    last_added_(-1) {}
+
+SpdyCredentialState::~SpdyCredentialState() {}
+
+bool SpdyCredentialState::HasCredential(const GURL& origin) const {
+  return FindCredentialSlot(origin) != kNoEntry;
+}
+
+size_t SpdyCredentialState::SetHasCredential(const GURL& origin) {
+  size_t i = FindCredentialSlot(origin);
+  if (i != kNoEntry)
+    return i;
+  // Add the new entry at the next index following the index of the last
+  // entry added, or at index 0 if the last added index is the last index.
+  if (last_added_ + 1 == slots_.size()) {
+    last_added_ = 0;
+  } else {
+    last_added_++;
+  }
+  slots_[last_added_] = GetCanonicalOrigin(origin);
+  return last_added_ + 1;
+}
+
+size_t SpdyCredentialState::FindCredentialSlot(const GURL& origin) const {
+  GURL url = GetCanonicalOrigin(origin);
+  for (size_t i = 0; i < slots_.size(); i++) {
+    if (url == slots_[i])
+      return i + 1;
+  }
+  return kNoEntry;
+}
+
+void SpdyCredentialState::Resize(size_t size) {
+  slots_.resize(size);
+  if (last_added_ >= slots_.size())
+    last_added_ = slots_.size() - 1;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_credential_state.h b/src/net/spdy/spdy_credential_state.h
new file mode 100644
index 0000000..1460eac
--- /dev/null
+++ b/src/net/spdy/spdy_credential_state.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_CREDENTIAL_STATE_H_
+#define NET_SPDY_SPDY_CREDENTIAL_STATE_H_
+
+#include <vector>
+
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// A class for tracking the credentials associated with a SPDY session.
+class NET_EXPORT_PRIVATE SpdyCredentialState {
+ public:
+  explicit SpdyCredentialState(size_t num_slots);
+  ~SpdyCredentialState();
+
+  // Changes the number of credentials being tracked.  If the new size is
+  // larger, then empty slots will be added to the end.  If the new size is
+  // smaller than the current size, then the extra slots will be truncated
+  // from the end.
+  void Resize(size_t size);
+
+  // Returns the one-based index in |slots_| for |url| or kNoEntry, if no entry
+  // for |url| exists.
+  size_t FindCredentialSlot(const GURL& url) const;
+
+  // Returns true if there is a credential associated with |url|.
+  bool HasCredential(const GURL& url) const;
+
+  // Adds the new credentials to be associated with all origins matching
+  // |url|.  If there is space, then it will add in the first available
+  // position.  Otherwise, an existing credential will be evicted.  Returns
+  // the slot in which this domain was added.
+  size_t SetHasCredential(const GURL& url);
+
+  // This value is defined as the default initial value in the SPDY spec unless
+  // otherwise negotiated via SETTINGS.
+  static const size_t kDefaultNumSlots;
+
+  // Sentinel value to be returned by FindCredentialSlot when no entry exists.
+  static const size_t kNoEntry;
+
+ private:
+  // Vector of origins that have credentials.
+  std::vector<GURL> slots_;
+  // Index of the last origin added to |slots_|.
+  size_t last_added_;
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_CREDENTIAL_STATE_H_
diff --git a/src/net/spdy/spdy_credential_state_unittest.cc b/src/net/spdy/spdy_credential_state_unittest.cc
new file mode 100644
index 0000000..b512921
--- /dev/null
+++ b/src/net/spdy/spdy_credential_state_unittest.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_credential_state.h"
+
+#include "net/base/host_port_pair.h"
+#include "testing/platform_test.h"
+
+namespace net {
+
+class SpdyCredentialStateTest : public PlatformTest {
+ public:
+  SpdyCredentialStateTest()
+    : state_(4),
+      origin1_("https://1.com"),
+      origin2_("https://2.com"),
+      origin3_("https://3.com"),
+      origin4_("https://4.com"),
+      origin5_("https://5.com"),
+      origin6_("https://6.com"),
+      origin11_("https://11.com"),
+      host1_("https://www.1.com:443") {
+  }
+
+ protected:
+  SpdyCredentialState state_;
+  const GURL origin1_;
+  const GURL origin2_;
+  const GURL origin3_;
+  const GURL origin4_;
+  const GURL origin5_;
+  const GURL origin6_;
+  const GURL origin11_;
+  const GURL host1_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyCredentialStateTest);
+};
+
+TEST_F(SpdyCredentialStateTest, HasCredentialReturnsFalseWhenEmpty) {
+  EXPECT_FALSE(state_.HasCredential(origin1_));
+  EXPECT_FALSE(state_.HasCredential(origin2_));
+  EXPECT_FALSE(state_.HasCredential(origin3_));
+}
+
+TEST_F(SpdyCredentialStateTest, HasCredentialReturnsTrueWhenAdded) {
+  state_.SetHasCredential(origin1_);
+  EXPECT_TRUE(state_.HasCredential(origin1_));
+  EXPECT_TRUE(state_.HasCredential(host1_));
+  EXPECT_FALSE(state_.HasCredential(origin11_));
+  EXPECT_FALSE(state_.HasCredential(origin2_));
+  EXPECT_FALSE(state_.HasCredential(origin3_));
+}
+
+TEST_F(SpdyCredentialStateTest, SetCredentialAddsToEndOfList) {
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+  EXPECT_EQ(3u, (state_.SetHasCredential(origin3_)));
+}
+
+TEST_F(SpdyCredentialStateTest, SetReturnsPositionIfAlreadyInList) {
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+}
+
+TEST_F(SpdyCredentialStateTest, SetReplacesOldestElementWhenFull) {
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+  EXPECT_EQ(3u, (state_.SetHasCredential(origin3_)));
+  EXPECT_EQ(4u, (state_.SetHasCredential(origin4_)));
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin5_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin6_)));
+  EXPECT_EQ(3u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(4u, (state_.SetHasCredential(origin2_)));
+}
+
+TEST_F(SpdyCredentialStateTest, ResizeAddsEmptySpaceAtEnd) {
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+  EXPECT_EQ(3u, (state_.SetHasCredential(origin3_)));
+  EXPECT_EQ(4u, (state_.SetHasCredential(origin4_)));
+  state_.Resize(6);
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+  EXPECT_EQ(3u, (state_.SetHasCredential(origin3_)));
+  EXPECT_EQ(4u, (state_.SetHasCredential(origin4_)));
+  EXPECT_EQ(5u, (state_.SetHasCredential(origin5_)));
+  EXPECT_EQ(6u, (state_.SetHasCredential(origin6_)));
+}
+
+TEST_F(SpdyCredentialStateTest, ResizeTrunatesFromEnd) {
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin1_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin2_)));
+  EXPECT_EQ(3u, (state_.SetHasCredential(origin3_)));
+  EXPECT_EQ(4u, (state_.SetHasCredential(origin4_)));
+  state_.Resize(2);
+  EXPECT_TRUE(state_.HasCredential(origin1_));
+  EXPECT_TRUE(state_.HasCredential(origin2_));
+  EXPECT_FALSE(state_.HasCredential(origin3_));
+  EXPECT_FALSE(state_.HasCredential(origin4_));
+  EXPECT_EQ(1u, (state_.SetHasCredential(origin5_)));
+  EXPECT_EQ(2u, (state_.SetHasCredential(origin6_)));
+}
+
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_frame_builder.cc b/src/net/spdy/spdy_frame_builder.cc
new file mode 100644
index 0000000..04bf62c
--- /dev/null
+++ b/src/net/spdy/spdy_frame_builder.cc
@@ -0,0 +1,111 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "net/spdy/spdy_frame_builder.h"
+#include "net/spdy/spdy_protocol.h"
+
+namespace net {
+
+namespace {
+
+// Creates a FlagsAndLength.
+FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) {
+  DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
+  FlagsAndLength flags_length;
+  flags_length.length_ = htonl(static_cast<uint32>(length));
+  DCHECK_EQ(0, flags & ~kControlFlagsMask);
+  flags_length.flags_[0] = flags;
+  return flags_length;
+}
+
+}  // namespace
+
+SpdyFrameBuilder::SpdyFrameBuilder(SpdyControlType type,
+                                   SpdyControlFlags flags,
+                                   int spdy_version,
+                                   size_t size)
+    : buffer_(new char[size]),
+      capacity_(size),
+      length_(0) {
+  FlagsAndLength flags_length = CreateFlagsAndLength(
+      flags, size - SpdyFrame::kHeaderSize);
+  WriteUInt16(kControlFlagMask | spdy_version);
+  WriteUInt16(type);
+  WriteBytes(&flags_length, sizeof(flags_length));
+}
+
+SpdyFrameBuilder::SpdyFrameBuilder(SpdyStreamId stream_id,
+                                   SpdyDataFlags flags,
+                                   size_t size)
+    : buffer_(new char[size]),
+      capacity_(size),
+      length_(0) {
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  WriteUInt32(stream_id);
+  size_t length = size - SpdyFrame::kHeaderSize;
+  DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
+  FlagsAndLength flags_length;
+  flags_length.length_ = htonl(length);
+  DCHECK_EQ(0, flags & ~kDataFlagsMask);
+  flags_length.flags_[0] = flags;
+  WriteBytes(&flags_length, sizeof(flags_length));
+}
+
+SpdyFrameBuilder::~SpdyFrameBuilder() {
+  delete[] buffer_;
+}
+
+char* SpdyFrameBuilder::BeginWrite(size_t length) {
+  size_t offset = length_;
+  size_t needed_size = length_ + length;
+  if (needed_size > capacity_)
+    return NULL;
+
+#ifdef ARCH_CPU_64_BITS
+  DCHECK_LE(length, std::numeric_limits<uint32>::max());
+#endif
+
+  return buffer_ + offset;
+}
+
+void SpdyFrameBuilder::EndWrite(char* dest, int length) {
+}
+
+bool SpdyFrameBuilder::WriteBytes(const void* data, uint32 data_len) {
+  if (data_len > kLengthMask) {
+    return false;
+  }
+
+  char* dest = BeginWrite(data_len);
+  if (!dest)
+    return false;
+
+  memcpy(dest, data, data_len);
+
+  EndWrite(dest, data_len);
+  length_ += data_len;
+  return true;
+}
+
+bool SpdyFrameBuilder::WriteString(const std::string& value) {
+  if (value.size() > 0xffff)
+    return false;
+
+  if (!WriteUInt16(static_cast<int>(value.size())))
+    return false;
+
+  return WriteBytes(value.data(), static_cast<uint16>(value.size()));
+}
+
+bool SpdyFrameBuilder::WriteStringPiece32(const base::StringPiece& value) {
+  if (!WriteUInt32(value.size())) {
+    return false;
+  }
+
+  return WriteBytes(value.data(), value.size());
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_frame_builder.h b/src/net/spdy/spdy_frame_builder.h
new file mode 100644
index 0000000..affdbe4
--- /dev/null
+++ b/src/net/spdy/spdy_frame_builder.h
@@ -0,0 +1,132 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_
+#define NET_SPDY_SPDY_FRAME_BUILDER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/string_piece.h"
+#include "base/sys_byteorder.h"
+#include "net/base/net_export.h"
+#include "net/spdy/spdy_protocol.h"
+
+namespace net {
+
+// This class provides facilities for basic binary value packing and unpacking
+// into Spdy frames.
+//
+// The SpdyFrameBuilder supports appending primitive values (int, string, etc)
+// to a frame instance.  The SpdyFrameBuilder grows its internal memory buffer
+// dynamically to hold the sequence of primitive values.   The internal memory
+// buffer is exposed as the "data" of the SpdyFrameBuilder.
+class NET_EXPORT_PRIVATE SpdyFrameBuilder {
+ public:
+  ~SpdyFrameBuilder();
+
+  // Initializes a SpdyFrameBuilder with a buffer of given size,
+  // populate with a SPDY control frame header based on
+  // |type|, |flags|, and |spdy_version|.
+  SpdyFrameBuilder(SpdyControlType type, SpdyControlFlags flags,
+                   int spdy_version, size_t size);
+
+  // Initiailizes a SpdyFrameBuilder with a buffer of given size,
+  // populated with a SPDY data frame header based on
+  // |stream_id| and |flags|.
+  SpdyFrameBuilder(SpdyStreamId stream_id, SpdyDataFlags flags,  size_t size);
+
+  // Returns the size of the SpdyFrameBuilder's data.
+  size_t length() const { return length_; }
+
+  // Takes the buffer from the SpdyFrameBuilder.
+  SpdyFrame* take() {
+    SpdyFrame* rv = new SpdyFrame(buffer_, true);
+    buffer_ = NULL;
+    capacity_ = 0;
+    length_ = 0;
+    return rv;
+  }
+
+  // Methods for adding to the payload.  These values are appended to the end
+  // of the SpdyFrameBuilder payload. Note - binary integers are converted from
+  // host to network form.
+  bool WriteUInt8(uint8 value) {
+    return WriteBytes(&value, sizeof(value));
+  }
+  bool WriteUInt16(uint16 value) {
+    value = htons(value);
+    return WriteBytes(&value, sizeof(value));
+  }
+  bool WriteUInt32(uint32 value) {
+    value = htonl(value);
+    return WriteBytes(&value, sizeof(value));
+  }
+  // TODO(hkhalil) Rename to WriteStringPiece16().
+  bool WriteString(const std::string& value);
+  bool WriteStringPiece32(const base::StringPiece& value);
+  bool WriteBytes(const void* data, uint32 data_len);
+
+  // Write an integer to a particular offset in the data buffer.
+  bool WriteUInt32ToOffset(int offset, uint32 value) {
+    value = htonl(value);
+    return WriteBytesToOffset(offset, &value, sizeof(value));
+  }
+
+  // Write to a particular offset in the data buffer.
+  bool WriteBytesToOffset(int offset, const void* data, uint32 data_len) {
+    if (offset + data_len > length_)
+      return false;
+    char *ptr = buffer_ + offset;
+    memcpy(ptr, data, data_len);
+    return true;
+  }
+
+  // Returns true if the given iterator could point to data with the given
+  // length. If there is no room for the given data before the end of the
+  // payload, returns false.
+  bool IteratorHasRoomFor(const void* iter, int len) const {
+    const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
+    if (len < 0 ||
+        iter < buffer_ ||
+        iter > end_of_payload() ||
+        iter > end_of_region ||
+        end_of_region > end_of_payload())
+      return false;
+
+    // Watch out for overflow in pointer calculation, which wraps.
+    return (iter <= end_of_region) && (end_of_region <= end_of_payload());
+  }
+
+ protected:
+  size_t capacity() const {
+    return capacity_;
+  }
+
+  const char* end_of_payload() const { return buffer_ + length_; }
+
+  // Completes the write operation by padding the data with NULL bytes until it
+  // is padded. Should be paired with BeginWrite, but it does not necessarily
+  // have to be called after the data is written.
+  void EndWrite(char* dest, int length);
+
+  // Moves the iterator by the given number of bytes.
+  static void UpdateIter(void** iter, int bytes) {
+    *iter = static_cast<char*>(*iter) + bytes;
+  }
+
+ private:
+  // Returns the location that the data should be written at, or NULL if there
+  // is not enough room. Call EndWrite with the returned offset and the given
+  // length to pad out for the next write.
+  char* BeginWrite(size_t length);
+
+  char* buffer_;
+  size_t capacity_;  // Allocation size of payload (or -1 if buffer is const).
+  size_t length_;    // current length of the buffer
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_FRAME_BUILDER_H_
diff --git a/src/net/spdy/spdy_frame_reader.cc b/src/net/spdy/spdy_frame_reader.cc
new file mode 100644
index 0000000..57bf9eb
--- /dev/null
+++ b/src/net/spdy/spdy_frame_reader.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "base/sys_byteorder.h"
+#include "net/spdy/spdy_frame_reader.h"
+
+namespace net {
+
+SpdyFrameReader::SpdyFrameReader(const char* data, const size_t len)
+    : data_(data),
+      len_(len),
+      ofs_(0) {
+}
+
+bool SpdyFrameReader::ReadUInt16(uint16* result) {
+  // Make sure that we have the whole uint16.
+  if (!CanRead(2)) {
+    OnFailure();
+    return false;
+  }
+
+  // Read into result.
+  *result = ntohs(*(reinterpret_cast<const uint16*>(data_ + ofs_)));
+
+  // Iterate.
+  ofs_ += 2;
+
+  return true;
+}
+
+bool SpdyFrameReader::ReadUInt32(uint32* result) {
+  // Make sure that we have the whole uint32.
+  if (!CanRead(4)) {
+    OnFailure();
+    return false;
+  }
+
+  // Read into result.
+  *result = ntohl(*(reinterpret_cast<const uint32*>(data_ + ofs_)));
+
+  // Iterate.
+  ofs_ += 4;
+
+  return true;
+}
+
+bool SpdyFrameReader::ReadStringPiece16(base::StringPiece* result) {
+  // Read resultant length.
+  uint16 result_len;
+  if (!ReadUInt16(&result_len)) {
+    // OnFailure() already called.
+    return false;
+  }
+
+  // Make sure that we have the whole string.
+  if (!CanRead(result_len)) {
+    OnFailure();
+    return false;
+  }
+
+  // Set result.
+  result->set(data_ + ofs_, result_len);
+
+  // Iterate.
+  ofs_ += result_len;
+
+  return true;
+}
+
+bool SpdyFrameReader::ReadStringPiece32(base::StringPiece* result) {
+  // Read resultant length.
+  uint32 result_len;
+  if (!ReadUInt32(&result_len)) {
+    // OnFailure() already called.
+    return false;
+  }
+
+  // Make sure that we have the whole string.
+  if (!CanRead(result_len)) {
+    OnFailure();
+    return false;
+  }
+
+  // Set result.
+  result->set(data_ + ofs_, result_len);
+
+  // Iterate.
+  ofs_ += result_len;
+
+  return true;
+}
+
+bool SpdyFrameReader::ReadBytes(void* result, size_t size) {
+  // Make sure that we have enough data to read.
+  if (!CanRead(size)) {
+    OnFailure();
+    return false;
+  }
+
+  // Read into result.
+  memcpy(result, data_ + ofs_, size);
+
+  // Iterate.
+  ofs_ += size;
+
+  return true;
+}
+
+bool SpdyFrameReader::IsDoneReading() const {
+  return len_ == ofs_;
+}
+
+bool SpdyFrameReader::CanRead(size_t bytes) const {
+  return bytes <= (len_ - ofs_);
+}
+
+void SpdyFrameReader::OnFailure() {
+  // Set our iterator to the end of the buffer so that further reads fail
+  // immediately.
+  ofs_ = len_;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_frame_reader.h b/src/net/spdy/spdy_frame_reader.h
new file mode 100644
index 0000000..6db7a08
--- /dev/null
+++ b/src/net/spdy/spdy_frame_reader.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_FRAME_READER_H_
+#define NET_SPDY_SPDY_FRAME_READER_H_
+
+#include "base/basictypes.h"
+#include "base/string_piece.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// Used for reading SPDY frames. Though there isn't really anything terribly
+// SPDY-specific here, it's a helper class that's useful when doing SPDY
+// framing.
+//
+// To use, simply construct a SpdyFramerReader using the underlying buffer that
+// you'd like to read fields from, then call one of the Read*() methods to
+// actually do some reading.
+//
+// This class keeps an internal iterator to keep track of what's already been
+// read and each successive Read*() call automatically increments said iterator
+// on success. On failure, internal state of the SpdyFrameReader should not be
+// trusted and it is up to the caller to throw away the failed instance and
+// handle the error as appropriate. None of the Read*() methods should ever be
+// called after failure, as they will also fail immediately.
+class NET_EXPORT_PRIVATE SpdyFrameReader {
+ public:
+  // Caller must provide an underlying buffer to work on.
+  SpdyFrameReader(const char* data, const size_t len);
+
+  // Empty destructor.
+  ~SpdyFrameReader() {}
+
+  // Reads a 16-bit unsigned integer into the given output parameter.
+  // Forwards the internal iterater on success.
+  // Returns true on success, false otherwise.
+  bool ReadUInt16(uint16* result);
+
+  // Reads a 32-bit unsigned integer into the given output parameter.
+  // Forwards the internal iterater on success.
+  // Returns true on success, false otherwise.
+  bool ReadUInt32(uint32* result);
+
+  // Reads a string prefixed with 16-bit length into the given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterater on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPiece16(base::StringPiece* result);
+
+  // Reads a string prefixed with 32-bit length into the given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterater on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPiece32(base::StringPiece* result);
+
+  // Reads a given number of bytes into the given buffer. The buffer
+  // must be of adequate size.
+  // Forwards the internal iterater on success.
+  // Returns true on success, false otherwise.
+  bool ReadBytes(void* result, size_t size);
+
+  // Returns true if the entirety of the underlying buffer has been read via
+  // Read*() calls.
+  bool IsDoneReading() const;
+
+ private:
+  // Returns true if the underlying buffer has enough room to read the given
+  // amount of bytes.
+  bool CanRead(size_t bytes) const;
+
+  // To be called when a read fails for any reason.
+  void OnFailure();
+
+  // The data buffer that we're reading from.
+  const char* data_;
+
+  // The length of the data buffer that we're reading from.
+  const size_t len_;
+
+  // The location of the next read from our data buffer.
+  size_t ofs_;
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_FRAME_READER_H_
diff --git a/src/net/spdy/spdy_frame_reader_test.cc b/src/net/spdy/spdy_frame_reader_test.cc
new file mode 100644
index 0000000..c72e5be
--- /dev/null
+++ b/src/net/spdy/spdy_frame_reader_test.cc
@@ -0,0 +1,249 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <iostream>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/sys_byteorder.h"
+#include "net/spdy/spdy_frame_reader.h"
+#include "testing/platform_test.h"
+
+namespace net {
+
+TEST(SpdyFrameReaderTest, ReadUInt16) {
+  // Frame data in network byte order.
+  const uint16 kFrameData[] = {
+    htons(1), htons(1<<15),
+  };
+
+  SpdyFrameReader frame_reader(reinterpret_cast<const char *>(kFrameData),
+                               arraysize(kFrameData) * sizeof(uint16));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  uint16 uint16_val;
+  EXPECT_TRUE(frame_reader.ReadUInt16(&uint16_val));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+  EXPECT_EQ(1, uint16_val);
+
+  EXPECT_TRUE(frame_reader.ReadUInt16(&uint16_val));
+  EXPECT_TRUE(frame_reader.IsDoneReading());
+  EXPECT_EQ(1<<15, uint16_val);
+}
+
+TEST(SpdyFrameReaderTest, ReadUInt32) {
+  // Frame data in network byte order.
+  const uint32 kFrameData[] = {
+    htonl(1), htonl(1<<31),
+  };
+
+  SpdyFrameReader frame_reader(reinterpret_cast<const char *>(kFrameData),
+                               arraysize(kFrameData) * sizeof(uint32));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  uint32 uint32_val;
+  EXPECT_TRUE(frame_reader.ReadUInt32(&uint32_val));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+  EXPECT_EQ(1u, uint32_val);
+
+  EXPECT_TRUE(frame_reader.ReadUInt32(&uint32_val));
+  EXPECT_TRUE(frame_reader.IsDoneReading());
+  EXPECT_EQ(1u<<31, uint32_val);
+}
+
+TEST(SpdyFrameReaderTest, ReadStringPiece16) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00, 0x02,  // uint16(2)
+    0x48, 0x69,  // "Hi"
+    0x00, 0x10,  // uint16(16)
+    0x54, 0x65, 0x73, 0x74,
+    0x69, 0x6e, 0x67, 0x2c,
+    0x20, 0x31, 0x2c, 0x20,
+    0x32, 0x2c, 0x20, 0x33,  // "Testing, 1, 2, 3"
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  base::StringPiece stringpiece_val;
+  EXPECT_TRUE(frame_reader.ReadStringPiece16(&stringpiece_val));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+  EXPECT_EQ(0, stringpiece_val.compare("Hi"));
+
+  EXPECT_TRUE(frame_reader.ReadStringPiece16(&stringpiece_val));
+  EXPECT_TRUE(frame_reader.IsDoneReading());
+  EXPECT_EQ(0, stringpiece_val.compare("Testing, 1, 2, 3"));
+}
+
+TEST(SpdyFrameReaderTest, ReadStringPiece32) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00, 0x00, 0x00, 0x03,  // uint32(3)
+    0x66, 0x6f, 0x6f,  // "foo"
+    0x00, 0x00, 0x00, 0x10,  // uint32(16)
+    0x54, 0x65, 0x73, 0x74,
+    0x69, 0x6e, 0x67, 0x2c,
+    0x20, 0x34, 0x2c, 0x20,
+    0x35, 0x2c, 0x20, 0x36,  // "Testing, 4, 5, 6"
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  base::StringPiece stringpiece_val;
+  EXPECT_TRUE(frame_reader.ReadStringPiece32(&stringpiece_val));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+  EXPECT_EQ(0, stringpiece_val.compare("foo"));
+
+  EXPECT_TRUE(frame_reader.ReadStringPiece32(&stringpiece_val));
+  EXPECT_TRUE(frame_reader.IsDoneReading());
+  EXPECT_EQ(0, stringpiece_val.compare("Testing, 4, 5, 6"));
+}
+
+TEST(SpdyFrameReaderTest, ReadUInt16WithBufferTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00,  // part of a uint16
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  uint16 uint16_val;
+  EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
+}
+
+TEST(SpdyFrameReaderTest, ReadUInt32WithBufferTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00, 0x00, 0x00,  // part of a uint32
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  uint32 uint32_val;
+  EXPECT_FALSE(frame_reader.ReadUInt32(&uint32_val));
+
+  // Also make sure that trying to read a uint16, which technically could work,
+  // fails immediately due to previously encountered failed read.
+  uint16 uint16_val;
+  EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
+}
+
+// Tests ReadStringPiece16() with a buffer too small to fit the entire string.
+TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00, 0x03,  // uint16(3)
+    0x48, 0x69,  // "Hi"
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  base::StringPiece stringpiece_val;
+  EXPECT_FALSE(frame_reader.ReadStringPiece16(&stringpiece_val));
+
+  // Also make sure that trying to read a uint16, which technically could work,
+  // fails immediately due to previously encountered failed read.
+  uint16 uint16_val;
+  EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
+}
+
+// Tests ReadStringPiece16() with a buffer too small even to fit the length.
+TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferWayTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00,  // part of a uint16
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  base::StringPiece stringpiece_val;
+  EXPECT_FALSE(frame_reader.ReadStringPiece16(&stringpiece_val));
+
+  // Also make sure that trying to read a uint16, which technically could work,
+  // fails immediately due to previously encountered failed read.
+  uint16 uint16_val;
+  EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
+}
+
+// Tests ReadStringPiece32() with a buffer too small to fit the entire string.
+TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00, 0x00, 0x00, 0x03,  // uint32(3)
+    0x48, 0x69,  // "Hi"
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  base::StringPiece stringpiece_val;
+  EXPECT_FALSE(frame_reader.ReadStringPiece32(&stringpiece_val));
+
+  // Also make sure that trying to read a uint16, which technically could work,
+  // fails immediately due to previously encountered failed read.
+  uint16 uint16_val;
+  EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
+}
+
+// Tests ReadStringPiece32() with a buffer too small even to fit the length.
+TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferWayTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x00, 0x00, 0x00,  // part of a uint32
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  base::StringPiece stringpiece_val;
+  EXPECT_FALSE(frame_reader.ReadStringPiece32(&stringpiece_val));
+
+  // Also make sure that trying to read a uint16, which technically could work,
+  // fails immediately due to previously encountered failed read.
+  uint16 uint16_val;
+  EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
+}
+
+TEST(SpdyFrameReaderTest, ReadBytes) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x66, 0x6f, 0x6f,  // "foo"
+    0x48, 0x69,  // "Hi"
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  char dest1[3] = {};
+  EXPECT_TRUE(frame_reader.ReadBytes(&dest1, arraysize(dest1)));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+  EXPECT_EQ("foo", base::StringPiece(dest1, arraysize(dest1)));
+
+  char dest2[2] = {};
+  EXPECT_TRUE(frame_reader.ReadBytes(&dest2, arraysize(dest2)));
+  EXPECT_TRUE(frame_reader.IsDoneReading());
+  EXPECT_EQ("Hi", base::StringPiece(dest2, arraysize(dest2)));
+}
+
+TEST(SpdyFrameReaderTest, ReadBytesWithBufferTooSmall) {
+  // Frame data in network byte order.
+  const char kFrameData[] = {
+    0x01,
+  };
+
+  SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
+  EXPECT_FALSE(frame_reader.IsDoneReading());
+
+  char dest[arraysize(kFrameData) + 2] = {};
+  EXPECT_FALSE(frame_reader.ReadBytes(&dest, arraysize(kFrameData) + 1));
+  EXPECT_STREQ("", dest);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_framer.cc b/src/net/spdy/spdy_framer.cc
new file mode 100644
index 0000000..0d9049d
--- /dev/null
+++ b/src/net/spdy/spdy_framer.cc
@@ -0,0 +1,1881 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO(rtenhove) clean up frame buffer size calculations so that we aren't
+// constantly adding and subtracting header sizes; this is ugly and error-
+// prone.
+
+#include "net/spdy/spdy_framer.h"
+
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/stats_counters.h"
+#include "base/third_party/valgrind/memcheck.h"
+#include "net/spdy/spdy_frame_builder.h"
+#include "net/spdy/spdy_frame_reader.h"
+#include "net/spdy/spdy_bitmasks.h"
+
+#if defined(USE_SYSTEM_ZLIB)
+#include <zlib.h>
+#else
+#include "third_party/zlib/zlib.h"
+#endif
+
+using std::vector;
+
+namespace net {
+
+namespace {
+
+// Compute the id of our dictionary so that we know we're using the
+// right one when asked for it.
+uLong CalculateDictionaryId(const char* dictionary,
+                            const size_t dictionary_size) {
+  uLong initial_value = adler32(0L, Z_NULL, 0);
+  return adler32(initial_value,
+                 reinterpret_cast<const Bytef*>(dictionary),
+                 dictionary_size);
+}
+
+struct DictionaryIds {
+  DictionaryIds()
+    : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
+      v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
+  {}
+  const uLong v2_dictionary_id;
+  const uLong v3_dictionary_id;
+};
+
+// Adler ID for the SPDY header compressor dictionaries. Note that they are
+// initialized lazily to avoid static initializers.
+base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
+
+}  // namespace
+
+const int SpdyFramer::kMinSpdyVersion = 2;
+const int SpdyFramer::kMaxSpdyVersion = 3;
+const SpdyStreamId SpdyFramer::kInvalidStream = -1;
+const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
+const size_t SpdyFramer::kControlFrameBufferSize =
+    sizeof(SpdySynStreamControlFrameBlock);
+const size_t SpdyFramer::kMaxControlFrameSize = 16 * 1024;
+
+#ifdef DEBUG_SPDY_STATE_CHANGES
+#define CHANGE_STATE(newstate)                                  \
+  do {                                                          \
+    LOG(INFO) << "Changing state from: "                        \
+              << StateToString(state_)                          \
+              << " to " << StateToString(newstate) << "\n";     \
+    DCHECK(state_ != SPDY_ERROR);                               \
+    DCHECK_EQ(previous_state_, state_);                         \
+    previous_state_ = state_;                                   \
+    state_ = newstate;                                          \
+  } while (false)
+#else
+#define CHANGE_STATE(newstate)                                  \
+  do {                                                          \
+    DCHECK(state_ != SPDY_ERROR);                               \
+    DCHECK_EQ(previous_state_, state_);                         \
+    previous_state_ = state_;                                   \
+    state_ = newstate;                                          \
+  } while (false)
+#endif
+
+SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version,
+                                                      uint32 wire) {
+  if (version < 3) {
+    ConvertFlagsAndIdForSpdy2(&wire);
+  }
+  return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
+}
+
+SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
+    : flags_(flags), id_(id & 0x00ffffff) {
+  DCHECK_GT(1u << 24, id) << "SPDY setting ID too large.";
+}
+
+uint32 SettingsFlagsAndId::GetWireFormat(int version) const {
+  uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
+  if (version < 3) {
+    ConvertFlagsAndIdForSpdy2(&wire);
+  }
+  return wire;
+}
+
+// SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
+// This method is used to preserve buggy behavior and works on both
+// little-endian and big-endian hosts.
+// This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
+// as well as vice versa).
+void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
+    uint8* wire_array = reinterpret_cast<uint8*>(val);
+    std::swap(wire_array[0], wire_array[3]);
+    std::swap(wire_array[1], wire_array[2]);
+}
+
+SpdyCredential::SpdyCredential() : slot(0) {}
+SpdyCredential::~SpdyCredential() {}
+
+SpdyFramer::SpdyFramer(int version)
+    : state_(SPDY_RESET),
+      previous_state_(SPDY_RESET),
+      error_code_(SPDY_NO_ERROR),
+      remaining_data_(0),
+      remaining_control_payload_(0),
+      remaining_control_header_(0),
+      current_frame_buffer_(new char[kControlFrameBufferSize]),
+      current_frame_len_(0),
+      enable_compression_(true),
+      visitor_(NULL),
+      display_protocol_("SPDY"),
+      spdy_version_(version),
+      syn_frame_processed_(false),
+      probable_http_response_(false) {
+  DCHECK_GE(kMaxSpdyVersion, version);
+  DCHECK_LE(kMinSpdyVersion, version);
+}
+
+SpdyFramer::~SpdyFramer() {
+  if (header_compressor_.get()) {
+    deflateEnd(header_compressor_.get());
+  }
+  if (header_decompressor_.get()) {
+    inflateEnd(header_decompressor_.get());
+  }
+}
+
+void SpdyFramer::Reset() {
+  state_ = SPDY_RESET;
+  previous_state_ = SPDY_RESET;
+  error_code_ = SPDY_NO_ERROR;
+  remaining_data_ = 0;
+  remaining_control_payload_ = 0;
+  remaining_control_header_ = 0;
+  current_frame_len_ = 0;
+  settings_scratch_.Reset();
+}
+
+const char* SpdyFramer::StateToString(int state) {
+  switch (state) {
+    case SPDY_ERROR:
+      return "ERROR";
+    case SPDY_DONE:
+      return "DONE";
+    case SPDY_AUTO_RESET:
+      return "AUTO_RESET";
+    case SPDY_RESET:
+      return "RESET";
+    case SPDY_READING_COMMON_HEADER:
+      return "READING_COMMON_HEADER";
+    case SPDY_CONTROL_FRAME_PAYLOAD:
+      return "CONTROL_FRAME_PAYLOAD";
+    case SPDY_IGNORE_REMAINING_PAYLOAD:
+      return "IGNORE_REMAINING_PAYLOAD";
+    case SPDY_FORWARD_STREAM_FRAME:
+      return "FORWARD_STREAM_FRAME";
+    case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
+      return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
+    case SPDY_CONTROL_FRAME_HEADER_BLOCK:
+      return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
+    case SPDY_CREDENTIAL_FRAME_PAYLOAD:
+      return "SPDY_CREDENTIAL_FRAME_PAYLOAD";
+    case SPDY_SETTINGS_FRAME_PAYLOAD:
+      return "SPDY_SETTINGS_FRAME_PAYLOAD";
+  }
+  return "UNKNOWN_STATE";
+}
+
+void SpdyFramer::set_error(SpdyError error) {
+  DCHECK(visitor_);
+  error_code_ = error;
+  CHANGE_STATE(SPDY_ERROR);
+  visitor_->OnError(this);
+}
+
+const char* SpdyFramer::ErrorCodeToString(int error_code) {
+  switch (error_code) {
+    case SPDY_NO_ERROR:
+      return "NO_ERROR";
+    case SPDY_INVALID_CONTROL_FRAME:
+      return "INVALID_CONTROL_FRAME";
+    case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
+      return "CONTROL_PAYLOAD_TOO_LARGE";
+    case SPDY_ZLIB_INIT_FAILURE:
+      return "ZLIB_INIT_FAILURE";
+    case SPDY_UNSUPPORTED_VERSION:
+      return "UNSUPPORTED_VERSION";
+    case SPDY_DECOMPRESS_FAILURE:
+      return "DECOMPRESS_FAILURE";
+    case SPDY_COMPRESS_FAILURE:
+      return "COMPRESS_FAILURE";
+    case SPDY_INVALID_DATA_FRAME_FLAGS:
+      return "SPDY_INVALID_DATA_FRAME_FLAGS";
+  }
+  return "UNKNOWN_ERROR";
+}
+
+const char* SpdyFramer::StatusCodeToString(int status_code) {
+  switch (status_code) {
+    case INVALID:
+      return "INVALID";
+    case PROTOCOL_ERROR:
+      return "PROTOCOL_ERROR";
+    case INVALID_STREAM:
+      return "INVALID_STREAM";
+    case REFUSED_STREAM:
+      return "REFUSED_STREAM";
+    case UNSUPPORTED_VERSION:
+      return "UNSUPPORTED_VERSION";
+    case CANCEL:
+      return "CANCEL";
+    case INTERNAL_ERROR:
+      return "INTERNAL_ERROR";
+    case FLOW_CONTROL_ERROR:
+      return "FLOW_CONTROL_ERROR";
+    case STREAM_IN_USE:
+      return "STREAM_IN_USE";
+    case STREAM_ALREADY_CLOSED:
+      return "STREAM_ALREADY_CLOSED";
+    case INVALID_CREDENTIALS:
+      return "INVALID_CREDENTIALS";
+    case FRAME_TOO_LARGE:
+      return "FRAME_TOO_LARGE";
+  }
+  return "UNKNOWN_STATUS";
+}
+
+const char* SpdyFramer::ControlTypeToString(SpdyControlType type) {
+  switch (type) {
+    case SYN_STREAM:
+      return "SYN_STREAM";
+    case SYN_REPLY:
+      return "SYN_REPLY";
+    case RST_STREAM:
+      return "RST_STREAM";
+    case SETTINGS:
+      return "SETTINGS";
+    case NOOP:
+      return "NOOP";
+    case PING:
+      return "PING";
+    case GOAWAY:
+      return "GOAWAY";
+    case HEADERS:
+      return "HEADERS";
+    case WINDOW_UPDATE:
+      return "WINDOW_UPDATE";
+    case CREDENTIAL:
+      return "CREDENTIAL";
+    case NUM_CONTROL_FRAME_TYPES:
+      break;
+  }
+  return "UNKNOWN_CONTROL_TYPE";
+}
+
+size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
+  DCHECK(visitor_);
+  DCHECK(data);
+
+  size_t original_len = len;
+  do {
+    previous_state_ = state_;
+    switch (state_) {
+      case SPDY_ERROR:
+      case SPDY_DONE:
+        goto bottom;
+
+      case SPDY_AUTO_RESET:
+      case SPDY_RESET:
+        Reset();
+        if (len > 0) {
+          CHANGE_STATE(SPDY_READING_COMMON_HEADER);
+        }
+        break;
+
+      case SPDY_READING_COMMON_HEADER: {
+        size_t bytes_read = ProcessCommonHeader(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+
+      case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
+        // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY,
+        // HEADERS) take a different path through the state machine - they
+        // will go:
+        //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
+        //   2. SPDY_CONTROL_FRAME_HEADER_BLOCK
+        //
+        // SETTINGS frames take a slightly modified route:
+        //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
+        //   2. SPDY_SETTINGS_FRAME_PAYLOAD
+        //
+        //  All other control frames will use the alternate route directly to
+        //  SPDY_CONTROL_FRAME_PAYLOAD
+        int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+
+      case SPDY_SETTINGS_FRAME_PAYLOAD: {
+        int bytes_read = ProcessSettingsFramePayload(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+
+      case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
+        int bytes_read = ProcessControlFrameHeaderBlock(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+
+      case SPDY_CREDENTIAL_FRAME_PAYLOAD: {
+        size_t bytes_read = ProcessCredentialFramePayload(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+
+      case SPDY_CONTROL_FRAME_PAYLOAD: {
+        size_t bytes_read = ProcessControlFramePayload(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+
+      case SPDY_IGNORE_REMAINING_PAYLOAD:
+        // control frame has too-large payload
+        // intentional fallthrough
+      case SPDY_FORWARD_STREAM_FRAME: {
+        size_t bytes_read = ProcessDataFramePayload(data, len);
+        len -= bytes_read;
+        data += bytes_read;
+        break;
+      }
+      default:
+        LOG(DFATAL) << "Invalid value for " << display_protocol_
+                    << " framer state: " << state_;
+        // This ensures that we don't infinite-loop if state_ gets an
+        // invalid value somehow, such as due to a SpdyFramer getting deleted
+        // from a callback it calls.
+        goto bottom;
+    }
+  } while (state_ != previous_state_);
+ bottom:
+  DCHECK(len == 0 || state_ == SPDY_ERROR);
+  if (current_frame_len_ == 0 &&
+      remaining_data_ == 0 &&
+      remaining_control_payload_ == 0 &&
+      remaining_control_header_ == 0) {
+    DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR)
+        << "State: " << StateToString(state_);
+  }
+
+  return original_len - len;
+}
+
+size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
+  // This should only be called when we're in the SPDY_READING_COMMON_HEADER
+  // state.
+  DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);
+
+  size_t original_len = len;
+  SpdyFrame current_frame(current_frame_buffer_.get(), false);
+
+  // Update current frame buffer as needed.
+  if (current_frame_len_ < SpdyFrame::kHeaderSize) {
+    size_t bytes_desired = SpdyFrame::kHeaderSize - current_frame_len_;
+    UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
+  }
+
+  if (current_frame_len_ < SpdyFrame::kHeaderSize) {
+    // TODO(rch): remove this empty block
+    // Do nothing.
+  } else {
+    remaining_data_ = current_frame.length();
+
+    // This is just a sanity check for help debugging early frame errors.
+    if (remaining_data_ > 1000000u) {
+      // The strncmp for 5 is safe because we only hit this point if we
+      // have SpdyFrame::kHeaderSize (8) bytes
+      if (!syn_frame_processed_ &&
+          strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
+        LOG(WARNING) << "Unexpected HTTP response to spdy request";
+        probable_http_response_ = true;
+      } else {
+        LOG(WARNING) << "Unexpectedly large frame.  " << display_protocol_
+                     << " session is likely corrupt.";
+      }
+    }
+
+    // if we're here, then we have the common header all received.
+    if (!current_frame.is_control_frame()) {
+      SpdyDataFrame data_frame(current_frame_buffer_.get(), false);
+      visitor_->OnDataFrameHeader(&data_frame);
+
+      if (current_frame.length() > 0) {
+        CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
+      } else {
+        // Empty data frame.
+        if (current_frame.flags() & DATA_FLAG_FIN) {
+          visitor_->OnStreamFrameData(data_frame.stream_id(),
+                                      NULL, 0, DATA_FLAG_FIN);
+        }
+        CHANGE_STATE(SPDY_AUTO_RESET);
+      }
+    } else {
+      ProcessControlFrameHeader();
+    }
+  }
+  return original_len - len;
+}
+
+void SpdyFramer::ProcessControlFrameHeader() {
+  DCHECK_EQ(SPDY_NO_ERROR, error_code_);
+  DCHECK_LE(static_cast<size_t>(SpdyFrame::kHeaderSize), current_frame_len_);
+  SpdyControlFrame current_control_frame(current_frame_buffer_.get(), false);
+
+  // We check version before we check validity: version can never be 'invalid',
+  // it can only be unsupported.
+  if (current_control_frame.version() != spdy_version_) {
+    DLOG(INFO) << "Unsupported SPDY version " << current_control_frame.version()
+               << " (expected " << spdy_version_ << ")";
+    set_error(SPDY_UNSUPPORTED_VERSION);
+    return;
+  }
+
+  // Next up, check to see if we have valid data.  This should be after version
+  // checking (otherwise if the the type were out of bounds due to a version
+  // upgrade we would misclassify the error) and before checking the type
+  // (type can definitely be out of bounds)
+  if (!current_control_frame.AppearsToBeAValidControlFrame()) {
+    set_error(SPDY_INVALID_CONTROL_FRAME);
+    return;
+  }
+
+  if (current_control_frame.type() == NOOP) {
+    DLOG(INFO) << "NOOP control frame found. Ignoring.";
+    CHANGE_STATE(SPDY_AUTO_RESET);
+    return;
+  }
+
+  // Do some sanity checking on the control frame sizes.
+  switch (current_control_frame.type()) {
+    case SYN_STREAM:
+      if (current_control_frame.length() <
+          SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    case SYN_REPLY:
+      if (current_control_frame.length() <
+          SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    case RST_STREAM:
+      if (current_control_frame.length() !=
+          SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    case SETTINGS:
+      // Make sure that we have an integral number of 8-byte key/value pairs,
+      // plus a 4-byte length field.
+      if (current_control_frame.length() <
+          SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize ||
+          (current_control_frame.length() % 8 != 4)) {
+        DLOG(WARNING) << "Invalid length for SETTINGS frame: "
+                      << current_control_frame.length();
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      }
+      break;
+    case GOAWAY:
+      {
+        // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account
+        // for this difference via a separate offset variable, since
+        // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
+        const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
+        if (current_control_frame.length() + goaway_offset !=
+            SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize)
+          set_error(SPDY_INVALID_CONTROL_FRAME);
+        break;
+      }
+    case HEADERS:
+      if (current_control_frame.length() <
+          SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    case WINDOW_UPDATE:
+      if (current_control_frame.length() !=
+          SpdyWindowUpdateControlFrame::size() -
+          SpdyControlFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    case PING:
+      if (current_control_frame.length() !=
+          SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    case CREDENTIAL:
+      if (current_control_frame.length() <
+          SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize)
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+    default:
+      LOG(WARNING) << "Valid " << display_protocol_
+                   << " control frame with unhandled type: "
+                   << current_control_frame.type();
+      DLOG(FATAL);
+      set_error(SPDY_INVALID_CONTROL_FRAME);
+      break;
+  }
+
+  if (state_ == SPDY_ERROR) {
+    return;
+  }
+
+  remaining_control_payload_ = current_control_frame.length();
+  const size_t total_frame_size =
+      remaining_control_payload_ + SpdyFrame::kHeaderSize;
+  if (total_frame_size > kMaxControlFrameSize) {
+    DLOG(WARNING) << "Received control frame with way too big of a payload: "
+                  << total_frame_size;
+    set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
+    return;
+  }
+
+  if (current_control_frame.type() == CREDENTIAL) {
+    CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD);
+    return;
+  }
+
+  // Determine the frame size without variable-length data.
+  int32 frame_size_without_variable_data;
+  switch (current_control_frame.type()) {
+    case SYN_STREAM:
+      syn_frame_processed_ = true;
+      frame_size_without_variable_data = SpdySynStreamControlFrame::size();
+      break;
+    case SYN_REPLY:
+      syn_frame_processed_ = true;
+      frame_size_without_variable_data = SpdySynReplyControlFrame::size();
+      // SPDY 2 had two bytes of unused space preceeding payload.
+      if (spdy_version_ < 3) {
+        frame_size_without_variable_data += 2;
+      }
+      break;
+    case HEADERS:
+      frame_size_without_variable_data = SpdyHeadersControlFrame::size();
+      // SPDY 2 had two bytes of unused space preceeding payload.
+      if (spdy_version_ < 3) {
+        frame_size_without_variable_data += 2;
+      }
+      break;
+    case SETTINGS:
+      frame_size_without_variable_data = SpdySettingsControlFrame::size();
+      break;
+    default:
+      frame_size_without_variable_data = -1;
+      break;
+  }
+
+  if ((frame_size_without_variable_data == -1) &&
+      (total_frame_size > kControlFrameBufferSize)) {
+    // We should already be in an error state. Double-check.
+    DCHECK_EQ(SPDY_ERROR, state_);
+    if (state_ != SPDY_ERROR) {
+      LOG(DFATAL) << display_protocol_
+                  << " control frame buffer too small for fixed-length frame.";
+      set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
+    }
+    return;
+  }
+  if (frame_size_without_variable_data > 0) {
+    // We have a control frame with a header block. We need to parse the
+    // remainder of the control frame's header before we can parse the header
+    // block. The start of the header block varies with the control type.
+    DCHECK_GE(frame_size_without_variable_data,
+              static_cast<int32>(current_frame_len_));
+    remaining_control_header_ = frame_size_without_variable_data -
+        current_frame_len_;
+    remaining_control_payload_ += SpdyFrame::kHeaderSize -
+        frame_size_without_variable_data;
+    CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
+    return;
+  }
+
+  CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
+}
+
+size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
+                                            size_t max_bytes) {
+  size_t bytes_to_read = std::min(*len, max_bytes);
+  DCHECK_GE(kControlFrameBufferSize, current_frame_len_ + bytes_to_read);
+  memcpy(current_frame_buffer_.get() + current_frame_len_,
+         *data,
+         bytes_to_read);
+  current_frame_len_ += bytes_to_read;
+  *data += bytes_to_read;
+  *len -= bytes_to_read;
+  return bytes_to_read;
+}
+
+size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock* headers) const {
+  const size_t num_name_value_pairs_size
+      = (spdy_version_ < 3) ? sizeof(uint16) : sizeof(uint32);
+  const size_t length_of_name_size = num_name_value_pairs_size;
+  const size_t length_of_value_size = num_name_value_pairs_size;
+
+  size_t total_length = num_name_value_pairs_size;
+  for (SpdyHeaderBlock::const_iterator it = headers->begin();
+       it != headers->end();
+       ++it) {
+    // We add space for the length of the name and the length of the value as
+    // well as the length of the name and the length of the value.
+    total_length += length_of_name_size + it->first.size() +
+                    length_of_value_size + it->second.size();
+  }
+  return total_length;
+}
+
+void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
+                                  const SpdyHeaderBlock* headers) const {
+  if (spdy_version_ < 3) {
+    frame->WriteUInt16(headers->size());  // Number of headers.
+  } else {
+    frame->WriteUInt32(headers->size());  // Number of headers.
+  }
+  SpdyHeaderBlock::const_iterator it;
+  for (it = headers->begin(); it != headers->end(); ++it) {
+    bool wrote_header;
+    if (spdy_version_ < 3) {
+      wrote_header = frame->WriteString(it->first);
+      wrote_header &= frame->WriteString(it->second);
+    } else {
+      wrote_header = frame->WriteStringPiece32(it->first);
+      wrote_header &= frame->WriteStringPiece32(it->second);
+    }
+    DCHECK(wrote_header);
+  }
+}
+
+// TODO(phajdan.jr): Clean up after we no longer need
+// to workaround http://crbug.com/139744.
+#if !defined(USE_SYSTEM_ZLIB)
+
+// These constants are used by zlib to differentiate between normal data and
+// cookie data. Cookie data is handled specially by zlib when compressing.
+enum ZDataClass {
+  // kZStandardData is compressed normally, save that it will never match
+  // against any other class of data in the window.
+  kZStandardData = Z_CLASS_STANDARD,
+  // kZCookieData is compressed in its own Huffman blocks and only matches in
+  // its entirety and only against other kZCookieData blocks. Any matches must
+  // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
+  // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
+  // prefix matches.
+  kZCookieData = Z_CLASS_COOKIE,
+  // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
+  // against the window.
+  kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
+};
+
+// WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
+// needed when switching between classes of data.
+static void WriteZ(const base::StringPiece& data,
+                   ZDataClass clas,
+                   z_stream* out) {
+  int rv;
+
+  // If we are switching from standard to non-standard data then we need to end
+  // the current Huffman context to avoid it leaking between them.
+  if (out->clas == kZStandardData &&
+      clas != kZStandardData) {
+    out->avail_in = 0;
+    rv = deflate(out, Z_PARTIAL_FLUSH);
+    DCHECK_EQ(Z_OK, rv);
+    DCHECK_EQ(0u, out->avail_in);
+    DCHECK_LT(0u, out->avail_out);
+  }
+
+  out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
+  out->avail_in = data.size();
+  out->clas = clas;
+  if (clas == kZStandardData) {
+    rv = deflate(out, Z_NO_FLUSH);
+  } else {
+    rv = deflate(out, Z_PARTIAL_FLUSH);
+  }
+  DCHECK_EQ(Z_OK, rv);
+  DCHECK_EQ(0u, out->avail_in);
+  DCHECK_LT(0u, out->avail_out);
+}
+
+// WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
+static void WriteLengthZ(size_t n,
+                         unsigned length,
+                         ZDataClass clas,
+                         z_stream* out) {
+  char buf[4];
+  DCHECK_LE(length, sizeof(buf));
+  for (unsigned i = 1; i <= length; i++) {
+    buf[length - i] = n;
+    n >>= 8;
+  }
+  WriteZ(base::StringPiece(buf, length), clas, out);
+}
+
+// WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
+// manner that resists the length of the compressed data from compromising
+// cookie data.
+void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
+                                     z_stream* z) const {
+  unsigned length_length = 4;
+  if (spdy_version_ < 3)
+    length_length = 2;
+
+  WriteLengthZ(headers->size(), length_length, kZStandardData, z);
+
+  std::map<std::string, std::string>::const_iterator it;
+  for (it = headers->begin(); it != headers->end(); ++it) {
+    WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
+    WriteZ(it->first, kZStandardData, z);
+
+    if (it->first == "cookie") {
+      // We require the cookie values (save for the last) to end with a
+      // semicolon and (save for the first) to start with a space. This is
+      // typically the format that we are given them in but we reserialize them
+      // to be sure.
+
+      std::vector<base::StringPiece> cookie_values;
+      size_t cookie_length = 0;
+      base::StringPiece cookie_data(it->second);
+
+      for (;;) {
+        while (!cookie_data.empty() &&
+               (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
+          cookie_data.remove_prefix(1);
+        }
+        if (cookie_data.empty())
+          break;
+
+        size_t i;
+        for (i = 0; i < cookie_data.size(); i++) {
+          if (cookie_data[i] == ';')
+            break;
+        }
+        if (i < cookie_data.size()) {
+          cookie_values.push_back(cookie_data.substr(0, i));
+          cookie_length += i + 2 /* semicolon and space */;
+          cookie_data.remove_prefix(i + 1);
+        } else {
+          cookie_values.push_back(cookie_data);
+          cookie_length += cookie_data.size();
+          cookie_data.remove_prefix(i);
+        }
+      }
+
+      WriteLengthZ(cookie_length, length_length, kZStandardData, z);
+      for (size_t i = 0; i < cookie_values.size(); i++) {
+        std::string cookie;
+        // Since zlib will only back-reference complete cookies, a cookie that
+        // is currently last (and so doesn't have a trailing semicolon) won't
+        // match if it's later in a non-final position. The same is true of
+        // the first cookie.
+        if (i == 0 && cookie_values.size() == 1) {
+          cookie = cookie_values[i].as_string();
+        } else if (i == 0) {
+          cookie = cookie_values[i].as_string() + ";";
+        } else if (i < cookie_values.size() - 1) {
+          cookie = " " + cookie_values[i].as_string() + ";";
+        } else {
+          cookie = " " + cookie_values[i].as_string();
+        }
+        WriteZ(cookie, kZCookieData, z);
+      }
+    } else if (it->first == "accept" ||
+               it->first == "accept-charset" ||
+               it->first == "accept-encoding" ||
+               it->first == "accept-language" ||
+               it->first == "host" ||
+               it->first == "version" ||
+               it->first == "method" ||
+               it->first == "scheme" ||
+               it->first == ":host" ||
+               it->first == ":version" ||
+               it->first == ":method" ||
+               it->first == ":scheme" ||
+               it->first == "user-agent") {
+      WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
+      WriteZ(it->second, kZStandardData, z);
+    } else {
+      // Non-whitelisted headers are Huffman compressed in their own block, but
+      // don't match against the window.
+      WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
+      WriteZ(it->second, kZHuffmanOnlyData, z);
+    }
+  }
+
+  z->avail_in = 0;
+  int rv = deflate(z, Z_SYNC_FLUSH);
+  DCHECK_EQ(Z_OK, rv);
+  z->clas = kZStandardData;
+}
+#endif  // !defined(USE_SYSTEM_ZLIB)
+
+size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
+                                                        size_t len) {
+  DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
+  size_t original_len = len;
+
+  if (remaining_control_header_ > 0) {
+    size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
+                                                 remaining_control_header_);
+    remaining_control_header_ -= bytes_read;
+  }
+
+  if (remaining_control_header_ == 0) {
+    SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
+    switch (control_frame.type()) {
+      case SYN_STREAM:
+        {
+          SpdySynStreamControlFrame* syn_stream_frame =
+              reinterpret_cast<SpdySynStreamControlFrame*>(&control_frame);
+          // TODO(hkhalil): Check that invalid flag bits are unset?
+          visitor_->OnSynStream(
+              syn_stream_frame->stream_id(),
+              syn_stream_frame->associated_stream_id(),
+              syn_stream_frame->priority(),
+              syn_stream_frame->credential_slot(),
+              (syn_stream_frame->flags() & CONTROL_FLAG_FIN) != 0,
+              (syn_stream_frame->flags() & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
+        }
+        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
+        break;
+      case SYN_REPLY:
+        {
+          SpdySynReplyControlFrame* syn_reply_frame =
+              reinterpret_cast<SpdySynReplyControlFrame*>(&control_frame);
+          visitor_->OnSynReply(
+              syn_reply_frame->stream_id(),
+              (syn_reply_frame->flags() & CONTROL_FLAG_FIN) != 0);
+        }
+        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
+        break;
+      case HEADERS:
+        {
+          SpdyHeadersControlFrame* headers_frame =
+              reinterpret_cast<SpdyHeadersControlFrame*>(&control_frame);
+          visitor_->OnHeaders(
+              headers_frame->stream_id(),
+              (headers_frame->flags() & CONTROL_FLAG_FIN) != 0);
+        }
+        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
+        break;
+      case SETTINGS:
+        CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
+        break;
+      default:
+        DCHECK(false);
+    }
+  }
+  return original_len - len;
+}
+
+// Does not buffer the control payload. Instead, either passes directly to the
+// visitor or decompresses and then passes directly to the visitor, via
+// IncrementallyDeliverControlFrameHeaderData() or
+// IncrementallyDecompressControlFrameHeaderData() respectively.
+size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
+                                                  size_t data_len) {
+  DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
+  SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
+
+  bool processed_successfully = true;
+  DCHECK(control_frame.type() == SYN_STREAM ||
+         control_frame.type() == SYN_REPLY ||
+         control_frame.type() == HEADERS);
+  size_t process_bytes = std::min(data_len, remaining_control_payload_);
+  if (process_bytes > 0) {
+    if (enable_compression_) {
+      processed_successfully = IncrementallyDecompressControlFrameHeaderData(
+          &control_frame, data, process_bytes);
+    } else {
+      processed_successfully = IncrementallyDeliverControlFrameHeaderData(
+          &control_frame, data, process_bytes);
+    }
+
+    remaining_control_payload_ -= process_bytes;
+    remaining_data_ -= process_bytes;
+  }
+
+  // Handle the case that there is no futher data in this frame.
+  if (remaining_control_payload_ == 0 && processed_successfully) {
+    // The complete header block has been delivered. We send a zero-length
+    // OnControlFrameHeaderData() to indicate this.
+    visitor_->OnControlFrameHeaderData(
+        GetControlFrameStreamId(&control_frame), NULL, 0);
+
+    // If this is a FIN, tell the caller.
+    if (control_frame.flags() & CONTROL_FLAG_FIN) {
+      visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame),
+                                  NULL, 0, DATA_FLAG_FIN);
+    }
+
+    CHANGE_STATE(SPDY_AUTO_RESET);
+  }
+
+  // Handle error.
+  if (!processed_successfully) {
+    return data_len;
+  }
+
+  // Return amount processed.
+  return process_bytes;
+}
+
+size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
+                                               size_t data_len) {
+  DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
+  SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
+  DCHECK_EQ(SETTINGS, control_frame.type());
+  size_t unprocessed_bytes = std::min(data_len, remaining_control_payload_);
+  size_t processed_bytes = 0;
+
+  // Loop over our incoming data.
+  while (unprocessed_bytes > 0) {
+    // Process up to one setting at a time.
+    size_t processing = std::min(
+        unprocessed_bytes,
+        static_cast<size_t>(8 - settings_scratch_.setting_buf_len));
+
+    // Check if we have a complete setting in our input.
+    if (processing == 8) {
+      // Parse the setting directly out of the input without buffering.
+      if (!ProcessSetting(data + processed_bytes)) {
+        set_error(SPDY_INVALID_CONTROL_FRAME);
+        return processed_bytes;
+      }
+    } else {
+      // Continue updating settings_scratch_.setting_buf.
+      memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
+             data + processed_bytes,
+             processing);
+      settings_scratch_.setting_buf_len += processing;
+
+      // Check if we have a complete setting buffered.
+      if (settings_scratch_.setting_buf_len == 8) {
+        if (!ProcessSetting(settings_scratch_.setting_buf)) {
+          set_error(SPDY_INVALID_CONTROL_FRAME);
+          return processed_bytes;
+        }
+        // Reset settings_scratch_.setting_buf for our next setting.
+        settings_scratch_.setting_buf_len = 0;
+      }
+    }
+
+    // Iterate.
+    unprocessed_bytes -= processing;
+    processed_bytes += processing;
+  }
+
+  // Check if we're done handling this SETTINGS frame.
+  remaining_control_payload_ -= processed_bytes;
+  if (remaining_control_payload_ == 0) {
+    CHANGE_STATE(SPDY_AUTO_RESET);
+  }
+
+  return processed_bytes;
+}
+
+bool SpdyFramer::ProcessSetting(const char* data) {
+  // Extract fields.
+  // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
+  const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
+  SettingsFlagsAndId id_and_flags =
+      SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire);
+  uint8 flags = id_and_flags.flags();
+  uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
+
+  // Validate id.
+  switch (id_and_flags.id()) {
+    case SETTINGS_UPLOAD_BANDWIDTH:
+    case SETTINGS_DOWNLOAD_BANDWIDTH:
+    case SETTINGS_ROUND_TRIP_TIME:
+    case SETTINGS_MAX_CONCURRENT_STREAMS:
+    case SETTINGS_CURRENT_CWND:
+    case SETTINGS_DOWNLOAD_RETRANS_RATE:
+    case SETTINGS_INITIAL_WINDOW_SIZE:
+      // Valid values.
+      break;
+    default:
+      DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id();
+      return false;
+  }
+  SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id());
+
+  // Detect duplciates.
+  if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) {
+    DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
+                  << " in " << display_protocol_ << " SETTINGS frame "
+                  << "(last settikng id was "
+                  << settings_scratch_.last_setting_id << ").";
+    return false;
+  }
+  settings_scratch_.last_setting_id = id;
+
+  // Validate flags.
+  uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
+  if ((flags & ~(kFlagsMask)) != 0) {
+    DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
+                  << flags;
+    return false;
+  }
+
+  // Validation succeeded. Pass on to visitor.
+  visitor_->OnSetting(id, flags, value);
+  return true;
+}
+
+size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
+  size_t original_len = len;
+  if (remaining_control_payload_) {
+    size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
+                                                 remaining_control_payload_);
+    remaining_control_payload_ -= bytes_read;
+    remaining_data_ -= bytes_read;
+    if (remaining_control_payload_ == 0) {
+      SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
+      DCHECK(!control_frame.has_header_block());
+      // Use frame-specific handlers.
+      switch (control_frame.type()) {
+        case PING: {
+            SpdyPingControlFrame* ping_frame =
+                reinterpret_cast<SpdyPingControlFrame*>(&control_frame);
+            visitor_->OnPing(ping_frame->unique_id());
+          }
+          break;
+        case WINDOW_UPDATE: {
+            SpdyWindowUpdateControlFrame *window_update_frame =
+                reinterpret_cast<SpdyWindowUpdateControlFrame*>(&control_frame);
+            visitor_->OnWindowUpdate(window_update_frame->stream_id(),
+                                     window_update_frame->delta_window_size());
+          }
+          break;
+        case RST_STREAM: {
+            SpdyRstStreamControlFrame* rst_stream_frame =
+                reinterpret_cast<SpdyRstStreamControlFrame*>(&control_frame);
+            visitor_->OnRstStream(rst_stream_frame->stream_id(),
+                                  rst_stream_frame->status());
+          }
+          break;
+        case GOAWAY: {
+            SpdyGoAwayControlFrame* go_away_frame =
+                reinterpret_cast<SpdyGoAwayControlFrame*>(&control_frame);
+            if (spdy_version_ < 3) {
+              visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(),
+                                 GOAWAY_OK);
+            } else {
+              visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(),
+                                 go_away_frame->status());
+            }
+          }
+          break;
+        default:
+          // Unreachable.
+          LOG(FATAL) << "Unhandled control frame " << control_frame.type();
+      }
+
+      CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
+    }
+  }
+  return original_len - len;
+}
+
+size_t SpdyFramer::ProcessCredentialFramePayload(const char* data, size_t len) {
+  if (len > 0) {
+    // Process only up to the end of this CREDENTIAL frame.
+    len = std::min(len, remaining_control_payload_);
+    bool processed_succesfully = visitor_->OnCredentialFrameData(data, len);
+    remaining_control_payload_ -= len;
+    remaining_data_ -= len;
+    if (!processed_succesfully) {
+      set_error(SPDY_CREDENTIAL_FRAME_CORRUPT);
+    } else if (remaining_control_payload_ == 0) {
+      visitor_->OnCredentialFrameData(NULL, 0);
+      CHANGE_STATE(SPDY_AUTO_RESET);
+    }
+  }
+  return len;
+}
+
+size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
+  size_t original_len = len;
+
+  SpdyDataFrame current_data_frame(current_frame_buffer_.get(), false);
+  if (remaining_data_ > 0) {
+    size_t amount_to_forward = std::min(remaining_data_, len);
+    if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
+      // Only inform the visitor if there is data.
+      if (amount_to_forward) {
+        visitor_->OnStreamFrameData(current_data_frame.stream_id(),
+                                    data, amount_to_forward, SpdyDataFlags());
+      }
+    }
+    data += amount_to_forward;
+    len -= amount_to_forward;
+    remaining_data_ -= amount_to_forward;
+
+    // If the FIN flag is set, and there is no more data in this data
+    // frame, inform the visitor of EOF via a 0-length data frame.
+    if (!remaining_data_ &&
+        current_data_frame.flags() & DATA_FLAG_FIN) {
+      visitor_->OnStreamFrameData(current_data_frame.stream_id(),
+                                  NULL, 0, DATA_FLAG_FIN);
+    }
+  }
+
+  if (remaining_data_ == 0) {
+    CHANGE_STATE(SPDY_AUTO_RESET);
+  }
+  return original_len - len;
+}
+
+bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
+                                          size_t header_length,
+                                          SpdyHeaderBlock* block) const {
+  SpdyFrameReader reader(header_data, header_length);
+
+  // Read number of headers.
+  uint32 num_headers;
+  if (spdy_version_ < 3) {
+    uint16 temp;
+    if (!reader.ReadUInt16(&temp)) {
+      DLOG(INFO) << "Unable to read number of headers.";
+      return false;
+    }
+    num_headers = temp;
+  } else {
+    if (!reader.ReadUInt32(&num_headers)) {
+      DLOG(INFO) << "Unable to read number of headers.";
+      return false;
+    }
+  }
+
+  // Read each header.
+  for (uint32 index = 0; index < num_headers; ++index) {
+    base::StringPiece temp;
+
+    // Read header name.
+    if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
+                            : !reader.ReadStringPiece32(&temp)) {
+      DLOG(INFO) << "Unable to read header name (" << index + 1 << " of "
+                 << num_headers << ").";
+      return false;
+    }
+    std::string name = temp.as_string();
+
+    // Read header value.
+    if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
+                            : !reader.ReadStringPiece32(&temp)) {
+      DLOG(INFO) << "Unable to read header value (" << index + 1 << " of "
+                 << num_headers << ").";
+      return false;
+    }
+    std::string value = temp.as_string();
+
+    // Ensure no duplicates.
+    if (block->find(name) != block->end()) {
+      DLOG(INFO) << "Duplicate header '" << name << "' (" << index + 1 << " of "
+                 << num_headers << ").";
+      return false;
+    }
+
+    // Store header.
+    (*block)[name] = value;
+  }
+  return true;
+}
+
+// TODO(hkhalil): Remove, or move to test utils kit.
+/* static */
+bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame,
+                               SettingsMap* settings) {
+  DCHECK_EQ(frame->type(), SETTINGS);
+  DCHECK(settings);
+
+  SpdyFrameReader parser(frame->header_block(), frame->header_block_len());
+  for (size_t index = 0; index < frame->num_entries(); ++index) {
+    uint32 id_and_flags_wire;
+    uint32 value;
+    // SettingsFlagsAndId accepts off-the-wire (network byte order) data, so we
+    // use ReadBytes() instead of ReadUInt32() as the latter calls ntohl().
+    if (!parser.ReadBytes(&id_and_flags_wire, 4)) {
+      return false;
+    }
+    if (!parser.ReadUInt32(&value))
+      return false;
+    SettingsFlagsAndId flags_and_id =
+        SettingsFlagsAndId::FromWireFormat(frame->version(), id_and_flags_wire);
+    SpdySettingsIds id = static_cast<SpdySettingsIds>(flags_and_id.id());
+    SpdySettingsFlags flags =
+        static_cast<SpdySettingsFlags>(flags_and_id.flags());
+    (*settings)[id] = SettingsFlagsAndValue(flags, value);
+  }
+  return true;
+}
+
+/* static */
+bool SpdyFramer::ParseCredentialData(const char* data, size_t len,
+                                     SpdyCredential* credential) {
+  DCHECK(credential);
+
+  SpdyFrameReader parser(data, len);
+  base::StringPiece temp;
+  if (!parser.ReadUInt16(&credential->slot)) {
+    return false;
+  }
+
+  if (!parser.ReadStringPiece32(&temp)) {
+    return false;
+  }
+  credential->proof = temp.as_string();
+
+  while (!parser.IsDoneReading()) {
+    if (!parser.ReadStringPiece32(&temp)) {
+      return false;
+    }
+    credential->certs.push_back(temp.as_string());
+  }
+  return true;
+}
+
+SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
+    SpdyStreamId stream_id,
+    SpdyStreamId associated_stream_id,
+    SpdyPriority priority,
+    uint8 credential_slot,
+    SpdyControlFlags flags,
+    bool compressed,
+    const SpdyHeaderBlock* headers) {
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask);
+
+  // Find our length.
+  size_t frame_size = SpdySynStreamControlFrame::size() +
+                      GetSerializedLength(headers);
+
+  SpdyFrameBuilder frame(SYN_STREAM, flags, spdy_version_, frame_size);
+  frame.WriteUInt32(stream_id);
+  frame.WriteUInt32(associated_stream_id);
+  // Cap as appropriate.
+  if (priority > GetLowestPriority()) {
+    DLOG(DFATAL) << "Priority out-of-bounds.";
+    priority = GetLowestPriority();
+  }
+  // Priority is 2 bits for <spdy3, 3 bits otherwise.
+  frame.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
+  frame.WriteUInt8((spdy_version_ < 3) ? 0 : credential_slot);
+  WriteHeaderBlock(&frame, headers);
+  DCHECK_EQ(frame.length(), frame_size);
+
+  scoped_ptr<SpdySynStreamControlFrame> syn_frame(
+      reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
+  if (compressed) {
+    return reinterpret_cast<SpdySynStreamControlFrame*>(
+        CompressControlFrame(*syn_frame.get(), headers));
+  }
+  return syn_frame.release();
+}
+
+SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
+    SpdyStreamId stream_id,
+    SpdyControlFlags flags,
+    bool compressed,
+    const SpdyHeaderBlock* headers) {
+  DCHECK_GT(stream_id, 0u);
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+
+  // Find our length.
+  size_t frame_size = SpdySynReplyControlFrame::size() +
+                      GetSerializedLength(headers);
+  // In SPDY 2, there were 2 unused bytes before payload.
+  if (spdy_version_ < 3) {
+    frame_size += 2;
+  }
+
+  SpdyFrameBuilder frame(SYN_REPLY, flags, spdy_version_, frame_size);
+  frame.WriteUInt32(stream_id);
+  if (spdy_version_ < 3) {
+    frame.WriteUInt16(0);  // Unused
+  }
+  WriteHeaderBlock(&frame, headers);
+  DCHECK_EQ(frame.length(), frame_size);
+
+  scoped_ptr<SpdySynReplyControlFrame> reply_frame(
+      reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
+  if (compressed) {
+    return reinterpret_cast<SpdySynReplyControlFrame*>(
+        CompressControlFrame(*reply_frame.get(), headers));
+  }
+  return reply_frame.release();
+}
+
+SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(
+    SpdyStreamId stream_id,
+    SpdyStatusCodes status) const {
+  DCHECK_GT(stream_id, 0u);
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  DCHECK_NE(status, INVALID);
+  DCHECK_LT(status, NUM_STATUS_CODES);
+
+  size_t frame_size = SpdyRstStreamControlFrame::size();
+  SpdyFrameBuilder frame(RST_STREAM, CONTROL_FLAG_NONE, spdy_version_,
+                         frame_size);
+  frame.WriteUInt32(stream_id);
+  frame.WriteUInt32(status);
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take());
+}
+
+SpdySettingsControlFrame* SpdyFramer::CreateSettings(
+    const SettingsMap& values) const {
+  size_t frame_size = SpdySettingsControlFrame::size() + 8 * values.size();
+  SpdyFrameBuilder frame(SETTINGS, CONTROL_FLAG_NONE, spdy_version_,
+                         frame_size);
+  frame.WriteUInt32(values.size());
+  for (SettingsMap::const_iterator it = values.begin();
+       it != values.end();
+       it++) {
+    SettingsFlagsAndId flags_and_id(it->second.first, it->first);
+    uint32 id_and_flags_wire = flags_and_id.GetWireFormat(spdy_version_);
+    frame.WriteBytes(&id_and_flags_wire, 4);
+    frame.WriteUInt32(it->second.second);
+  }
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdySettingsControlFrame*>(frame.take());
+}
+
+SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
+  size_t frame_size = SpdyPingControlFrame::size();
+  SpdyFrameBuilder frame(PING, CONTROL_FLAG_NONE, spdy_version_, frame_size);
+  frame.WriteUInt32(unique_id);
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdyPingControlFrame*>(frame.take());
+}
+
+SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway(
+    SpdyStreamId last_accepted_stream_id,
+    SpdyGoAwayStatus status) const {
+  DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask);
+
+  // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account for
+  // this difference via a separate offset variable, since
+  // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
+  const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
+  size_t frame_size = SpdyGoAwayControlFrame::size() - goaway_offset;
+  SpdyFrameBuilder frame(GOAWAY, CONTROL_FLAG_NONE, spdy_version_, frame_size);
+  frame.WriteUInt32(last_accepted_stream_id);
+  if (protocol_version() >= 3) {
+    frame.WriteUInt32(status);
+  }
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take());
+}
+
+SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(
+    SpdyStreamId stream_id,
+    SpdyControlFlags flags,
+    bool compressed,
+    const SpdyHeaderBlock* headers) {
+  // Basically the same as CreateSynReply().
+  DCHECK_GT(stream_id, 0u);
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+
+  // Find our length.
+  size_t frame_size = SpdyHeadersControlFrame::size() +
+                      GetSerializedLength(headers);
+  // In SPDY 2, there were 2 unused bytes before payload.
+  if (spdy_version_ < 3) {
+    frame_size += 2;
+  }
+
+  SpdyFrameBuilder frame(HEADERS, flags, spdy_version_, frame_size);
+  frame.WriteUInt32(stream_id);
+  if (spdy_version_ < 3) {
+    frame.WriteUInt16(0);  // Unused
+  }
+  WriteHeaderBlock(&frame, headers);
+  DCHECK_EQ(frame.length(), frame_size);
+
+  scoped_ptr<SpdyHeadersControlFrame> headers_frame(
+      reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
+  if (compressed) {
+    return reinterpret_cast<SpdyHeadersControlFrame*>(
+        CompressControlFrame(*headers_frame.get(), headers));
+  }
+  return headers_frame.release();
+}
+
+SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate(
+    SpdyStreamId stream_id,
+    uint32 delta_window_size) const {
+  DCHECK_GT(stream_id, 0u);
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  DCHECK_GT(delta_window_size, 0u);
+  DCHECK_LE(delta_window_size,
+            static_cast<uint32>(kSpdyStreamMaximumWindowSize));
+
+  size_t frame_size = SpdyWindowUpdateControlFrame::size();
+  SpdyFrameBuilder frame(WINDOW_UPDATE, CONTROL_FLAG_NONE, spdy_version_,
+                         frame_size);
+  frame.WriteUInt32(stream_id);
+  frame.WriteUInt32(delta_window_size);
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take());
+}
+
+SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame(
+    const SpdyCredential& credential) const {
+  // Calculate the size of the frame by adding the size of the
+  // variable length data to the size of the fixed length data.
+  size_t frame_size =  SpdyCredentialControlFrame::size() +
+      credential.proof.length();
+  DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u);
+  for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
+       cert != credential.certs.end();
+       ++cert) {
+    frame_size += sizeof(uint32);  // size of the cert_length field
+    frame_size += cert->length();     // size of the cert_data field
+  }
+
+  SpdyFrameBuilder frame(CREDENTIAL, CONTROL_FLAG_NONE, spdy_version_,
+                         frame_size);
+  frame.WriteUInt16(credential.slot);
+  frame.WriteUInt32(credential.proof.size());
+  frame.WriteBytes(credential.proof.c_str(), credential.proof.size());
+  for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
+       cert != credential.certs.end();
+       ++cert) {
+    frame.WriteUInt32(cert->length());
+    frame.WriteBytes(cert->c_str(), cert->length());
+  }
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take());
+}
+
+SpdyDataFrame* SpdyFramer::CreateDataFrame(
+    SpdyStreamId stream_id,
+                                           const char* data,
+    uint32 len, SpdyDataFlags flags) const {
+  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  size_t frame_size = SpdyDataFrame::size() + len;
+  SpdyFrameBuilder frame(stream_id, flags, frame_size);
+  frame.WriteBytes(data, len);
+  DCHECK_EQ(frame.length(), frame_size);
+  return reinterpret_cast<SpdyDataFrame*>(frame.take());
+}
+
+// The following compression setting are based on Brian Olson's analysis. See
+// https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792
+// for more details.
+#if defined(USE_SYSTEM_ZLIB)
+// System zlib is not expected to have workaround for http://crbug.com/139744,
+// so disable compression in that case.
+// TODO(phajdan.jr): Remove the special case when it's no longer necessary.
+static const int kCompressorLevel = 0;
+#else  // !defined(USE_SYSTEM_ZLIB)
+static const int kCompressorLevel = 9;
+#endif  // !defined(USE_SYSTEM_ZLIB)
+static const int kCompressorWindowSizeInBits = 11;
+static const int kCompressorMemLevel = 1;
+
+z_stream* SpdyFramer::GetHeaderCompressor() {
+  if (header_compressor_.get())
+    return header_compressor_.get();  // Already initialized.
+
+  header_compressor_.reset(new z_stream);
+  memset(header_compressor_.get(), 0, sizeof(z_stream));
+
+  int success = deflateInit2(header_compressor_.get(),
+                             kCompressorLevel,
+                             Z_DEFLATED,
+                             kCompressorWindowSizeInBits,
+                             kCompressorMemLevel,
+                             Z_DEFAULT_STRATEGY);
+  if (success == Z_OK) {
+    const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
+                                                 : kV3Dictionary;
+    const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
+                                                    : kV3DictionarySize;
+    success = deflateSetDictionary(header_compressor_.get(),
+                                   reinterpret_cast<const Bytef*>(dictionary),
+                                   dictionary_size);
+  }
+  if (success != Z_OK) {
+    LOG(WARNING) << "deflateSetDictionary failure: " << success;
+    header_compressor_.reset(NULL);
+    return NULL;
+  }
+  return header_compressor_.get();
+}
+
+z_stream* SpdyFramer::GetHeaderDecompressor() {
+  if (header_decompressor_.get())
+    return header_decompressor_.get();  // Already initialized.
+
+  header_decompressor_.reset(new z_stream);
+  memset(header_decompressor_.get(), 0, sizeof(z_stream));
+
+  int success = inflateInit(header_decompressor_.get());
+  if (success != Z_OK) {
+    LOG(WARNING) << "inflateInit failure: " << success;
+    header_decompressor_.reset(NULL);
+    return NULL;
+  }
+  return header_decompressor_.get();
+}
+
+bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame,
+                                    int* payload_length,
+                                    int* header_length,
+                                    const char** payload) const {
+  size_t frame_size;
+  if (frame.is_control_frame()) {
+    const SpdyControlFrame& control_frame =
+        reinterpret_cast<const SpdyControlFrame&>(frame);
+    switch (control_frame.type()) {
+      case SYN_STREAM:
+        {
+          const SpdySynStreamControlFrame& syn_frame =
+              reinterpret_cast<const SpdySynStreamControlFrame&>(frame);
+          frame_size = SpdySynStreamControlFrame::size();
+          *payload_length = syn_frame.header_block_len();
+          *header_length = frame_size;
+          *payload = frame.data() + *header_length;
+        }
+        break;
+      case SYN_REPLY:
+        {
+          const SpdySynReplyControlFrame& syn_frame =
+              reinterpret_cast<const SpdySynReplyControlFrame&>(frame);
+          frame_size = SpdySynReplyControlFrame::size();
+          *payload_length = syn_frame.header_block_len();
+          *header_length = frame_size;
+          *payload = frame.data() + *header_length;
+          // SPDY 2 had two bytes of unused space preceeding payload.
+          if (spdy_version_ < 3) {
+            *header_length += 2;
+            *payload += 2;
+          }
+        }
+        break;
+      case HEADERS:
+        {
+          const SpdyHeadersControlFrame& headers_frame =
+              reinterpret_cast<const SpdyHeadersControlFrame&>(frame);
+          frame_size = SpdyHeadersControlFrame::size();
+          *payload_length = headers_frame.header_block_len();
+          *header_length = frame_size;
+          *payload = frame.data() + *header_length;
+          // SPDY 2 had two bytes of unused space preceeding payload.
+          if (spdy_version_ < 3) {
+            *header_length += 2;
+            *payload += 2;
+          }
+        }
+        break;
+      default:
+        // TODO(mbelshe): set an error?
+        return false;  // We can't compress this frame!
+    }
+  } else {
+    frame_size = SpdyFrame::kHeaderSize;
+    *header_length = frame_size;
+    *payload_length = frame.length();
+    *payload = frame.data() + SpdyFrame::kHeaderSize;
+  }
+  return true;
+}
+
+SpdyControlFrame* SpdyFramer::CompressControlFrame(
+    const SpdyControlFrame& frame,
+    const SpdyHeaderBlock* headers) {
+  z_stream* compressor = GetHeaderCompressor();
+  if (!compressor)
+    return NULL;
+
+  int payload_length;
+  int header_length;
+  const char* payload;
+
+  base::StatsCounter compressed_frames("spdy.CompressedFrames");
+  base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
+  base::StatsCounter post_compress_bytes("spdy.PostCompressSize");
+
+  if (!enable_compression_)
+    return reinterpret_cast<SpdyControlFrame*>(DuplicateFrame(frame));
+
+  if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload))
+    return NULL;
+
+  // Create an output frame.
+  int compressed_max_size = deflateBound(compressor, payload_length);
+  // Since we'll be performing lots of flushes when compressing the data,
+  // zlib's lower bounds may be insufficient.
+  compressed_max_size *= 2;
+
+  size_t new_frame_size = header_length + compressed_max_size;
+  if ((frame.type() == SYN_REPLY || frame.type() == HEADERS) &&
+      spdy_version_ < 3) {
+    new_frame_size += 2;
+  }
+  DCHECK_GE(new_frame_size, frame.length() + SpdyFrame::kHeaderSize);
+  scoped_ptr<SpdyControlFrame> new_frame(new SpdyControlFrame(new_frame_size));
+  memcpy(new_frame->data(), frame.data(),
+         frame.length() + SpdyFrame::kHeaderSize);
+
+  // TODO(phajdan.jr): Clean up after we no longer need
+  // to workaround http://crbug.com/139744.
+#if defined(USE_SYSTEM_ZLIB)
+  compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
+  compressor->avail_in = payload_length;
+#endif  // defined(USE_SYSTEM_ZLIB)
+  compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) +
+                          header_length;
+  compressor->avail_out = compressed_max_size;
+  // TODO(phajdan.jr): Clean up after we no longer need
+  // to workaround http://crbug.com/139744.
+#if defined(USE_SYSTEM_ZLIB)
+  int rv = deflate(compressor, Z_SYNC_FLUSH);
+  if (rv != Z_OK) {  // How can we know that it compressed everything?
+    // This shouldn't happen, right?
+    LOG(WARNING) << "deflate failure: " << rv;
+    return NULL;
+  }
+#else  // !defined(USE_SYSTEM_ZLIB)
+  WriteHeaderBlockToZ(headers, compressor);
+#endif  // !defined(USE_SYSTEM_ZLIB)
+  int compressed_size = compressed_max_size - compressor->avail_out;
+
+  // We trust zlib. Also, we can't do anything about it.
+  // See http://www.zlib.net/zlib_faq.html#faq36
+  (void)VALGRIND_MAKE_MEM_DEFINED(new_frame->data() + header_length,
+                                  compressed_size);
+
+  new_frame->set_length(
+      header_length + compressed_size - SpdyFrame::kHeaderSize);
+
+  pre_compress_bytes.Add(payload_length);
+  post_compress_bytes.Add(new_frame->length());
+
+  compressed_frames.Increment();
+
+  if (visitor_)
+    visitor_->OnControlFrameCompressed(frame, *new_frame);
+
+  return new_frame.release();
+}
+
+// Incrementally decompress the control frame's header block, feeding the
+// result to the visitor in chunks. Continue this until the visitor
+// indicates that it cannot process any more data, or (more commonly) we
+// run out of data to deliver.
+bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
+    const SpdyControlFrame* control_frame,
+    const char* data,
+    size_t len) {
+  // Get a decompressor or set error.
+  z_stream* decomp = GetHeaderDecompressor();
+  if (decomp == NULL) {
+    LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
+    set_error(SPDY_DECOMPRESS_FAILURE);
+    return false;
+  }
+
+  bool processed_successfully = true;
+  char buffer[kHeaderDataChunkMaxSize];
+
+  decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
+  decomp->avail_in = len;
+  const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
+  DCHECK_LT(0u, stream_id);
+  while (decomp->avail_in > 0 && processed_successfully) {
+    decomp->next_out = reinterpret_cast<Bytef*>(buffer);
+    decomp->avail_out = arraysize(buffer);
+
+    int rv = inflate(decomp, Z_SYNC_FLUSH);
+    if (rv == Z_NEED_DICT) {
+      const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
+                                                   : kV3Dictionary;
+      const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
+                                                      : kV3DictionarySize;
+      const DictionaryIds& ids = g_dictionary_ids.Get();
+      const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id
+                                                      : ids.v3_dictionary_id;
+      // Need to try again with the right dictionary.
+      if (decomp->adler == dictionary_id) {
+        rv = inflateSetDictionary(decomp,
+                                  reinterpret_cast<const Bytef*>(dictionary),
+                                  dictionary_size);
+        if (rv == Z_OK)
+          rv = inflate(decomp, Z_SYNC_FLUSH);
+      }
+    }
+
+    // Inflate will generate a Z_BUF_ERROR if it runs out of input
+    // without producing any output.  The input is consumed and
+    // buffered internally by zlib so we can detect this condition by
+    // checking if avail_in is 0 after the call to inflate.
+    bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
+    if ((rv == Z_OK) || input_exhausted) {
+      size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
+      if (decompressed_len > 0) {
+        processed_successfully = visitor_->OnControlFrameHeaderData(
+            stream_id, buffer, decompressed_len);
+      }
+      if (!processed_successfully) {
+        // Assume that the problem was the header block was too large for the
+        // visitor.
+        set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
+      }
+    } else {
+      DLOG(WARNING) << "inflate failure: " << rv << " " << len;
+      set_error(SPDY_DECOMPRESS_FAILURE);
+      processed_successfully = false;
+    }
+  }
+  return processed_successfully;
+}
+
+bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
+    const SpdyControlFrame* control_frame, const char* data, size_t len) {
+  bool read_successfully = true;
+  const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
+  while (read_successfully && len > 0) {
+    size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
+    read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
+                                                           bytes_to_deliver);
+    data += bytes_to_deliver;
+    len -= bytes_to_deliver;
+    if (!read_successfully) {
+      // Assume that the problem was the header block was too large for the
+      // visitor.
+      set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
+    }
+  }
+  return read_successfully;
+}
+
+SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame& frame) {
+  int size = SpdyFrame::kHeaderSize + frame.length();
+  SpdyFrame* new_frame = new SpdyFrame(size);
+  memcpy(new_frame->data(), frame.data(), size);
+  return new_frame;
+}
+
+bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const {
+  // The important frames to compress are those which contain large
+  // amounts of compressible data - namely the headers in the SYN_STREAM
+  // and SYN_REPLY.
+  if (frame.is_control_frame()) {
+    const SpdyControlFrame& control_frame =
+        reinterpret_cast<const SpdyControlFrame&>(frame);
+    return control_frame.type() == SYN_STREAM ||
+        control_frame.type() == SYN_REPLY ||
+        control_frame.type() == HEADERS;
+  }
+
+  // We don't compress Data frames.
+  return false;
+}
+
+size_t SpdyFramer::GetMinimumControlFrameSize(int version,
+                                              SpdyControlType type) {
+  switch (type) {
+    case SYN_STREAM:
+      return SpdySynStreamControlFrame::size();
+    case SYN_REPLY:
+      return SpdySynReplyControlFrame::size();
+    case RST_STREAM:
+      return SpdyRstStreamControlFrame::size();
+    case SETTINGS:
+      return SpdySettingsControlFrame::size();
+    case NOOP:
+      // Even though NOOP is no longer supported, we still correctly report its
+      // size so that it can be handled correctly as incoming data if
+      // implementations so desire.
+      return SpdyFrame::kHeaderSize;
+    case PING:
+      return SpdyPingControlFrame::size();
+    case GOAWAY:
+      if (version < 3) {
+        // SPDY 2 GOAWAY is smaller by 32 bits. Since
+        // SpdyGoAwayControlFrame::size() returns the size for SPDY 3, we adjust
+        // before returning here.
+        return SpdyGoAwayControlFrame::size() - 4;
+      } else {
+        return SpdyGoAwayControlFrame::size();
+      }
+    case HEADERS:
+      return SpdyHeadersControlFrame::size();
+    case WINDOW_UPDATE:
+      return SpdyWindowUpdateControlFrame::size();
+    case CREDENTIAL:
+      return SpdyCredentialControlFrame::size();
+    case NUM_CONTROL_FRAME_TYPES:
+      break;
+  }
+  LOG(ERROR) << "Unknown control frame type " << type;
+  return std::numeric_limits<size_t>::max();
+}
+
+/* static */
+SpdyStreamId SpdyFramer::GetControlFrameStreamId(
+    const SpdyControlFrame* control_frame) {
+  SpdyStreamId stream_id = kInvalidStream;
+  if (control_frame != NULL) {
+    switch (control_frame->type()) {
+      case SYN_STREAM:
+        stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>(
+            control_frame)->stream_id();
+        break;
+      case SYN_REPLY:
+        stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>(
+            control_frame)->stream_id();
+        break;
+      case HEADERS:
+        stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>(
+            control_frame)->stream_id();
+        break;
+      case RST_STREAM:
+        stream_id = reinterpret_cast<const SpdyRstStreamControlFrame*>(
+            control_frame)->stream_id();
+        break;
+      case WINDOW_UPDATE:
+        stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame*>(
+            control_frame)->stream_id();
+        break;
+      // All of the following types are not part of a particular stream.
+      // They all fall through to the invalid control frame type case.
+      // (The default case isn't used so that the compile will break if a new
+      // control frame type is added but not included here.)
+      case SETTINGS:
+      case NOOP:
+      case PING:
+      case GOAWAY:
+      case CREDENTIAL:
+      case NUM_CONTROL_FRAME_TYPES:  // makes compiler happy
+        break;
+    }
+  }
+  return stream_id;
+}
+
+void SpdyFramer::set_enable_compression(bool value) {
+  enable_compression_ = value;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_framer.h b/src/net/spdy/spdy_framer.h
new file mode 100644
index 0000000..0c834fd
--- /dev/null
+++ b/src/net/spdy/spdy_framer.h
@@ -0,0 +1,609 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_FRAMER_H_
+#define NET_SPDY_SPDY_FRAMER_H_
+
+#include <list>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/sys_byteorder.h"
+#include "net/base/net_export.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_protocol.h"
+
+typedef struct z_stream_s z_stream;  // Forward declaration for zlib.
+
+namespace net {
+
+class HttpProxyClientSocketPoolTest;
+class HttpNetworkLayer;
+class HttpNetworkTransactionTest;
+class SpdyHttpStreamTest;
+class SpdyNetworkTransactionTest;
+class SpdyProxyClientSocketTest;
+class SpdySessionTest;
+class SpdyStreamTest;
+class SpdyWebSocketStreamTest;
+class WebSocketJobTest;
+
+class SpdyFramer;
+class SpdyFrameBuilder;
+class SpdyFramerTest;
+
+namespace test {
+
+class TestSpdyVisitor;
+
+}  // namespace test
+
+// A datastructure for holding the ID and flag fields for SETTINGS.
+// Conveniently handles converstion to/from wire format.
+class NET_EXPORT_PRIVATE SettingsFlagsAndId {
+ public:
+  static SettingsFlagsAndId FromWireFormat(int version, uint32 wire);
+
+  SettingsFlagsAndId() : flags_(0), id_(0) {}
+
+  // TODO(hkhalil): restrict to enums instead of free-form ints.
+  SettingsFlagsAndId(uint8 flags, uint32 id);
+
+  uint32 GetWireFormat(int version) const;
+
+  uint32 id() const { return id_; }
+  uint8 flags() const { return flags_; }
+
+ private:
+  static void ConvertFlagsAndIdForSpdy2(uint32* val);
+
+  uint8 flags_;
+  uint32 id_;
+};
+
+// SettingsMap has unique (flags, value) pair for given SpdySettingsIds ID.
+typedef std::pair<SpdySettingsFlags, uint32> SettingsFlagsAndValue;
+typedef std::map<SpdySettingsIds, SettingsFlagsAndValue> SettingsMap;
+
+// A datastrcture for holding the contents of a CREDENTIAL frame.
+struct NET_EXPORT_PRIVATE SpdyCredential {
+  SpdyCredential();
+  ~SpdyCredential();
+
+  uint16 slot;
+  std::vector<std::string> certs;
+  std::string proof;
+};
+
+// Scratch space necessary for processing SETTINGS frames.
+struct NET_EXPORT_PRIVATE SpdySettingsScratch {
+  SpdySettingsScratch() { Reset(); }
+
+  void Reset() {
+    setting_buf_len = 0;
+    last_setting_id = 0;
+  }
+
+  // Buffer contains up to one complete key/value pair.
+  char setting_buf[8];
+
+  // The amount of the buffer that is filled with valid data.
+  size_t setting_buf_len;
+
+  // The ID of the last setting that was processed in the current SETTINGS
+  // frame. Used for detecting out-of-order or duplicate keys within a settings
+  // frame. Set to 0 before first key/value pair is processed.
+  uint32 last_setting_id;
+};
+
+// SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer.
+// Implement this interface to receive event callbacks as frames are
+// decoded from the framer.
+//
+// Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY, and
+// HEADER) are processed in fashion that allows the decompressed header block
+// to be delivered in chunks to the visitor. The following steps are followed:
+//   1. OnSynStream, OnSynReply or OnHeaders is called.
+//   2. Repeated: OnControlFrameHeaderData is called with chunks of the
+//      decompressed header block. In each call the len parameter is greater
+//      than zero.
+//   3. OnControlFrameHeaderData is called with len set to zero, indicating
+//      that the full header block has been delivered for the control frame.
+// During step 2 the visitor may return false, indicating that the chunk of
+// header data could not be handled by the visitor (typically this indicates
+// resource exhaustion). If this occurs the framer will discontinue
+// delivering chunks to the visitor, set a SPDY_CONTROL_PAYLOAD_TOO_LARGE
+// error, and clean up appropriately. Note that this will cause the header
+// decompressor to lose synchronization with the sender's header compressor,
+// making the SPDY session unusable for future work. The visitor's OnError
+// function should deal with this condition by closing the SPDY connection.
+class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
+ public:
+  virtual ~SpdyFramerVisitorInterface() {}
+
+  // Called if an error is detected in the SpdyFrame protocol.
+  virtual void OnError(SpdyFramer* framer) = 0;
+
+  // Called when a SYN_STREAM frame is received.
+  // Note that header block data is not included. See
+  // OnControlFrameHeaderData().
+  virtual void OnSynStream(SpdyStreamId stream_id,
+                           SpdyStreamId associated_stream_id,
+                           SpdyPriority priority,
+                           uint8 credential_slot,
+                           bool fin,
+                           bool unidirectional) = 0;
+
+  // Called when a SYN_REPLY frame is received.
+  // Note that header block data is not included. See
+  // OnControlFrameHeaderData().
+  virtual void OnSynReply(SpdyStreamId stream_id, bool fin) = 0;
+
+  // Called when a HEADERS frame is received.
+  // Note that header block data is not included. See
+  // OnControlFrameHeaderData().
+  virtual void OnHeaders(SpdyStreamId stream_id, bool fin) = 0;
+
+  // Called when a chunk of header data is available. This is called
+  // after OnSynStream, OnSynReply or OnHeaders().
+  // |stream_id| The stream receiving the header data.
+  // |header_data| A buffer containing the header data chunk received.
+  // |len| The length of the header data buffer. A length of zero indicates
+  //       that the header data block has been completely sent.
+  // When this function returns true the visitor indicates that it accepted
+  // all of the data. Returning false indicates that that an unrecoverable
+  // error has occurred, such as bad header data or resource exhaustion.
+  virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
+                                        const char* header_data,
+                                        size_t len) = 0;
+
+  // Called when a chunk of payload data for a credential frame is available.
+  // |header_data| A buffer containing the header data chunk received.
+  // |len| The length of the header data buffer. A length of zero indicates
+  //       that the header data block has been completely sent.
+  // When this function returns true the visitor indicates that it accepted
+  // all of the data. Returning false indicates that that an unrecoverable
+  // error has occurred, such as bad header data or resource exhaustion.
+  virtual bool OnCredentialFrameData(const char* header_data,
+                                     size_t len) = 0;
+
+  // Called when a data frame header is received. The frame's data
+  // payload will be provided via subsequent calls to
+  // OnStreamFrameData().
+  virtual void OnDataFrameHeader(const SpdyDataFrame* frame) = 0;
+
+  // Called when data is received.
+  // |stream_id| The stream receiving data.
+  // |data| A buffer containing the data received.
+  // |len| The length of the data buffer.
+  // When the other side has finished sending data on this stream,
+  // this method will be called with a zero-length buffer.
+  virtual void OnStreamFrameData(SpdyStreamId stream_id,
+                                 const char* data,
+                                 size_t len,
+                                 SpdyDataFlags flags) = 0;
+
+  // Called when a complete setting within a SETTINGS frame has been parsed and
+  // validated.
+  virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
+
+  // Called when a PING frame has been parsed.
+  virtual void OnPing(uint32 unique_id) = 0;
+
+  // Called when a RST_STREAM frame has been parsed.
+  virtual void OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) = 0;
+
+  // Called when a GOAWAY frame has been parsed.
+  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                        SpdyGoAwayStatus status) = 0;
+
+  // Called when a WINDOW_UPDATE frame has been parsed.
+  virtual void OnWindowUpdate(SpdyStreamId stream_id,
+                              int delta_window_size) = 0;
+
+  // Called after a control frame has been compressed to allow the visitor
+  // to record compression statistics.
+  virtual void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) = 0;
+};
+
+class NET_EXPORT_PRIVATE SpdyFramer {
+ public:
+  // SPDY states.
+  // TODO(mbelshe): Can we move these into the implementation
+  //                and avoid exposing through the header.  (Needed for test)
+  enum SpdyState {
+    SPDY_ERROR,
+    SPDY_DONE,
+    SPDY_RESET,
+    SPDY_AUTO_RESET,
+    SPDY_READING_COMMON_HEADER,
+    SPDY_CONTROL_FRAME_PAYLOAD,
+    SPDY_IGNORE_REMAINING_PAYLOAD,
+    SPDY_FORWARD_STREAM_FRAME,
+    SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK,
+    SPDY_CONTROL_FRAME_HEADER_BLOCK,
+    SPDY_CREDENTIAL_FRAME_PAYLOAD,
+    SPDY_SETTINGS_FRAME_PAYLOAD,
+  };
+
+  // SPDY error codes.
+  enum SpdyError {
+    SPDY_NO_ERROR,
+    SPDY_INVALID_CONTROL_FRAME,      // Control frame is mal-formatted.
+    SPDY_CONTROL_PAYLOAD_TOO_LARGE,  // Control frame payload was too large.
+    SPDY_ZLIB_INIT_FAILURE,          // The Zlib library could not initialize.
+    SPDY_UNSUPPORTED_VERSION,        // Control frame has unsupported version.
+    SPDY_DECOMPRESS_FAILURE,         // There was an error decompressing.
+    SPDY_COMPRESS_FAILURE,           // There was an error compressing.
+    SPDY_CREDENTIAL_FRAME_CORRUPT,   // CREDENTIAL frame could not be parsed.
+    SPDY_INVALID_DATA_FRAME_FLAGS,   // Data frame has invalid flags.
+
+    LAST_ERROR,  // Must be the last entry in the enum.
+  };
+
+  // The minimum supported SPDY version that SpdyFramer can speak.
+  static const int kMinSpdyVersion;
+
+  // The maximum supported SPDY version that SpdyFramer can speak.
+  static const int kMaxSpdyVersion;
+
+  // Constant for invalid (or unknown) stream IDs.
+  static const SpdyStreamId kInvalidStream;
+
+  // The maximum size of header data chunks delivered to the framer visitor
+  // through OnControlFrameHeaderData. (It is exposed here for unit test
+  // purposes.)
+  static const size_t kHeaderDataChunkMaxSize;
+
+  // Create a new Framer, provided a SPDY version.
+  explicit SpdyFramer(int version);
+  virtual ~SpdyFramer();
+
+  // Set callbacks to be called from the framer.  A visitor must be set, or
+  // else the framer will likely crash.  It is acceptable for the visitor
+  // to do nothing.  If this is called multiple times, only the last visitor
+  // will be used.
+  void set_visitor(SpdyFramerVisitorInterface* visitor) {
+    visitor_ = visitor;
+  }
+
+  // Pass data into the framer for parsing.
+  // Returns the number of bytes consumed. It is safe to pass more bytes in
+  // than may be consumed.
+  size_t ProcessInput(const char* data, size_t len);
+
+  // Resets the framer state after a frame has been successfully decoded.
+  // TODO(mbelshe): can we make this private?
+  void Reset();
+
+  // Check the state of the framer.
+  SpdyError error_code() const { return error_code_; }
+  SpdyState state() const { return state_; }
+
+  bool MessageFullyRead() const {
+    return state_ == SPDY_DONE || state_ == SPDY_AUTO_RESET;
+  }
+  bool HasError() const { return state_ == SPDY_ERROR; }
+
+  // Given a buffer containing a decompressed header block in SPDY
+  // serialized format, parse out a SpdyHeaderBlock, putting the results
+  // in the given header block.
+  // Returns true if successfully parsed, false otherwise.
+  bool ParseHeaderBlockInBuffer(const char* header_data,
+                                size_t header_length,
+                                SpdyHeaderBlock* block) const;
+
+  // Create a SpdySynStreamControlFrame.
+  // |stream_id| is the id for this stream.
+  // |associated_stream_id| is the associated stream id for this stream.
+  // |priority| is the priority (GetHighestPriority()-GetLowestPriority) for
+  //    this stream.
+  // |credential_slot| is the CREDENTIAL slot to be used for this request.
+  // |flags| is the flags to use with the data.
+  //    To mark this frame as the last frame, enable CONTROL_FLAG_FIN.
+  // |compressed| specifies whether the frame should be compressed.
+  // |headers| is the header block to include in the frame.
+  SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id,
+                                             SpdyStreamId associated_stream_id,
+                                             SpdyPriority priority,
+                                             uint8 credential_slot,
+                                             SpdyControlFlags flags,
+                                             bool compressed,
+                                             const SpdyHeaderBlock* headers);
+
+  // Create a SpdySynReplyControlFrame.
+  // |stream_id| is the stream for this frame.
+  // |flags| is the flags to use with the data.
+  //    To mark this frame as the last frame, enable CONTROL_FLAG_FIN.
+  // |compressed| specifies whether the frame should be compressed.
+  // |headers| is the header block to include in the frame.
+  SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id,
+                                           SpdyControlFlags flags,
+                                           bool compressed,
+                                           const SpdyHeaderBlock* headers);
+
+  SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id,
+                                             SpdyStatusCodes status) const;
+
+  // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is
+  // used to communicate name/value pairs relevant to the communication channel.
+  SpdySettingsControlFrame* CreateSettings(const SettingsMap& values) const;
+
+  // Creates an instance of SpdyPingControlFrame. The unique_id is used to
+  // identify the ping request/response.
+  SpdyPingControlFrame* CreatePingFrame(uint32 unique_id) const;
+
+  // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used
+  // prior to the shutting down of the TCP connection, and includes the
+  // stream_id of the last stream the sender of the frame is willing to process
+  // to completion.
+  SpdyGoAwayControlFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id,
+                                       SpdyGoAwayStatus status) const;
+
+  // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used
+  // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The
+  // arguments are the same as for CreateSynReply.
+  SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id,
+                                         SpdyControlFlags flags,
+                                         bool compressed,
+                                         const SpdyHeaderBlock* headers);
+
+  // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE
+  // frame is used to implement per stream flow control in SPDY.
+  SpdyWindowUpdateControlFrame* CreateWindowUpdate(
+      SpdyStreamId stream_id,
+      uint32 delta_window_size) const;
+
+  // Creates an instance of SpdyCredentialControlFrame.  The CREDENTIAL
+  // frame is used to send a client certificate to the server when
+  // request more than one origin are sent over the same SPDY session.
+  SpdyCredentialControlFrame* CreateCredentialFrame(
+      const SpdyCredential& credential) const;
+
+  // Given a SpdySettingsControlFrame, extract the settings.
+  // Returns true on successful parse, false otherwise.
+  static bool ParseSettings(const SpdySettingsControlFrame* frame,
+                            SettingsMap* settings);
+
+  // Given a SpdyCredentialControlFrame's payload, extract the credential.
+  // Returns true on successful parse, false otherwise.
+  // TODO(hkhalil): Implement CREDENTIAL frame parsing in SpdyFramer
+  // and eliminate this method.
+  static bool ParseCredentialData(const char* data, size_t len,
+                                  SpdyCredential* credential);
+
+  // Create a data frame.
+  // |stream_id| is the stream  for this frame
+  // |data| is the data to be included in the frame.
+  // |len| is the length of the data
+  // |flags| is the flags to use with the data.
+  //    To mark this frame as the last data frame, enable DATA_FLAG_FIN.
+  SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id, const char* data,
+                                 uint32 len, SpdyDataFlags flags) const;
+
+  // NOTES about frame compression.
+  // We want spdy to compress headers across the entire session.  As long as
+  // the session is over TCP, frames are sent serially.  The client & server
+  // can each compress frames in the same order and then compress them in that
+  // order, and the remote can do the reverse.  However, we ultimately want
+  // the creation of frames to be less sensitive to order so that they can be
+  // placed over a UDP based protocol and yet still benefit from some
+  // compression.  We don't know of any good compression protocol which does
+  // not build its state in a serial (stream based) manner....  For now, we're
+  // using zlib anyway.
+
+  // Compresses a SpdyFrame.
+  // On success, returns a new SpdyFrame with the payload compressed.
+  // Compression state is maintained as part of the SpdyFramer.
+  // Returned frame must be freed with "delete".
+  // On failure, returns NULL.
+  SpdyFrame* CompressFrame(const SpdyFrame& frame);
+
+  // Create a copy of a frame.
+  // Returned frame must be freed with "delete".
+  SpdyFrame* DuplicateFrame(const SpdyFrame& frame);
+
+  // Returns true if a frame could be compressed.
+  bool IsCompressible(const SpdyFrame& frame) const;
+
+  // Get the minimum size of the control frame for the given control frame
+  // type. This is useful for validating frame blocks.
+  static size_t GetMinimumControlFrameSize(int version, SpdyControlType type);
+
+  // Get the stream ID for the given control frame (SYN_STREAM, SYN_REPLY, and
+  // HEADERS). If the control frame is NULL or of another type, this
+  // function returns kInvalidStream.
+  static SpdyStreamId GetControlFrameStreamId(
+      const SpdyControlFrame* control_frame);
+
+  // For ease of testing and experimentation we can tweak compression on/off.
+  void set_enable_compression(bool value);
+
+  // Used only in log messages.
+  void set_display_protocol(const std::string& protocol) {
+    display_protocol_ = protocol;
+  }
+
+  // For debugging.
+  static const char* StateToString(int state);
+  static const char* ErrorCodeToString(int error_code);
+  static const char* StatusCodeToString(int status_code);
+  static const char* ControlTypeToString(SpdyControlType type);
+
+  int protocol_version() const { return spdy_version_; }
+
+  bool probable_http_response() const { return probable_http_response_; }
+
+  SpdyPriority GetLowestPriority() const {
+      return spdy_version_ < 3 ? 3U : 7U;
+  }
+  SpdyPriority GetHighestPriority() const { return 0; }
+
+ protected:
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, BasicCompression);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameSizesAreValidated);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HeaderCompression);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DecompressUncompressedFrame);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
+                           UnclosedStreamDataCompressorsOneByteAtATime);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
+                           UncompressLargerThanFrameBufferInitialSize);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrame);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
+                           ReadLargeSettingsFrameInSmallChunks);
+  friend class net::HttpNetworkLayer;  // This is temporary for the server.
+  friend class net::HttpNetworkTransactionTest;
+  friend class net::HttpProxyClientSocketPoolTest;
+  friend class net::SpdyHttpStreamTest;
+  friend class net::SpdyNetworkTransactionTest;
+  friend class net::SpdyProxyClientSocketTest;
+  friend class net::SpdySessionTest;
+  friend class net::SpdyStreamTest;
+  friend class net::SpdyWebSocketStreamTest;
+  friend class net::WebSocketJobTest;
+  friend class test::TestSpdyVisitor;
+
+ private:
+  // Internal breakouts from ProcessInput. Each returns the number of bytes
+  // consumed from the data.
+  size_t ProcessCommonHeader(const char* data, size_t len);
+  size_t ProcessControlFramePayload(const char* data, size_t len);
+  size_t ProcessCredentialFramePayload(const char* data, size_t len);
+  size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len);
+  size_t ProcessControlFrameHeaderBlock(const char* data, size_t len);
+  size_t ProcessSettingsFramePayload(const char* data, size_t len);
+  size_t ProcessDataFramePayload(const char* data, size_t len);
+
+  // Helpers for above internal breakouts from ProcessInput.
+  void ProcessControlFrameHeader();
+  bool ProcessSetting(const char* data);  // Always passed exactly 8 bytes.
+
+  // Get (and lazily initialize) the ZLib state.
+  z_stream* GetHeaderCompressor();
+  z_stream* GetHeaderDecompressor();
+
+  // Deliver the given control frame's compressed headers block to the visitor
+  // in decompressed form, in chunks. Returns true if the visitor has
+  // accepted all of the chunks.
+  bool IncrementallyDecompressControlFrameHeaderData(
+      const SpdyControlFrame* frame,
+      const char* data,
+      size_t len);
+
+  // Deliver the given control frame's uncompressed headers block to the
+  // visitor in chunks. Returns true if the visitor has accepted all of the
+  // chunks.
+  bool IncrementallyDeliverControlFrameHeaderData(const SpdyControlFrame* frame,
+                                                  const char* data,
+                                                  size_t len);
+
+  // Utility to copy the given data block to the current frame buffer, up
+  // to the given maximum number of bytes, and update the buffer
+  // data (pointer and length). Returns the number of bytes
+  // read, and:
+  //   *data is advanced the number of bytes read.
+  //   *len is reduced by the number of bytes read.
+  size_t UpdateCurrentFrameBuffer(const char** data, size_t* len,
+                                  size_t max_bytes);
+
+  // Retrieve serialized length of SpdyHeaderBlock.
+  size_t GetSerializedLength(const SpdyHeaderBlock* headers) const;
+
+  // Serializes a SpdyHeaderBlock.
+  void WriteHeaderBlock(SpdyFrameBuilder* frame,
+                        const SpdyHeaderBlock* headers) const;
+
+  void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
+                           z_stream* out) const;
+
+  // Set the error code and moves the framer into the error state.
+  void set_error(SpdyError error);
+
+  // Given a frame, breakdown the variable payload length, the static header
+  // header length, and variable payload pointer.
+  bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length,
+                          int* header_length, const char** payload) const;
+
+  // Returns a new SpdyControlFrame with the compressed payload of |frame|.
+  SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame,
+                                         const SpdyHeaderBlock* headers);
+
+  // The size of the control frame buffer.
+  // Since this is only used for control frame headers, the maximum control
+  // frame header size (SYN_STREAM) is sufficient; all remaining control
+  // frame data is streamed to the visitor.
+  static const size_t kControlFrameBufferSize;
+
+  // The maximum size of the control frames that we support.
+  // This limit is arbitrary. We can enforce it here or at the application
+  // layer. We chose the framing layer, but this can be changed (or removed)
+  // if necessary later down the line.
+  static const size_t kMaxControlFrameSize;
+
+  SpdyState state_;
+  SpdyState previous_state_;
+  SpdyError error_code_;
+  size_t remaining_data_;
+
+  // The number of bytes remaining to read from the current control frame's
+  // payload.
+  size_t remaining_control_payload_;
+
+  // The number of bytes remaining to read from the current control frame's
+  // headers. Note that header data blocks (for control types that have them)
+  // are part of the frame's payload, and not the frame's headers.
+  size_t remaining_control_header_;
+
+  scoped_array<char> current_frame_buffer_;
+  size_t current_frame_len_;  // Number of bytes read into the current_frame_.
+
+  // Scratch space for handling SETTINGS frames.
+  // TODO(hkhalil): Unify memory for this scratch space with
+  // current_frame_buffer_.
+  SpdySettingsScratch settings_scratch_;
+
+  bool enable_compression_;  // Controls all compression
+  // SPDY header compressors.
+  scoped_ptr<z_stream> header_compressor_;
+  scoped_ptr<z_stream> header_decompressor_;
+
+  SpdyFramerVisitorInterface* visitor_;
+
+  std::string display_protocol_;
+
+  // The SPDY version to be spoken/understood by this framer. We support only
+  // integer versions here, as major version numbers indicate framer-layer
+  // incompatibility and minor version numbers indicate application-layer
+  // incompatibility.
+  const int spdy_version_;
+
+  // Tracks if we've ever gotten far enough in framing to see a control frame of
+  // type SYN_STREAM or SYN_REPLY.
+  //
+  // If we ever get something which looks like a data frame before we've had a
+  // SYN, we explicitly check to see if it looks like we got an HTTP response to
+  // a SPDY request.  This boolean lets us do that.
+  bool syn_frame_processed_;
+
+  // If we ever get a data frame before a SYN frame, we check to see if it
+  // starts with HTTP.  If it does, we likely have an HTTP response.   This
+  // isn't guaranteed though: we could have gotten a settings frame and then
+  // corrupt data that just looks like HTTP, but deterministic checking requires
+  // a lot more state.
+  bool probable_http_response_;
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_FRAMER_H_
diff --git a/src/net/spdy/spdy_framer_test.cc b/src/net/spdy/spdy_framer_test.cc
new file mode 100644
index 0000000..e0b0d57
--- /dev/null
+++ b/src/net/spdy/spdy_framer_test.cc
@@ -0,0 +1,3218 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <iostream>
+#include <limits>
+
+#include "base/memory/scoped_ptr.h"
+#include "net/spdy/spdy_framer.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_frame_builder.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/platform_test.h"
+
+using std::string;
+using std::max;
+using std::min;
+using std::numeric_limits;
+using testing::_;
+
+namespace net {
+
+namespace test {
+
+static const size_t kMaxDecompressedSize = 1024;
+
+class MockVisitor : public SpdyFramerVisitorInterface {
+ public:
+  MOCK_METHOD1(OnError, void(SpdyFramer* framer));
+  MOCK_METHOD6(OnSynStream, void(SpdyStreamId stream_id,
+                                 SpdyStreamId associated_stream_id,
+                                 SpdyPriority priority,
+                                 uint8 slot,
+                                 bool fin,
+                                 bool unidirectional));
+  MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin));
+  MOCK_METHOD2(OnHeaders, void(SpdyStreamId stream_id, bool fin));
+  MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id,
+                                              const char* header_data,
+                                              size_t len));
+  MOCK_METHOD2(OnCredentialFrameData, bool(const char* header_data,
+                                           size_t len));
+  MOCK_METHOD1(OnDataFrameHeader, void(const SpdyDataFrame* frame));
+  MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id,
+                                       const char* data,
+                                       size_t len,
+                                       SpdyDataFlags flags));
+  MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
+  MOCK_METHOD1(OnPing, void(uint32 unique_id));
+  MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id,
+                                 SpdyStatusCodes status));
+  MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
+                              SpdyGoAwayStatus status));
+  MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId stream_id,
+                                    int delta_window_size));
+  MOCK_METHOD2(OnControlFrameCompressed,
+               void(const SpdyControlFrame& uncompressed_frame,
+                    const SpdyControlFrame& compressed_frame));
+};
+
+class SpdyFramerTestUtil {
+ public:
+  // Decompress a single frame using the decompression context held by
+  // the SpdyFramer.  The implemention is meant for use only in tests
+  // and will CHECK fail if the input is anything other than a single,
+  // well-formed compressed frame.
+  //
+  // Returns a new decompressed SpdyFrame.
+  template<class SpdyFrameType> static SpdyFrame* DecompressFrame(
+      SpdyFramer* framer, const SpdyFrameType& frame) {
+    DecompressionVisitor visitor(framer->protocol_version());
+    framer->set_visitor(&visitor);
+    size_t input_size = frame.length() + SpdyFrame::kHeaderSize;
+    CHECK_EQ(input_size, framer->ProcessInput(frame.data(), input_size));
+    CHECK_EQ(SpdyFramer::SPDY_RESET, framer->state());
+    framer->set_visitor(NULL);
+
+    char* buffer = visitor.ReleaseBuffer();
+    CHECK(buffer != NULL);
+    SpdyFrame* decompressed_frame = new SpdyFrame(buffer, true);
+    decompressed_frame->set_length(visitor.size() - SpdyFrame::kHeaderSize);
+    return decompressed_frame;
+  }
+
+  class DecompressionVisitor : public SpdyFramerVisitorInterface {
+   public:
+    explicit DecompressionVisitor(int version)
+        : version_(version), buffer_(NULL), size_(0), finished_(false) {
+    }
+
+    void ResetBuffer() {
+      CHECK(buffer_.get() == NULL);
+      CHECK_EQ(0u, size_);
+      CHECK(!finished_);
+      buffer_.reset(new char[kMaxDecompressedSize]);
+    }
+
+    virtual void OnSynStream(SpdyStreamId stream_id,
+                             SpdyStreamId associated_stream_id,
+                             SpdyPriority priority,
+                             uint8 slot,
+                             bool fin,
+                             bool unidirectional) {
+      SpdyFramer framer(version_);
+      const SpdyHeaderBlock null_headers;
+      int flags = CONTROL_FLAG_NONE;
+      if (fin) {
+        flags &= CONTROL_FLAG_FIN;
+      }
+      if (unidirectional) {
+        flags &= CONTROL_FLAG_UNIDIRECTIONAL;
+      }
+      scoped_ptr<SpdySynStreamControlFrame> frame(
+          framer.CreateSynStream(stream_id,
+                                 associated_stream_id,
+                                 priority,
+                                 slot,
+                                 static_cast<SpdyControlFlags>(flags),
+                                 false,
+                                 &null_headers));
+      ResetBuffer();
+      memcpy(buffer_.get(), frame->data(), SpdySynStreamControlFrame::size());
+      size_ += SpdySynStreamControlFrame::size();
+    }
+
+    virtual void OnSynReply(SpdyStreamId stream_id, bool fin) {
+      SpdyFramer framer(version_);
+      const SpdyHeaderBlock null_headers;
+      int flags = CONTROL_FLAG_NONE;
+      if (fin) {
+        flags &= CONTROL_FLAG_FIN;
+      }
+      scoped_ptr<SpdyHeadersControlFrame> frame(
+          framer.CreateHeaders(stream_id,
+                               static_cast<SpdyControlFlags>(flags),
+                               false,
+                               &null_headers));
+      ResetBuffer();
+      memcpy(buffer_.get(), frame->data(), SpdyHeadersControlFrame::size());
+      size_ += SpdySynStreamControlFrame::size();
+    }
+
+    virtual void OnHeaders(SpdyStreamId stream_id, bool fin) {
+      SpdyFramer framer(version_);
+      const SpdyHeaderBlock null_headers;
+      int flags = CONTROL_FLAG_NONE;
+      if (fin) {
+        flags &= CONTROL_FLAG_FIN;
+      }
+      scoped_ptr<SpdyHeadersControlFrame> frame(
+          framer.CreateHeaders(stream_id,
+                               static_cast<SpdyControlFlags>(flags),
+                               false,
+                               &null_headers));
+      ResetBuffer();
+      memcpy(buffer_.get(), frame->data(), SpdyHeadersControlFrame::size());
+      size_ += SpdySynStreamControlFrame::size();
+    }
+
+    virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
+                                          const char* header_data,
+                                          size_t len) {
+      CHECK(buffer_.get() != NULL);
+      CHECK_GE(kMaxDecompressedSize, size_ + len);
+      CHECK(!finished_);
+      if (len != 0) {
+        memcpy(buffer_.get() + size_, header_data, len);
+        size_ += len;
+      } else {
+        // Done.
+        finished_ = true;
+      }
+      return true;
+    }
+
+    virtual bool OnCredentialFrameData(const char* header_data,
+                                       size_t len) {
+      LOG(FATAL) << "Unexpected CREDENTIAL Frame";
+      return false;
+    }
+
+    virtual void OnError(SpdyFramer* framer) { LOG(FATAL); }
+    virtual void OnDataFrameHeader(const SpdyDataFrame* frame) {
+      LOG(FATAL) << "Unexpected data frame header";
+    }
+    virtual void OnStreamFrameData(SpdyStreamId stream_id,
+                                   const char* data,
+                                   size_t len,
+                                   SpdyDataFlags flags) {
+      LOG(FATAL);
+    }
+    virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
+      LOG(FATAL);
+    }
+    virtual void OnControlFrameCompressed(
+        const SpdyControlFrame& uncompressed_frame,
+        const SpdyControlFrame& compressed_frame) {
+    }
+    virtual void OnPing(uint32 unique_id) {
+      LOG(FATAL);
+    }
+    virtual void OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) {
+      LOG(FATAL);
+    }
+    virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                          SpdyGoAwayStatus status) {
+      LOG(FATAL);
+    }
+    virtual void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) {
+      LOG(FATAL);
+    }
+
+    char* ReleaseBuffer() {
+      CHECK(finished_);
+      return buffer_.release();
+    }
+
+    size_t size() const {
+      CHECK(finished_);
+      return size_;
+    }
+
+   private:
+    int version_;
+    scoped_array<char> buffer_;
+    size_t size_;
+    bool finished_;
+
+    DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor);
+  };
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil);
+};
+
+string HexDumpWithMarks(const unsigned char* data, int length,
+                             const bool* marks, int mark_length) {
+  static const char kHexChars[] = "0123456789abcdef";
+  static const int kColumns = 4;
+
+  const int kSizeLimit = 1024;
+  if (length > kSizeLimit || mark_length > kSizeLimit) {
+    LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
+    length = min(length, kSizeLimit);
+    mark_length = min(mark_length, kSizeLimit);
+  }
+
+  string hex;
+  for (const unsigned char* row = data; length > 0;
+       row += kColumns, length -= kColumns) {
+    for (const unsigned char *p = row; p < row + 4; ++p) {
+      if (p < row + length) {
+        const bool mark =
+            (marks && (p - data) < mark_length && marks[p - data]);
+        hex += mark ? '*' : ' ';
+        hex += kHexChars[(*p & 0xf0) >> 4];
+        hex += kHexChars[*p & 0x0f];
+        hex += mark ? '*' : ' ';
+      } else {
+        hex += "    ";
+      }
+    }
+    hex = hex + "  ";
+
+    for (const unsigned char *p = row; p < row + 4 && p < row + length; ++p)
+      hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
+
+    hex = hex + '\n';
+  }
+  return hex;
+}
+
+void CompareCharArraysWithHexError(
+    const string& description,
+    const unsigned char* actual,
+    const int actual_len,
+    const unsigned char* expected,
+    const int expected_len) {
+  const int min_len = min(actual_len, expected_len);
+  const int max_len = max(actual_len, expected_len);
+  scoped_array<bool> marks(new bool[max_len]);
+  bool identical = (actual_len == expected_len);
+  for (int i = 0; i < min_len; ++i) {
+    if (actual[i] != expected[i]) {
+      marks[i] = true;
+      identical = false;
+    } else {
+      marks[i] = false;
+    }
+  }
+  for (int i = min_len; i < max_len; ++i) {
+    marks[i] = true;
+  }
+  if (identical) return;
+  ADD_FAILURE()
+      << "Description:\n"
+      << description
+      << "\n\nExpected:\n"
+      << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
+      << "\nActual:\n"
+      << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
+}
+
+class TestSpdyVisitor : public SpdyFramerVisitorInterface  {
+ public:
+  static const size_t kDefaultHeaderBufferSize = 16 * 1024;
+  static const size_t kDefaultCredentialBufferSize = 16 * 1024;
+
+  explicit TestSpdyVisitor(int version)
+    : framer_(version),
+      use_compression_(false),
+      error_count_(0),
+      syn_frame_count_(0),
+      syn_reply_frame_count_(0),
+      headers_frame_count_(0),
+      goaway_count_(0),
+      setting_count_(0),
+      data_bytes_(0),
+      fin_frame_count_(0),
+      fin_flag_count_(0),
+      zero_length_data_frame_count_(0),
+      header_blocks_count_(0),
+      control_frame_header_data_count_(0),
+      zero_length_control_frame_header_data_count_(0),
+      data_frame_count_(0),
+      header_buffer_(new char[kDefaultHeaderBufferSize]),
+      header_buffer_length_(0),
+      header_buffer_size_(kDefaultHeaderBufferSize),
+      header_stream_id_(-1),
+      header_control_type_(NUM_CONTROL_FRAME_TYPES),
+      header_buffer_valid_(false),
+      credential_buffer_(new char[kDefaultCredentialBufferSize]),
+      credential_buffer_length_(0),
+      credential_buffer_size_(kDefaultCredentialBufferSize) {
+  }
+
+  void OnError(SpdyFramer* f) {
+    LOG(INFO) << "SpdyFramer Error: "
+              << SpdyFramer::ErrorCodeToString(f->error_code());
+    error_count_++;
+  }
+
+  void OnDataFrameHeader(const SpdyDataFrame* frame) {
+    data_frame_count_++;
+    header_stream_id_ = frame->stream_id();
+  }
+
+  void OnStreamFrameData(SpdyStreamId stream_id,
+                         const char* data,
+                         size_t len,
+                         SpdyDataFlags flags) {
+    EXPECT_EQ(header_stream_id_, stream_id);
+    if (len == 0)
+      ++zero_length_data_frame_count_;
+
+    data_bytes_ += len;
+    std::cerr << "OnStreamFrameData(" << stream_id << ", \"";
+    if (len > 0) {
+      for (size_t i = 0 ; i < len; ++i) {
+        std::cerr << std::hex << (0xFF & (unsigned int)data[i]) << std::dec;
+      }
+    }
+    std::cerr << "\", " << len << ")\n";
+  }
+
+  virtual void OnSynStream(SpdyStreamId stream_id,
+                           SpdyStreamId associated_stream_id,
+                           SpdyPriority priority,
+                           uint8 credential_slot,
+                           bool fin,
+                           bool unidirectional) {
+    syn_frame_count_++;
+    InitHeaderStreaming(SYN_STREAM, stream_id);
+    if (fin) {
+      fin_flag_count_++;
+    }
+  }
+
+  virtual void OnSynReply(SpdyStreamId stream_id, bool fin) {
+    syn_reply_frame_count_++;
+    InitHeaderStreaming(HEADERS, stream_id);
+    if (fin) {
+      fin_flag_count_++;
+    }
+  }
+
+  virtual void OnHeaders(SpdyStreamId stream_id, bool fin) {
+    headers_frame_count_++;
+    InitHeaderStreaming(SYN_REPLY, stream_id);
+    if (fin) {
+      fin_flag_count_++;
+    }
+  }
+
+  virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
+    setting_count_++;
+  }
+
+  virtual void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) {
+  }
+
+  virtual void OnPing(uint32 unique_id) {
+    DLOG(FATAL);
+  }
+
+  virtual void OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) {
+    fin_frame_count_++;
+  }
+
+  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                        SpdyGoAwayStatus status) {
+    goaway_count_++;
+  }
+
+  virtual void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) {
+    last_window_update_stream_ = stream_id;
+    last_window_update_delta_ = delta_window_size;
+  }
+
+  bool OnControlFrameHeaderData(SpdyStreamId stream_id,
+                                const char* header_data,
+                                size_t len) {
+    ++control_frame_header_data_count_;
+    CHECK_EQ(header_stream_id_, stream_id);
+    if (len == 0) {
+      ++zero_length_control_frame_header_data_count_;
+      // Indicates end-of-header-block.
+      CHECK(header_buffer_valid_);
+      bool parsed_headers = framer_.ParseHeaderBlockInBuffer(
+          header_buffer_.get(), header_buffer_length_, &headers_);
+      DCHECK(parsed_headers);
+      return true;
+    }
+    const size_t available = header_buffer_size_ - header_buffer_length_;
+    if (len > available) {
+      header_buffer_valid_ = false;
+      return false;
+    }
+    memcpy(header_buffer_.get() + header_buffer_length_, header_data, len);
+    header_buffer_length_ += len;
+    return true;
+  }
+
+  bool OnCredentialFrameData(const char* credential_data,
+                             size_t len) {
+    if (len == 0) {
+      if (!framer_.ParseCredentialData(credential_buffer_.get(),
+                                       credential_buffer_length_,
+                                       &credential_)) {
+        ++error_count_;
+      }
+      return true;
+    }
+    const size_t available =
+        credential_buffer_size_ - credential_buffer_length_;
+    if (len > available) {
+      return false;
+    }
+    memcpy(credential_buffer_.get() + credential_buffer_length_,
+           credential_data, len);
+    credential_buffer_length_ += len;
+    return true;
+  }
+
+  // Convenience function which runs a framer simulation with particular input.
+  void SimulateInFramer(const unsigned char* input, size_t size) {
+    framer_.set_enable_compression(use_compression_);
+    framer_.set_visitor(this);
+    size_t input_remaining = size;
+    const char* input_ptr = reinterpret_cast<const char*>(input);
+    while (input_remaining > 0 &&
+           framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) {
+      // To make the tests more interesting, we feed random (amd small) chunks
+      // into the framer.  This simulates getting strange-sized reads from
+      // the socket.
+      const size_t kMaxReadSize = 32;
+      size_t bytes_read =
+          (rand() % min(input_remaining, kMaxReadSize)) + 1;
+      size_t bytes_processed = framer_.ProcessInput(input_ptr, bytes_read);
+      input_remaining -= bytes_processed;
+      input_ptr += bytes_processed;
+      if (framer_.state() == SpdyFramer::SPDY_DONE)
+        framer_.Reset();
+    }
+  }
+
+  void InitHeaderStreaming(SpdyControlType header_control_type,
+                           SpdyStreamId stream_id) {
+    memset(header_buffer_.get(), 0, header_buffer_size_);
+    header_buffer_length_ = 0;
+    header_stream_id_ = stream_id;
+    header_control_type_ = header_control_type;
+    header_buffer_valid_ = true;
+    DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
+  }
+
+  // Override the default buffer size (16K). Call before using the framer!
+  void set_header_buffer_size(size_t header_buffer_size) {
+    header_buffer_size_ = header_buffer_size;
+    header_buffer_.reset(new char[header_buffer_size]);
+  }
+
+  static size_t control_frame_buffer_max_size() {
+    return SpdyFramer::kMaxControlFrameSize;
+  }
+
+  static size_t header_data_chunk_max_size() {
+    return SpdyFramer::kHeaderDataChunkMaxSize;
+  }
+
+  SpdyFramer framer_;
+  bool use_compression_;
+
+  // Counters from the visitor callbacks.
+  int error_count_;
+  int syn_frame_count_;
+  int syn_reply_frame_count_;
+  int headers_frame_count_;
+  int goaway_count_;
+  int setting_count_;
+  int last_window_update_stream_;
+  int last_window_update_delta_;
+  int data_bytes_;
+  int fin_frame_count_;  // The count of RST_STREAM type frames received.
+  int fin_flag_count_;  // The count of frames with the FIN flag set.
+  int zero_length_data_frame_count_;  // The count of zero-length data frames.
+  int header_blocks_count_;
+  int control_frame_header_data_count_;  // The count of chunks received.
+  // The count of zero-length control frame header data chunks received.
+  int zero_length_control_frame_header_data_count_;
+  int data_frame_count_;
+
+  // Header block streaming state:
+  scoped_array<char> header_buffer_;
+  size_t header_buffer_length_;
+  size_t header_buffer_size_;
+  SpdyStreamId header_stream_id_;
+  SpdyControlType header_control_type_;
+  bool header_buffer_valid_;
+  SpdyHeaderBlock headers_;
+
+  scoped_array<char> credential_buffer_;
+  size_t credential_buffer_length_;
+  size_t credential_buffer_size_;
+  SpdyCredential credential_;
+};
+
+}  // namespace net
+
+using test::CompareCharArraysWithHexError;
+using test::SpdyFramerTestUtil;
+using test::TestSpdyVisitor;
+
+TEST(SpdyFrameBuilderTest, WriteLimits) {
+  SpdyFrameBuilder builder(1, DATA_FLAG_NONE, kLengthMask + 8);
+  // Data frame header is 8 bytes
+  EXPECT_EQ(8u, builder.length());
+  const string kLargeData(kLengthMask, 'A');
+  builder.WriteUInt32(kLengthMask);
+  EXPECT_EQ(12u, builder.length());
+  EXPECT_TRUE(builder.WriteBytes(kLargeData.data(), kLengthMask - 4));
+  EXPECT_EQ(kLengthMask + 8u, builder.length());
+}
+
+enum SpdyFramerTestTypes {
+  SPDY2 = 2,
+  SPDY3 = 3,
+};
+
+class SpdyFramerTest
+    : public ::testing::TestWithParam<SpdyFramerTestTypes> {
+ protected:
+  virtual void SetUp() {
+    spdy_version_ = GetParam();
+  }
+
+  void CompareFrame(const string& description,
+                    const SpdyFrame& actual_frame,
+                    const unsigned char* expected,
+                    const int expected_len) {
+    const unsigned char* actual =
+        reinterpret_cast<const unsigned char*>(actual_frame.data());
+    int actual_len = actual_frame.length() + SpdyFrame::kHeaderSize;
+    CompareCharArraysWithHexError(
+        description, actual, actual_len, expected, expected_len);
+  }
+
+  // Returns true if the two header blocks have equivalent content.
+  bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
+                           const SpdyHeaderBlock* actual) {
+    if (expected->size() != actual->size()) {
+      LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
+                 << actual->size() << ".";
+      return false;
+    }
+    for (SpdyHeaderBlock::const_iterator it = expected->begin();
+         it != expected->end();
+         ++it) {
+      SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
+      if (it2 == actual->end()) {
+        LOG(ERROR) << "Expected header name '" << it->first << "'.";
+        return false;
+      }
+      if (it->second.compare(it2->second) != 0) {
+        LOG(ERROR) << "Expected header named '" << it->first
+                   << "' to have a value of '" << it->second
+                   << "'. The actual value received was '" << it2->second
+                   << "'.";
+        return false;
+      }
+    }
+    return true;
+  }
+
+  void AddSpdySettingFromWireFormat(SettingsMap* settings,
+                                    uint32 key,
+                                    uint32 value) {
+    SettingsFlagsAndId flags_and_id =
+        SettingsFlagsAndId::FromWireFormat(spdy_version_, key);
+    SpdySettingsIds id = static_cast<SpdySettingsIds>(flags_and_id.id());
+    SpdySettingsFlags flags =
+        static_cast<SpdySettingsFlags>(flags_and_id.flags());
+    CHECK(settings->find(id) == settings->end());
+    settings->insert(std::make_pair(id, SettingsFlagsAndValue(flags, value)));
+  }
+
+  bool IsSpdy2() { return spdy_version_ == SPDY2; }
+
+  // Version of SPDY protocol to be used.
+  unsigned char spdy_version_;
+};
+
+// All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
+INSTANTIATE_TEST_CASE_P(SpdyFramerTests,
+                        SpdyFramerTest,
+                        ::testing::Values(SPDY2, SPDY3));
+
+TEST_P(SpdyFramerTest, IsCompressible) {
+  SpdyFramer framer(spdy_version_);
+  for (SpdyControlType type = SYN_STREAM;
+       type < NUM_CONTROL_FRAME_TYPES;
+       type = static_cast<SpdyControlType>(type + 1)) {
+    SpdyFrameBuilder frame(type, CONTROL_FLAG_NONE, spdy_version_, 1024);
+    scoped_ptr<SpdyControlFrame> control_frame(
+        reinterpret_cast<SpdyControlFrame*>(frame.take()));
+    EXPECT_EQ(control_frame->has_header_block(),
+              framer.IsCompressible(*control_frame))
+        << "Frame type: " << type;
+  }
+}
+
+// Test that we can encode and decode a SpdyHeaderBlock in serialized form.
+TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "charlie";
+  SpdyFramer framer(spdy_version_);
+
+  // Encode the header block into a SynStream frame.
+  scoped_ptr<SpdySynStreamControlFrame> frame(
+      framer.CreateSynStream(1,  // stream id
+                             0,  // associated stream id
+                             1,  // priority
+                             0,  // credential slot
+                             CONTROL_FLAG_NONE,
+                             false,  // compress
+                             &headers));
+  EXPECT_TRUE(frame.get() != NULL);
+  string serialized_headers(frame->header_block(), frame->header_block_len());
+  SpdyHeaderBlock new_headers;
+  EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
+                                              serialized_headers.size(),
+                                              &new_headers));
+
+  EXPECT_EQ(headers.size(), new_headers.size());
+  EXPECT_EQ(headers["alpha"], new_headers["alpha"]);
+  EXPECT_EQ(headers["gamma"], new_headers["gamma"]);
+}
+
+// Test that if there's not a full frame, we fail to parse it.
+TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "charlie";
+  SpdyFramer framer(spdy_version_);
+
+  // Encode the header block into a SynStream frame.
+  scoped_ptr<SpdySynStreamControlFrame> frame(
+      framer.CreateSynStream(1,  // stream id
+                             0,  // associated stream id
+                             1,  // priority
+                             0,  // credential slot
+                             CONTROL_FLAG_NONE,
+                             false,  // compress
+                             &headers));
+  EXPECT_TRUE(frame.get() != NULL);
+
+  string serialized_headers(frame->header_block(), frame->header_block_len());
+  SpdyHeaderBlock new_headers;
+  EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
+                                               serialized_headers.size() - 2,
+                                               &new_headers));
+}
+
+TEST_P(SpdyFramerTest, OutOfOrderHeaders) {
+  // Frame builder with plentiful buffer size.
+  SpdyFrameBuilder frame(SYN_STREAM, CONTROL_FLAG_NONE, 1, 1024);
+
+  frame.WriteUInt32(3);  // stream_id
+  frame.WriteUInt32(0);  // Associated stream id
+  frame.WriteUInt16(0);  // Priority.
+
+  if (IsSpdy2()) {
+    frame.WriteUInt16(2);  // Number of headers.
+    frame.WriteString("gamma");
+    frame.WriteString("gamma");
+    frame.WriteString("alpha");
+    frame.WriteString("alpha");
+  } else {
+    frame.WriteUInt32(2);  // Number of headers.
+    frame.WriteStringPiece32("gamma");
+    frame.WriteStringPiece32("gamma");
+    frame.WriteStringPiece32("alpha");
+    frame.WriteStringPiece32("alpha");
+  }
+  // write the length
+  frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
+
+  SpdyHeaderBlock new_headers;
+  scoped_ptr<SpdyFrame> control_frame(frame.take());
+  SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
+  string serialized_headers(syn_frame.header_block(),
+                            syn_frame.header_block_len());
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(false);
+  EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
+                                              serialized_headers.size(),
+                                              &new_headers));
+}
+
+TEST_P(SpdyFramerTest, CreateCredential) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "CREDENTIAL frame";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x0A,
+      0x00, 0x00, 0x00, 0x33,
+      0x00, 0x03, 0x00, 0x00,
+      0x00, 0x05, 'p',  'r',
+      'o',  'o',  'f',  0x00,
+      0x00, 0x00, 0x06, 'a',
+      ' ',  'c',  'e',  'r',
+      't',  0x00, 0x00, 0x00,
+      0x0C, 'a',  'n',  'o',
+      't',  'h',  'e',  'r',
+      ' ',  'c',  'e',  'r',
+      't',  0x00,  0x00, 0x00,
+      0x0A, 'f',  'i',  'n',
+      'a',  'l',  ' ',  'c',
+      'e',  'r',  't',
+    };
+    SpdyCredential credential;
+    credential.slot = 3;
+    credential.proof = "proof";
+    credential.certs.push_back("a cert");
+    credential.certs.push_back("another cert");
+    credential.certs.push_back("final cert");
+    scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, ParseCredentialFrameData) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x0A,
+      0x00, 0x00, 0x00, 0x33,
+      0x00, 0x03, 0x00, 0x00,
+      0x00, 0x05, 'p',  'r',
+      'o',  'o',  'f',  0x00,
+      0x00, 0x00, 0x06, 'a',
+      ' ',  'c',  'e',  'r',
+      't',  0x00, 0x00, 0x00,
+      0x0C, 'a',  'n',  'o',
+      't',  'h',  'e',  'r',
+      ' ',  'c',  'e',  'r',
+      't',  0x00,  0x00, 0x00,
+      0x0A, 'f',  'i',  'n',
+      'a',  'l',  ' ',  'c',
+      'e',  'r',  't',
+    };
+    SpdyCredentialControlFrame frame(reinterpret_cast<char*>(kFrameData),
+                                     false);
+    SpdyCredential credential;
+    EXPECT_TRUE(SpdyFramer::ParseCredentialData(frame.payload(), frame.length(),
+                                                &credential));
+    EXPECT_EQ(3u, credential.slot);
+    EXPECT_EQ("proof", credential.proof);
+    EXPECT_EQ("a cert", credential.certs.front());
+    credential.certs.erase(credential.certs.begin());
+    EXPECT_EQ("another cert", credential.certs.front());
+    credential.certs.erase(credential.certs.begin());
+    EXPECT_EQ("final cert", credential.certs.front());
+    credential.certs.erase(credential.certs.begin());
+    EXPECT_TRUE(credential.certs.empty());
+  }
+}
+
+TEST_P(SpdyFramerTest, DuplicateHeader) {
+  // Frame builder with plentiful buffer size.
+  SpdyFrameBuilder frame(SYN_STREAM, CONTROL_FLAG_NONE, 1, 1024);
+
+  frame.WriteUInt32(3);  // stream_id
+  frame.WriteUInt32(0);  // associated stream id
+  frame.WriteUInt16(0);  // Priority.
+
+  if (IsSpdy2()) {
+    frame.WriteUInt16(2);  // Number of headers.
+    frame.WriteString("name");
+    frame.WriteString("value1");
+    frame.WriteString("name");
+    frame.WriteString("value2");
+  } else {
+    frame.WriteUInt32(2);  // Number of headers.
+    frame.WriteStringPiece32("name");
+    frame.WriteStringPiece32("value1");
+    frame.WriteStringPiece32("name");
+    frame.WriteStringPiece32("value2");
+  }
+  // write the length
+  frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
+
+  SpdyHeaderBlock new_headers;
+  scoped_ptr<SpdyFrame> control_frame(frame.take());
+  SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
+  string serialized_headers(syn_frame.header_block(),
+                            syn_frame.header_block_len());
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(false);
+  // This should fail because duplicate headers are verboten by the spec.
+  EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
+                                               serialized_headers.size(),
+                                               &new_headers));
+}
+
+TEST_P(SpdyFramerTest, MultiValueHeader) {
+  // Frame builder with plentiful buffer size.
+  SpdyFrameBuilder frame(SYN_STREAM, CONTROL_FLAG_NONE, 1, 1024);
+
+  frame.WriteUInt32(3);  // stream_id
+  frame.WriteUInt32(0);  // associated stream id
+  frame.WriteUInt16(0);  // Priority.
+
+  string value("value1\0value2");
+  if (IsSpdy2()) {
+    frame.WriteUInt16(1);  // Number of headers.
+    frame.WriteString("name");
+    frame.WriteString(value);
+  } else {
+    frame.WriteUInt32(1);  // Number of headers.
+    frame.WriteStringPiece32("name");
+    frame.WriteStringPiece32(value);
+  }
+  // write the length
+  frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
+
+  SpdyHeaderBlock new_headers;
+  scoped_ptr<SpdyFrame> control_frame(frame.take());
+  SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
+  string serialized_headers(syn_frame.header_block(),
+                            syn_frame.header_block_len());
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(false);
+  EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
+                                              serialized_headers.size(),
+                                              &new_headers));
+  EXPECT_TRUE(new_headers.find("name") != new_headers.end());
+  EXPECT_EQ(value, new_headers.find("name")->second);
+}
+
+TEST_P(SpdyFramerTest, BasicCompression) {
+  SpdyHeaderBlock headers;
+  headers["server"] = "SpdyServer 1.0";
+  headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
+  headers["status"] = "200";
+  headers["version"] = "HTTP/1.1";
+  headers["content-type"] = "text/html";
+  headers["content-length"] = "12";
+
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(true);
+  scoped_ptr<SpdySynStreamControlFrame> frame1(
+      framer.CreateSynStream(1,  // stream id
+                             0,  // associated stream id
+                             1,  // priority
+                             0,  // credential slot
+                             CONTROL_FLAG_NONE,
+                             true,  // compress
+                             &headers));
+  scoped_ptr<SpdySynStreamControlFrame> frame2(
+      framer.CreateSynStream(1,  // stream id
+                             0,  // associated stream id
+                             1,  // priority
+                             0,  // credential slot
+                             CONTROL_FLAG_NONE,
+                             true,  // compress
+                             &headers));
+
+  // Expect the second frame to be more compact than the first.
+  EXPECT_LE(frame2->length(), frame1->length());
+
+  // Decompress the first frame
+  scoped_ptr<SpdyFrame> frame3(SpdyFramerTestUtil::DecompressFrame(
+      &framer, *frame1.get()));
+
+  // Decompress the second frame
+  scoped_ptr<SpdyFrame> frame4(SpdyFramerTestUtil::DecompressFrame(
+      &framer, *frame2.get()));
+
+  // Expect frames 3 & 4 to be the same.
+  EXPECT_EQ(0,
+      memcmp(frame3->data(), frame4->data(),
+      SpdyFrame::kHeaderSize + frame3->length()));
+
+
+  // Expect frames 3 to be the same as a uncompressed frame created
+  // from scratch.
+  scoped_ptr<SpdySynStreamControlFrame> uncompressed_frame(
+      framer.CreateSynStream(1,  // stream id
+                             0,  // associated stream id
+                             1,  // priority
+                             0,  // credential slot
+                             CONTROL_FLAG_NONE,
+                             false,  // compress
+                             &headers));
+  EXPECT_EQ(frame3->length(), uncompressed_frame->length());
+  EXPECT_EQ(0,
+      memcmp(frame3->data(), uncompressed_frame->data(),
+      SpdyFrame::kHeaderSize + uncompressed_frame->length()));
+}
+
+TEST_P(SpdyFramerTest, Basic) {
+  const unsigned char kV2Input[] = {
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #1
+    0x00, 0x00, 0x00, 0x14,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x02, 'v', 'v',
+
+    0x80, spdy_version_, 0x00, 0x08,  // HEADERS on Stream #1
+    0x00, 0x00, 0x00, 0x18,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x02,
+    0x00, 0x02, 'h', '2',
+    0x00, 0x02, 'v', '2',
+    0x00, 0x02, 'h', '3',
+    0x00, 0x02, 'v', '3',
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x0c,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #3
+    0x00, 0x00, 0x00, 0x0c,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
+    0x00, 0x00, 0x00, 0x08,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x04,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x80, spdy_version_, 0x00, 0x03,  // RST_STREAM on Stream #1
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
+    0x00, 0x00, 0x00, 0x00,
+
+    0x80, spdy_version_, 0x00, 0x03,  // RST_STREAM on Stream #3
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x00,
+  };
+
+  const unsigned char kV3Input[] = {
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #1
+    0x00, 0x00, 0x00, 0x1a,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x00, 0x00, 0x02,
+    'v', 'v',
+
+    0x80, spdy_version_, 0x00, 0x08,  // HEADERS on Stream #1
+    0x00, 0x00, 0x00, 0x22,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x00,
+    0x00, 0x02, 'h', '2',
+    0x00, 0x00, 0x00, 0x02,
+    'v', '2', 0x00, 0x00,
+    0x00, 0x02, 'h', '3',
+    0x00, 0x00, 0x00, 0x02,
+    'v', '3',
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x0c,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #3
+    0x00, 0x00, 0x00, 0x0e,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00,
+
+    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
+    0x00, 0x00, 0x00, 0x08,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x04,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x80, spdy_version_, 0x00, 0x03,  // RST_STREAM on Stream #1
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
+    0x00, 0x00, 0x00, 0x00,
+
+    0x80, spdy_version_, 0x00, 0x03,  // RST_STREAM on Stream #3
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x00,
+  };
+
+  TestSpdyVisitor visitor(spdy_version_);
+  if (IsSpdy2()) {
+    visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
+  } else {
+    visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
+  }
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(24, visitor.data_bytes_);
+  EXPECT_EQ(2, visitor.fin_frame_count_);
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+  EXPECT_EQ(4, visitor.data_frame_count_);
+}
+
+// Test that the FIN flag on a data frame signifies EOF.
+TEST_P(SpdyFramerTest, FinOnDataFrame) {
+  const unsigned char kV2Input[] = {
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #1
+    0x00, 0x00, 0x00, 0x14,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x02, 'v', 'v',
+
+    0x80, spdy_version_, 0x00, 0x02,  // SYN REPLY Stream #1
+    0x00, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x02, 'a', 'a',
+    0x00, 0x02, 'b', 'b',
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x0c,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1, with EOF
+    0x01, 0x00, 0x00, 0x04,
+    0xde, 0xad, 0xbe, 0xef,
+  };
+  const unsigned char kV3Input[] = {
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #1
+    0x00, 0x00, 0x00, 0x1a,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x00, 0x00, 0x02,
+    'v', 'v',
+
+    0x80, spdy_version_, 0x00, 0x02,  // SYN REPLY Stream #1
+    0x00, 0x00, 0x00, 0x16,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00,
+    0x00, 0x02, 'a', 'a',
+    0x00, 0x00, 0x00, 0x02,
+    'b', 'b',
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x0c,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+    0xde, 0xad, 0xbe, 0xef,
+
+    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1, with EOF
+    0x01, 0x00, 0x00, 0x04,
+    0xde, 0xad, 0xbe, 0xef,
+  };
+
+  TestSpdyVisitor visitor(spdy_version_);
+  if (IsSpdy2()) {
+    visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
+  } else {
+    visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
+  }
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_EQ(16, visitor.data_bytes_);
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+  EXPECT_EQ(2, visitor.data_frame_count_);
+}
+
+// Test that the FIN flag on a SYN reply frame signifies EOF.
+TEST_P(SpdyFramerTest, FinOnSynReplyFrame) {
+  const unsigned char kV2Input[] = {
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #1
+    0x00, 0x00, 0x00, 0x14,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x02, 'v', 'v',
+
+    0x80, spdy_version_, 0x00, 0x02,  // SYN REPLY Stream #1
+    0x01, 0x00, 0x00, 0x14,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x02, 'a', 'a',
+    0x00, 0x02, 'b', 'b',
+  };
+  const unsigned char kV3Input[] = {
+    0x80, spdy_version_, 0x00, 0x01,  // SYN Stream #1
+    0x00, 0x00, 0x00, 0x1a,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x00, 0x00, 0x02,
+    'v', 'v',
+
+    0x80, spdy_version_, 0x00, 0x02,  // SYN REPLY Stream #1
+    0x01, 0x00, 0x00, 0x1a,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00,
+    0x00, 0x02, 'a', 'a',
+    0x00, 0x00, 0x00, 0x02,
+    'b', 'b',
+  };
+
+  TestSpdyVisitor visitor(spdy_version_);
+  if (IsSpdy2()) {
+    visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
+  } else {
+    visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
+  }
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.data_bytes_);
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(1, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+  EXPECT_EQ(0, visitor.data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, HeaderCompression) {
+  SpdyFramer send_framer(spdy_version_);
+  SpdyFramer recv_framer(spdy_version_);
+
+  send_framer.set_enable_compression(true);
+  recv_framer.set_enable_compression(true);
+
+  const char kHeader1[] = "header1";
+  const char kHeader2[] = "header2";
+  const char kHeader3[] = "header3";
+  const char kValue1[] = "value1";
+  const char kValue2[] = "value2";
+  const char kValue3[] = "value3";
+
+  // SYN_STREAM #1
+  SpdyHeaderBlock block;
+  block[kHeader1] = kValue1;
+  block[kHeader2] = kValue2;
+  SpdyControlFlags flags(CONTROL_FLAG_NONE);
+  scoped_ptr<SpdySynStreamControlFrame> syn_frame_1(
+      send_framer.CreateSynStream(1,  // stream id
+                                  0,  // associated stream id
+                                  0,  // priority
+                                  0,  // credential slot
+                                  flags,
+                                  true,  // compress
+                                  &block));
+  EXPECT_TRUE(syn_frame_1.get() != NULL);
+
+  // SYN_STREAM #2
+  block[kHeader3] = kValue3;
+  scoped_ptr<SpdySynStreamControlFrame> syn_frame_2(
+      send_framer.CreateSynStream(3,  // stream id
+                                  0,  // associated stream id
+                                  0,  // priority
+                                  0,  // credential slot
+                                  flags,
+                                  true,  // compress
+                                  &block));
+  EXPECT_TRUE(syn_frame_2.get() != NULL);
+
+  // Now start decompressing
+  scoped_ptr<SpdyFrame> decompressed;
+  scoped_ptr<SpdySynStreamControlFrame> syn_frame;
+  scoped_ptr<string> serialized_headers;
+  SpdyHeaderBlock decompressed_headers;
+
+  // Decompress SYN_STREAM #1
+  decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
+      &recv_framer, *syn_frame_1.get()));
+  EXPECT_TRUE(decompressed.get() != NULL);
+  EXPECT_TRUE(decompressed->is_control_frame());
+  EXPECT_EQ(SYN_STREAM,
+            reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type());
+  syn_frame.reset(new SpdySynStreamControlFrame(decompressed->data(), false));
+  serialized_headers.reset(new string(syn_frame->header_block(),
+                                      syn_frame->header_block_len()));
+  EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(),
+                                                   serialized_headers->size(),
+                                                   &decompressed_headers));
+  EXPECT_EQ(2u, decompressed_headers.size());
+  EXPECT_EQ(kValue1, decompressed_headers[kHeader1]);
+  EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
+
+  // Decompress SYN_STREAM #2
+  decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
+      &recv_framer, *syn_frame_2.get()));
+  EXPECT_TRUE(decompressed.get() != NULL);
+  EXPECT_TRUE(decompressed->is_control_frame());
+  EXPECT_EQ(SYN_STREAM,
+            reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type());
+  syn_frame.reset(new SpdySynStreamControlFrame(decompressed->data(), false));
+  serialized_headers.reset(new string(syn_frame->header_block(),
+                                      syn_frame->header_block_len()));
+  decompressed_headers.clear();
+  EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(),
+                                                   serialized_headers->size(),
+                                                   &decompressed_headers));
+  EXPECT_EQ(3u, decompressed_headers.size());
+  EXPECT_EQ(kValue1, decompressed_headers[kHeader1]);
+  EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
+  EXPECT_EQ(kValue3, decompressed_headers[kHeader3]);
+}
+
+// Verify we don't leak when we leave streams unclosed
+TEST_P(SpdyFramerTest, UnclosedStreamDataCompressors) {
+  SpdyFramer send_framer(spdy_version_);
+
+  send_framer.set_enable_compression(true);
+
+  const char kHeader1[] = "header1";
+  const char kHeader2[] = "header2";
+  const char kValue1[] = "value1";
+  const char kValue2[] = "value2";
+
+  SpdyHeaderBlock block;
+  block[kHeader1] = kValue1;
+  block[kHeader2] = kValue2;
+  SpdyControlFlags flags(CONTROL_FLAG_NONE);
+  scoped_ptr<SpdyFrame> syn_frame(
+      send_framer.CreateSynStream(1,  // stream id
+                                  0,  // associated stream id
+                                  0,  // priority
+                                  0,  // credential slot
+                                  flags,
+                                  true,  // compress
+                                  &block));
+  EXPECT_TRUE(syn_frame.get() != NULL);
+
+  const char bytes[] = "this is a test test test test test!";
+  scoped_ptr<SpdyFrame> send_frame(
+      send_framer.CreateDataFrame(
+          1, bytes, arraysize(bytes),
+          static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
+  EXPECT_TRUE(send_frame.get() != NULL);
+
+  // Run the inputs through the framer.
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  const unsigned char* data;
+  data = reinterpret_cast<const unsigned char*>(syn_frame->data());
+  visitor.SimulateInFramer(data, syn_frame->length() + SpdyFrame::kHeaderSize);
+  data = reinterpret_cast<const unsigned char*>(send_frame->data());
+  visitor.SimulateInFramer(data, send_frame->length() + SpdyFrame::kHeaderSize);
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+  EXPECT_EQ(1, visitor.data_frame_count_);
+}
+
+// Verify we can decompress the stream even if handed over to the
+// framer 1 byte at a time.
+TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
+  SpdyFramer send_framer(spdy_version_);
+
+  send_framer.set_enable_compression(true);
+
+  const char kHeader1[] = "header1";
+  const char kHeader2[] = "header2";
+  const char kValue1[] = "value1";
+  const char kValue2[] = "value2";
+
+  SpdyHeaderBlock block;
+  block[kHeader1] = kValue1;
+  block[kHeader2] = kValue2;
+  SpdyControlFlags flags(CONTROL_FLAG_NONE);
+  scoped_ptr<SpdyFrame> syn_frame(
+      send_framer.CreateSynStream(1,  // stream id
+                                  0,  // associated stream id
+                                  0,  // priority
+                                  0,  // credential slot
+                                  flags,
+                                  true,  // compress
+                                  &block));
+  EXPECT_TRUE(syn_frame.get() != NULL);
+
+  const char bytes[] = "this is a test test test test test!";
+  scoped_ptr<SpdyFrame> send_frame(
+      send_framer.CreateDataFrame(
+          1, bytes, arraysize(bytes),
+          static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
+  EXPECT_TRUE(send_frame.get() != NULL);
+
+  // Run the inputs through the framer.
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  const unsigned char* data;
+  data = reinterpret_cast<const unsigned char*>(syn_frame->data());
+  for (size_t idx = 0;
+       idx < syn_frame->length() + SpdyFrame::kHeaderSize;
+       ++idx) {
+    visitor.SimulateInFramer(data + idx, 1);
+    ASSERT_EQ(0, visitor.error_count_);
+  }
+  data = reinterpret_cast<const unsigned char*>(send_frame->data());
+  for (size_t idx = 0;
+       idx < send_frame->length() + SpdyFrame::kHeaderSize;
+       ++idx) {
+    visitor.SimulateInFramer(data + idx, 1);
+    ASSERT_EQ(0, visitor.error_count_);
+  }
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(0, visitor.headers_frame_count_);
+  EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+  EXPECT_EQ(1, visitor.data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, WindowUpdateFrame) {
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
+      framer.CreateWindowUpdate(1, 0x12345678));
+
+  const unsigned char expected_data_frame[] = {
+      0x80, spdy_version_, 0x00, 0x09,
+      0x00, 0x00, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x01,
+      0x12, 0x34, 0x56, 0x78
+  };
+
+  EXPECT_EQ(16u, window_update_frame->size());
+  EXPECT_EQ(0,
+            memcmp(window_update_frame->data(), expected_data_frame, 16));
+}
+
+TEST_P(SpdyFramerTest, CreateDataFrame) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "'hello' data frame, no FIN";
+    const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x05,
+      'h', 'e', 'l', 'l',
+      'o'
+    };
+    const char bytes[] = "hello";
+    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
+        1, bytes, strlen(bytes), DATA_FLAG_NONE));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "Data frame with negative data byte, no FIN";
+    const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x01,
+      0xff
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
+        1, "\xff", 1, DATA_FLAG_NONE));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "'hello' data frame, with FIN";
+    const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x00, 0x01,
+      0x01, 0x00, 0x00, 0x05,
+      'h', 'e', 'l', 'l',
+      'o'
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
+        1, "hello", 5, DATA_FLAG_FIN));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "Empty data frame";
+    const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x00,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
+        1, "", 0, DATA_FLAG_NONE));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "Data frame with max stream ID";
+    const unsigned char kFrameData[] = {
+      0x7f, 0xff, 0xff, 0xff,
+      0x01, 0x00, 0x00, 0x05,
+      'h', 'e', 'l', 'l',
+      'o'
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
+        0x7fffffff, "hello", 5, DATA_FLAG_FIN));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "Large data frame";
+    const int kDataSize = 4 * 1024 * 1024;  // 4 MB
+    const string kData(kDataSize, 'A');
+    const unsigned char kFrameHeader[] = {
+      0x00, 0x00, 0x00, 0x01,
+      0x01, 0x40, 0x00, 0x00,
+    };
+
+    const int kFrameSize = arraysize(kFrameHeader) + kDataSize;
+    scoped_array<unsigned char> expected_frame_data(
+        new unsigned char[kFrameSize]);
+    memcpy(expected_frame_data.get(), kFrameHeader, arraysize(kFrameHeader));
+    memset(expected_frame_data.get() + arraysize(kFrameHeader), 'A', kDataSize);
+
+    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
+        1, kData.data(), kData.size(), DATA_FLAG_FIN));
+    CompareFrame(kDescription, *frame, expected_frame_data.get(), kFrameSize);
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(false);
+
+  {
+    const char kDescription[] = "SYN_STREAM frame, lowest pri, slot 2, no FIN";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kPri = IsSpdy2() ? 0xC0 : 0xE0;
+    const unsigned char kCre = IsSpdy2() ? 0 : 2;
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x20,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x00,
+      kPri, 0x00, 0x00, 0x02,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x03, 'b',  'a',  'r'
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x2a,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x00,
+      kPri, kCre, 0x00, 0x00,
+      0x00, 0x02, 0x00, 0x00,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x00, 0x00,
+      0x03, 'f',  'o',  'o',
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00, 0x00, 0x03, 'b',
+      'a',  'r'
+    };
+    scoped_ptr<SpdySynStreamControlFrame> frame(
+        framer.CreateSynStream(1,  // stream id
+                               0,  // associated stream id
+                               framer.GetLowestPriority(),
+                               kCre,  // credential slot
+                               CONTROL_FLAG_NONE,
+                               false,  // compress
+                               &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+    EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
+  }
+
+  {
+    const char kDescription[] =
+        "SYN_STREAM frame with a 0-length header name, highest pri, FIN, "
+        "max stream ID";
+
+    SpdyHeaderBlock headers;
+    headers[""] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x01, 0x00, 0x00, 0x1D,
+      0x7f, 0xff, 0xff, 0xff,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x03, 'f',  'o',  'o',
+      0x00, 0x03, 'b',  'a',
+      'r'
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x01, 0x00, 0x00, 0x27,
+      0x7f, 0xff, 0xff, 0xff,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x02, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x03, 'f',  'o',
+      'o',  0x00, 0x00, 0x00,
+      0x03, 'f',  'o',  'o',
+      0x00, 0x00, 0x00, 0x03,
+      'b',  'a',  'r'
+    };
+    scoped_ptr<SpdyFrame> frame(
+        framer.CreateSynStream(0x7fffffff,  // stream id
+                               0x7fffffff,  // associated stream id
+                               framer.GetHighestPriority(),
+                               0,  // credential slot
+                               CONTROL_FLAG_FIN,
+                               false,  // compress
+                               &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "SYN_STREAM frame with a 0-length header val, high pri, FIN, "
+        "max stream ID";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "";
+
+    const unsigned char kPri = IsSpdy2() ? 0x40 : 0x20;
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x01, 0x00, 0x00, 0x1D,
+      0x7f, 0xff, 0xff, 0xff,
+      0x7f, 0xff, 0xff, 0xff,
+      kPri, 0x00, 0x00, 0x02,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x01, 0x00, 0x00, 0x27,
+      0x7f, 0xff, 0xff, 0xff,
+      0x7f, 0xff, 0xff, 0xff,
+      kPri, 0x00, 0x00, 0x00,
+      0x00, 0x02, 0x00, 0x00,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x00, 0x00,
+      0x03, 'f',  'o',  'o',
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00, 0x00, 0x00
+    };
+    scoped_ptr<SpdyFrame> frame(
+        framer.CreateSynStream(0x7fffffff,  // stream id
+                               0x7fffffff,  // associated stream id
+                               1,  // priority
+                               0,  // credential slot
+                               CONTROL_FLAG_FIN,
+                               false,  // compress
+                               &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+
+// TODO(phajdan.jr): Clean up after we no longer need
+// to workaround http://crbug.com/139744.
+#if !defined(USE_SYSTEM_ZLIB)
+TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(true);
+
+  {
+    const char kDescription[] =
+        "SYN_STREAM frame, low pri, no FIN";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "bar";
+
+    const SpdyPriority priority = IsSpdy2() ? 2 : 4;
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x36,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x00,
+      0x80, 0x00, 0x38, 0xea,
+      0xdf, 0xa2, 0x51, 0xb2,
+      0x62, 0x60, 0x62, 0x60,
+      0x4e, 0x4a, 0x2c, 0x62,
+      0x60, 0x06, 0x08, 0xa0,
+      0xb4, 0xfc, 0x7c, 0x80,
+      0x00, 0x62, 0x60, 0x4e,
+      0xcb, 0xcf, 0x67, 0x60,
+      0x06, 0x08, 0xa0, 0xa4,
+      0xc4, 0x22, 0x80, 0x00,
+      0x02, 0x00, 0x00, 0x00,
+      0xff, 0xff,
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x37,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x00,
+      0x80, 0x00, 0x38, 0xEA,
+      0xE3, 0xC6, 0xA7, 0xC2,
+      0x02, 0xE5, 0x0E, 0x50,
+      0xC2, 0x4B, 0x4A, 0x04,
+      0xE5, 0x0B, 0x66, 0x80,
+      0x00, 0x4A, 0xCB, 0xCF,
+      0x07, 0x08, 0x20, 0x10,
+      0x95, 0x96, 0x9F, 0x0F,
+      0xA2, 0x00, 0x02, 0x28,
+      0x29, 0xB1, 0x08, 0x20,
+      0x80, 0x00, 0x00, 0x00,
+      0x00, 0xFF, 0xFF,
+    };
+    scoped_ptr<SpdyFrame> frame(
+        framer.CreateSynStream(1,  // stream id
+                               0,  // associated stream id
+                               priority,
+                               0,  // credential slot
+                               CONTROL_FLAG_NONE,
+                               true,  // compress
+                               &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+#endif  // !defined(USE_SYSTEM_ZLIB)
+
+TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(false);
+
+  {
+    const char kDescription[] = "SYN_REPLY frame, no FIN";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x1C,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x03, 'b',  'a',  'r'
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x24,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'b',  'a',  'r',  0x00,
+      0x00, 0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x00,
+      0x00, 0x03, 'f',  'o',
+      'o',  0x00, 0x00, 0x00,
+      0x03, 'b',  'a',  'r'
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
+        1, CONTROL_FLAG_NONE, false, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "SYN_REPLY frame with a 0-length header name, FIN, max stream ID";
+
+    SpdyHeaderBlock headers;
+    headers[""] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x01, 0x00, 0x00, 0x19,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x03, 'f',  'o',  'o',
+      0x00, 0x03, 'b',  'a',
+      'r'
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x01, 0x00, 0x00, 0x21,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00, 0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x00,
+      0x00, 0x03, 'b',  'a',
+      'r'
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
+        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "SYN_REPLY frame with a 0-length header val, FIN, max stream ID";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x01, 0x00, 0x00, 0x19,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x01, 0x00, 0x00, 0x21,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'b',  'a',  'r',  0x00,
+      0x00, 0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x00,
+      0x00, 0x03, 'f',  'o',
+      'o',  0x00, 0x00, 0x00,
+      0x00
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
+        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+
+// TODO(phajdan.jr): Clean up after we no longer need
+// to workaround http://crbug.com/139744.
+#if !defined(USE_SYSTEM_ZLIB)
+TEST_P(SpdyFramerTest, CreateSynReplyCompressed) {
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(true);
+
+  {
+    const char kDescription[] = "SYN_REPLY frame, no FIN";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x32,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x38, 0xea,
+      0xdf, 0xa2, 0x51, 0xb2,
+      0x62, 0x60, 0x62, 0x60,
+      0x4e, 0x4a, 0x2c, 0x62,
+      0x60, 0x06, 0x08, 0xa0,
+      0xb4, 0xfc, 0x7c, 0x80,
+      0x00, 0x62, 0x60, 0x4e,
+      0xcb, 0xcf, 0x67, 0x60,
+      0x06, 0x08, 0xa0, 0xa4,
+      0xc4, 0x22, 0x80, 0x00,
+      0x02, 0x00, 0x00, 0x00,
+      0xff, 0xff,
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x31,
+      0x00, 0x00, 0x00, 0x01,
+      0x38, 0xea, 0xe3, 0xc6,
+      0xa7, 0xc2, 0x02, 0xe5,
+      0x0e, 0x50, 0xc2, 0x4b,
+      0x4a, 0x04, 0xe5, 0x0b,
+      0x66, 0x80, 0x00, 0x4a,
+      0xcb, 0xcf, 0x07, 0x08,
+      0x20, 0x10, 0x95, 0x96,
+      0x9f, 0x0f, 0xa2, 0x00,
+      0x02, 0x28, 0x29, 0xb1,
+      0x08, 0x20, 0x80, 0x00,
+      0x00, 0x00, 0x00, 0xff,
+      0xff,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
+        1, CONTROL_FLAG_NONE, true, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+#endif  // !defined(USE_SYSTEM_ZLIB)
+
+TEST_P(SpdyFramerTest, CreateRstStream) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "RST_STREAM frame";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x03,
+      0x00, 0x00, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x01,
+    };
+    scoped_ptr<SpdyRstStreamControlFrame> frame(
+        framer.CreateRstStream(1, PROTOCOL_ERROR));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
+  }
+
+  {
+    const char kDescription[] = "RST_STREAM frame with max stream ID";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x03,
+      0x00, 0x00, 0x00, 0x08,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x01,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(0x7FFFFFFF,
+                                                       PROTOCOL_ERROR));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "RST_STREAM frame with max status code";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x03,
+      0x00, 0x00, 0x00, 0x08,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x06,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(0x7FFFFFFF,
+                                                       INTERNAL_ERROR));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateSettings) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "Network byte order SETTINGS frame";
+
+    uint32 kValue = 0x0a0b0c0d;
+    SpdySettingsFlags kFlags = static_cast<SpdySettingsFlags>(0x04);
+    SpdySettingsIds kId = static_cast<SpdySettingsIds>(0x030201);
+
+    SettingsMap settings;
+    settings[kId] = SettingsFlagsAndValue(kFlags, kValue);
+
+    EXPECT_EQ(kFlags, settings[kId].first);
+    EXPECT_EQ(kValue, settings[kId].second);
+
+    const unsigned char kFrameDatav2[] = {
+      0x80, spdy_version_, 0x00, 0x04,
+      0x00, 0x00, 0x00, 0x0c,
+      0x00, 0x00, 0x00, 0x01,
+      0x01, 0x02, 0x03, 0x04,
+      0x0a, 0x0b, 0x0c, 0x0d,
+    };
+
+    const unsigned char kFrameDatav3[] = {
+      0x80, spdy_version_, 0x00, 0x04,
+      0x00, 0x00, 0x00, 0x0c,
+      0x00, 0x00, 0x00, 0x01,
+      0x04, 0x03, 0x02, 0x01,
+      0x0a, 0x0b, 0x0c, 0x0d,
+    };
+
+    scoped_ptr<SpdySettingsControlFrame> frame(framer.CreateSettings(settings));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kFrameDatav2 : kFrameDatav3,
+                 arraysize(kFrameDatav3));  // Size is unchanged among versions.
+    EXPECT_EQ(SpdyFramer::kInvalidStream,
+              SpdyFramer::GetControlFrameStreamId(frame.get()));
+
+    // Make sure that ParseSettings also works as advertised.
+    SettingsMap parsed_settings;
+    EXPECT_TRUE(framer.ParseSettings(frame.get(), &parsed_settings));
+    EXPECT_EQ(settings.size(), parsed_settings.size());
+    EXPECT_EQ(kFlags, parsed_settings[kId].first);
+    EXPECT_EQ(kValue, parsed_settings[kId].second);
+  }
+
+  {
+    const char kDescription[] = "Basic SETTINGS frame";
+
+    SettingsMap settings;
+#if defined(__LB_SHELL__)
+    // second argument is expected to be in network byte order
+    AddSpdySettingFromWireFormat(
+        &settings, htonl(0x00000000), 0x00000001);  // 1st Setting
+    AddSpdySettingFromWireFormat(
+        &settings, htonl(0x02000001), 0x00000002);  // 2nd Setting
+    AddSpdySettingFromWireFormat(
+        &settings, htonl(0x03000002), 0x00000003);  // 3rd Setting
+    AddSpdySettingFromWireFormat(
+        &settings, htonl(0x04000003), 0xff000004);  // 4th Setting
+    AddSpdySettingFromWireFormat(
+        &settings, htonl(0x050000ff), 0x00000005);  // 5th Setting
+    AddSpdySettingFromWireFormat(
+        &settings, htonl(0xffffffff), 0x00000006);  // 6th Setting
+#else
+    AddSpdySettingFromWireFormat(
+        &settings, 0x00000000, 0x00000001);  // 1st Setting
+    AddSpdySettingFromWireFormat(
+        &settings, 0x01000002, 0x00000002);  // 2nd Setting
+    AddSpdySettingFromWireFormat(
+        &settings, 0x02000003, 0x00000003);  // 3rd Setting
+    AddSpdySettingFromWireFormat(
+        &settings, 0x03000004, 0xff000004);  // 4th Setting
+    AddSpdySettingFromWireFormat(
+        &settings, 0xff000005, 0x00000005);  // 5th Setting
+    AddSpdySettingFromWireFormat(
+        &settings, 0xffffffff, 0x00000006);  // 6th Setting
+#endif
+
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x04,
+      0x00, 0x00, 0x00, 0x34,
+      0x00, 0x00, 0x00, 0x06,
+      0x00, 0x00, 0x00, 0x00,  // 1st Setting
+      0x00, 0x00, 0x00, 0x01,
+      0x02, 0x00, 0x00, 0x01,  // 2nd Setting
+      0x00, 0x00, 0x00, 0x02,
+      0x03, 0x00, 0x00, 0x02,  // 3rd Setting
+      0x00, 0x00, 0x00, 0x03,
+      0x04, 0x00, 0x00, 0x03,  // 4th Setting
+      0xff, 0x00, 0x00, 0x04,
+      0x05, 0x00, 0x00, 0xff,  // 5th Setting
+      0x00, 0x00, 0x00, 0x05,
+      0xff, 0xff, 0xff, 0xff,  // 6th Setting
+      0x00, 0x00, 0x00, 0x06,
+    };
+    scoped_ptr<SpdySettingsControlFrame> frame(framer.CreateSettings(settings));
+    CompareFrame(kDescription,
+                 *frame,
+                 kFrameData,
+                 arraysize(kFrameData));
+    EXPECT_EQ(SpdyFramer::kInvalidStream,
+              SpdyFramer::GetControlFrameStreamId(frame.get()));
+  }
+
+  {
+    const char kDescription[] = "Empty SETTINGS frame";
+
+    SettingsMap settings;
+
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x04,
+      0x00, 0x00, 0x00, 0x04,
+      0x00, 0x00, 0x00, 0x00,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreatePingFrame) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "PING frame";
+    const unsigned char kFrameData[] = {
+        0x80, spdy_version_, 0x00, 0x06,
+        0x00, 0x00, 0x00, 0x04,
+        0x12, 0x34, 0x56, 0x78,
+    };
+    scoped_ptr<SpdyPingControlFrame> frame(framer.CreatePingFrame(0x12345678u));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    EXPECT_EQ(SpdyFramer::kInvalidStream,
+              SpdyFramer::GetControlFrameStreamId(frame.get()));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateGoAway) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "GOAWAY frame";
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x07,
+      0x00, 0x00, 0x00, 0x04,
+      0x00, 0x00, 0x00, 0x00,
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x07,
+      0x00, 0x00, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+    };
+    scoped_ptr<SpdyGoAwayControlFrame> frame(framer.CreateGoAway(0, GOAWAY_OK));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+    EXPECT_EQ(SpdyFramer::kInvalidStream,
+              SpdyFramer::GetControlFrameStreamId(frame.get()));
+  }
+
+  {
+    const char kDescription[] = "GOAWAY frame with max stream ID, status";
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x07,
+      0x00, 0x00, 0x00, 0x04,
+      0x7f, 0xff, 0xff, 0xff,
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x07,
+      0x00, 0x00, 0x00, 0x08,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0x7FFFFFFF,
+                                                    GOAWAY_INTERNAL_ERROR));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(false);
+
+  {
+    const char kDescription[] = "HEADERS frame, no FIN";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x1C,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x03, 'b',  'a',  'r'
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x24,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'b',  'a',  'r',  0x00,
+      0x00, 0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x00,
+      0x00, 0x03, 'f',  'o',
+      'o',  0x00, 0x00, 0x00,
+      0x03, 'b',  'a',  'r'
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
+        1, CONTROL_FLAG_NONE, false, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header name, FIN, max stream ID";
+
+    SpdyHeaderBlock headers;
+    headers[""] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x01, 0x00, 0x00, 0x19,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x03, 'f',  'o',  'o',
+      0x00, 0x03, 'b',  'a',
+      'r'
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x01, 0x00, 0x00, 0x21,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00, 0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x00,
+      0x00, 0x03, 'b',  'a',
+      'r'
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
+        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header val, FIN, max stream ID";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x01, 0x00, 0x00, 0x19,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x03, 'b',  'a',
+      'r',  0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x03,
+      'f',  'o',  'o',  0x00,
+      0x00
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x01, 0x00, 0x00, 0x21,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x02,
+      0x00, 0x00, 0x00, 0x03,
+      'b',  'a',  'r',  0x00,
+      0x00, 0x00, 0x03, 'f',
+      'o',  'o',  0x00, 0x00,
+      0x00, 0x03, 'f',  'o',
+      'o',  0x00, 0x00, 0x00,
+      0x00
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
+        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+
+// TODO(phajdan.jr): Clean up after we no longer need
+// to workaround http://crbug.com/139744.
+#if !defined(USE_SYSTEM_ZLIB)
+TEST_P(SpdyFramerTest, CreateHeadersCompressed) {
+  SpdyFramer framer(spdy_version_);
+  framer.set_enable_compression(true);
+
+  {
+    const char kDescription[] = "HEADERS frame, no FIN";
+
+    SpdyHeaderBlock headers;
+    headers["bar"] = "foo";
+    headers["foo"] = "bar";
+
+    const unsigned char kV2FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x32,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x38, 0xea,
+      0xdf, 0xa2, 0x51, 0xb2,
+      0x62, 0x60, 0x62, 0x60,
+      0x4e, 0x4a, 0x2c, 0x62,
+      0x60, 0x06, 0x08, 0xa0,
+      0xb4, 0xfc, 0x7c, 0x80,
+      0x00, 0x62, 0x60, 0x4e,
+      0xcb, 0xcf, 0x67, 0x60,
+      0x06, 0x08, 0xa0, 0xa4,
+      0xc4, 0x22, 0x80, 0x00,
+      0x02, 0x00, 0x00, 0x00,
+      0xff, 0xff,
+    };
+    const unsigned char kV3FrameData[] = {
+      0x80, spdy_version_, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x31,
+      0x00, 0x00, 0x00, 0x01,
+      0x38, 0xea, 0xe3, 0xc6,
+      0xa7, 0xc2, 0x02, 0xe5,
+      0x0e, 0x50, 0xc2, 0x4b,
+      0x4a, 0x04, 0xe5, 0x0b,
+      0x66, 0x80, 0x00, 0x4a,
+      0xcb, 0xcf, 0x07, 0x08,
+      0x20, 0x10, 0x95, 0x96,
+      0x9f, 0x0f, 0xa2, 0x00,
+      0x02, 0x28, 0x29, 0xb1,
+      0x08, 0x20, 0x80, 0x00,
+      0x00, 0x00, 0x00, 0xff,
+      0xff,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
+        1, CONTROL_FLAG_NONE, true, &headers));
+    CompareFrame(kDescription,
+                 *frame,
+                 IsSpdy2() ? kV2FrameData : kV3FrameData,
+                 IsSpdy2() ? arraysize(kV2FrameData) : arraysize(kV3FrameData));
+  }
+}
+#endif  // !defined(USE_SYSTEM_ZLIB)
+
+TEST_P(SpdyFramerTest, CreateWindowUpdate) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "WINDOW_UPDATE frame";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x09,
+      0x00, 0x00, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x01,
+    };
+    scoped_ptr<SpdyWindowUpdateControlFrame> frame(
+        framer.CreateWindowUpdate(1, 1));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
+  }
+
+  {
+    const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x09,
+      0x00, 0x00, 0x00, 0x08,
+      0x7f, 0xff, 0xff, 0xff,
+      0x00, 0x00, 0x00, 0x01,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(0x7FFFFFFF, 1));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
+    const unsigned char kFrameData[] = {
+      0x80, spdy_version_, 0x00, 0x09,
+      0x00, 0x00, 0x00, 0x08,
+      0x00, 0x00, 0x00, 0x01,
+      0x7f, 0xff, 0xff, 0xff,
+    };
+    scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x7FFFFFFF));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, DuplicateFrame) {
+  SpdyFramer framer(spdy_version_);
+
+  {
+    const char kDescription[] = "PING frame";
+    const unsigned char kFrameData[] = {
+        0x80, spdy_version_, 0x00, 0x06,
+        0x00, 0x00, 0x00, 0x04,
+        0x12, 0x34, 0x56, 0x78,
+    };
+    scoped_ptr<SpdyFrame> frame1(framer.CreatePingFrame(0x12345678u));
+    CompareFrame(kDescription, *frame1, kFrameData, arraysize(kFrameData));
+
+    scoped_ptr<SpdyFrame> frame2(framer.DuplicateFrame(*frame1));
+    CompareFrame(kDescription, *frame2, kFrameData, arraysize(kFrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedSynStreamHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["aa"] = "vv";
+  headers["bb"] = "ww";
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                     // stream_id
+                             0,                     // associated_stream_id
+                             1,                     // priority
+                             0,                     // credential_slot
+                             CONTROL_FLAG_NONE,
+                             true,                  // compress
+                             &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedSynReplyHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdySynReplyControlFrame> control_frame(
+      framer.CreateSynReply(1,                     // stream_id
+                            CONTROL_FLAG_NONE,
+                            true,                  // compress
+                            &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyHeadersControlFrame> control_frame(
+      framer.CreateHeaders(1,                     // stream_id
+                           CONTROL_FLAG_NONE,
+                           true,                  // compress
+                           &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  // control_frame_header_data_count_ depends on the random sequence
+  // produced by rand(), so adding, removing or running single tests
+  // alters this value.  The best we can do is assert that it happens
+  // at least twice.
+  EXPECT_LE(2, visitor.control_frame_header_data_count_);
+  EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
+  SpdyHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "delta";
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyHeadersControlFrame> control_frame(
+      framer.CreateHeaders(1,                     // stream_id
+                           CONTROL_FLAG_FIN,
+                           true,                  // compress
+                           &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  // control_frame_header_data_count_ depends on the random sequence
+  // produced by rand(), so adding, removing or running single tests
+  // alters this value.  The best we can do is assert that it happens
+  // at least twice.
+  EXPECT_LE(2, visitor.control_frame_header_data_count_);
+  EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+}
+
+TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
+  SpdyHeaderBlock headers;
+  // Size a header value to just fit inside the control frame buffer:
+  //                               SPDY 2             SPDY 3
+  //   SYN_STREAM header:          18 bytes           18 bytes
+  //   Serialized header block:
+  //     # headers                  2 bytes (uint16)   4 bytes (uint32)
+  //     name length                2 bytes (uint16)   4 bytes (uint32)
+  //     name text ("aa")           2 bytes            2 bytes
+  //     value length               2 bytes (uint16)   4 bytes (uint32)
+  //                              ---                ---
+  //                               26 bytes           32 bytes
+  const size_t overhead = IsSpdy2() ? 26 : 32;
+  const size_t big_value_size =
+      TestSpdyVisitor::control_frame_buffer_max_size() - overhead;
+  std::string big_value(big_value_size, 'x');
+  headers["aa"] = big_value.c_str();
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                     // stream_id
+                             0,                     // associated_stream_id
+                             1,                     // priority
+                             0,                     // credential_slot
+                             CONTROL_FLAG_NONE,
+                             false,                 // compress
+                             &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.syn_frame_count_);
+  EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+  EXPECT_LT(big_value_size, visitor.header_buffer_length_);
+}
+
+TEST_P(SpdyFramerTest, ControlFrameTooLarge) {
+  SpdyHeaderBlock headers;
+  // See size calculation for test above. This is one byte larger, which
+  // should exceed the control frame buffer capacity by that one byte.
+  const size_t overhead = IsSpdy2() ? 25 : 31;
+  const size_t kBigValueSize =
+      TestSpdyVisitor::control_frame_buffer_max_size() - overhead;
+  std::string big_value(kBigValueSize, 'x');
+  headers["aa"] = big_value.c_str();
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                     // stream_id
+                             0,                     // associated_stream_id
+                             1,                     // priority
+                             0,                     // credential_slot
+                             CONTROL_FLAG_NONE,
+                             false,                 // compress
+                             &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_FALSE(visitor.header_buffer_valid_);
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
+            visitor.framer_.error_code());
+  EXPECT_EQ(0, visitor.syn_frame_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+}
+
+// Check that the framer stops delivering header data chunks once the visitor
+// declares it doesn't want any more. This is important to guard against
+// "zip bomb" types of attacks.
+TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
+  SpdyHeaderBlock headers;
+  const size_t kHeaderBufferChunks = 4;
+  const size_t kHeaderBufferSize =
+      TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks;
+  const size_t big_value_size = kHeaderBufferSize * 2;
+  std::string big_value(big_value_size, 'x');
+  headers["aa"] = big_value.c_str();
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                     // stream_id
+                             0,                     // associated_stream_id
+                             1,                     // priority
+                             0,                     // credential_slot
+                             CONTROL_FLAG_FIN,      // half close
+                             true,                  // compress
+                             &headers));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.set_header_buffer_size(kHeaderBufferSize);
+  visitor.use_compression_ = true;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_FALSE(visitor.header_buffer_valid_);
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
+            visitor.framer_.error_code());
+
+  // The framer should have stoped delivering chunks after the visitor
+  // signaled "stop" by returning false from OnControlFrameHeaderData().
+  //
+  // control_frame_header_data_count_ depends on the random sequence
+  // produced by rand(), so adding, removing or running single tests
+  // alters this value.  The best we can do is assert that it happens
+  // at least kHeaderBufferChunks + 1.
+  EXPECT_LE(kHeaderBufferChunks + 1,
+            static_cast<unsigned>(visitor.control_frame_header_data_count_));
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  // The framer should not have sent half-close to the visitor.
+  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) {
+  SpdyHeaderBlock headers;
+  headers["aa"] = "alpha beta gamma delta";
+  SpdyFramer framer(spdy_version_);
+  // Construct a SYN_STREAM control frame without compressing the header block,
+  // and have the framer try to decompress it. This will cause the framer to
+  // deal with a decompression error.
+  scoped_ptr<SpdySynStreamControlFrame> control_frame(
+      framer.CreateSynStream(1,                     // stream_id
+                             0,                     // associated_stream_id
+                             1,                     // priority
+                             0,                     // credential_slot
+                             CONTROL_FLAG_NONE,
+                             false,                 // compress
+                             &headers));
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = true;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(SpdyFramer::SPDY_DECOMPRESS_FAILURE, visitor.framer_.error_code());
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+}
+
+TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
+  // Create a GoAway frame that has a few extra bytes at the end.
+  // We create enough overhead to overflow the framer's control frame buffer.
+  size_t overhead = SpdyFramer::kControlFrameBufferSize;
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyGoAwayControlFrame> goaway(framer.CreateGoAway(1, GOAWAY_OK));
+  goaway->set_length(goaway->length() + overhead);
+  string pad('A', overhead);
+  TestSpdyVisitor visitor(spdy_version_);
+
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(goaway->data()),
+      goaway->length() - overhead + SpdyControlFrame::kHeaderSize);
+  visitor.SimulateInFramer(
+      reinterpret_cast<const unsigned char*>(pad.c_str()),
+      overhead);
+
+  EXPECT_EQ(1, visitor.error_count_);  // This generated an error.
+  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME,
+            visitor.framer_.error_code());
+  EXPECT_EQ(0, visitor.goaway_count_);  // Frame not parsed.
+}
+
+TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
+  SpdyFramer framer(spdy_version_);
+  SettingsMap settings;
+  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+  control_frame->set_length(0);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  // Should generate an error, since zero-len settings frames are unsupported.
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+// Tests handling of SETTINGS frames with invalid length.
+TEST_P(SpdyFramerTest, ReadBogusLenSettingsFrame) {
+  SpdyFramer framer(spdy_version_);
+  SettingsMap settings;
+  // Add a setting to pad the frame so that we don't get a buffer overflow when
+  // calling SimulateInFramer() below.
+  settings[SETTINGS_UPLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, 0x00000002);
+  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+  control_frame->set_length(5);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  // Should generate an error, since zero-len settings frames are unsupported.
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+// Tests handling of SETTINGS frames larger than the frame buffer size.
+TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
+  SpdyFramer framer(spdy_version_);
+  SettingsMap settings;
+  SpdySettingsFlags flags = SETTINGS_FLAG_PLEASE_PERSIST;
+  settings[SETTINGS_UPLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(flags, 0x00000002);
+  settings[SETTINGS_DOWNLOAD_BANDWIDTH] =
+      SettingsFlagsAndValue(flags, 0x00000003);
+  settings[SETTINGS_ROUND_TRIP_TIME] = SettingsFlagsAndValue(flags, 0x00000004);
+  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+  EXPECT_LT(SpdyFramer::kControlFrameBufferSize,
+            control_frame->length() + SpdyControlFrame::kHeaderSize);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+
+  // Read all at once.
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(settings.size(), static_cast<unsigned>(visitor.setting_count_));
+
+  // Read data in small chunks.
+  size_t framed_data = 0;
+  size_t unframed_data = control_frame->length() +
+                         SpdyControlFrame::kHeaderSize;
+  size_t kReadChunkSize = 5;  // Read five bytes at a time.
+  while (unframed_data > 0) {
+    size_t to_read = min(kReadChunkSize, unframed_data);
+    visitor.SimulateInFramer(
+        reinterpret_cast<unsigned char*>(control_frame->data() + framed_data),
+        to_read);
+    unframed_data -= to_read;
+    framed_data += to_read;
+  }
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(settings.size() * 2, static_cast<unsigned>(visitor.setting_count_));
+}
+
+// Tests handling of SETTINGS frame with duplicate entries.
+TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
+  SpdyFramer framer(spdy_version_);
+
+  const unsigned char kV2FrameData[] = {
+    0x80, spdy_version_, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x1C,
+    0x00, 0x00, 0x00, 0x03,
+    0x01, 0x00, 0x00, 0x00,  // 1st Setting
+    0x00, 0x00, 0x00, 0x02,
+    0x01, 0x00, 0x00, 0x00,  // 2nd (duplicate) Setting
+    0x00, 0x00, 0x00, 0x03,
+    0x03, 0x00, 0x00, 0x00,  // 3rd (unprocessed) Setting
+    0x00, 0x00, 0x00, 0x03,
+  };
+
+  const unsigned char kV3FrameData[] = {
+    0x80, spdy_version_, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x1C,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x01,  // 1st Setting
+    0x00, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x01,  // 2nd (duplicate) Setting
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x03,  // 3rd (unprocessed) Setting
+    0x00, 0x00, 0x00, 0x03,
+  };
+
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  if (IsSpdy2()) {
+    visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
+  } else {
+    visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
+  }
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(1, visitor.setting_count_);
+}
+
+// Tests handling of SETTINGS frame with entries out of order.
+TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
+  SpdyFramer framer(spdy_version_);
+
+  const unsigned char kV2FrameData[] = {
+    0x80, spdy_version_, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x1C,
+    0x00, 0x00, 0x00, 0x03,
+    0x02, 0x00, 0x00, 0x00,  // 1st Setting
+    0x00, 0x00, 0x00, 0x02,
+    0x01, 0x00, 0x00, 0x00,  // 2nd (out of order) Setting
+    0x00, 0x00, 0x00, 0x03,
+    0x03, 0x00, 0x00, 0x00,  // 3rd (unprocessed) Setting
+    0x00, 0x00, 0x00, 0x03,
+  };
+
+  const unsigned char kV3FrameData[] = {
+    0x80, spdy_version_, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x1C,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x02,  // 1st Setting
+    0x00, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x01,  // 2nd (out of order) Setting
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x01, 0x03,  // 3rd (unprocessed) Setting
+    0x00, 0x00, 0x00, 0x03,
+  };
+
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  if (IsSpdy2()) {
+    visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
+  } else {
+    visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
+  }
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(1, visitor.setting_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadWindowUpdate) {
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyWindowUpdateControlFrame> control_frame(
+      framer.CreateWindowUpdate(1, 2));
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.last_window_update_stream_);
+  EXPECT_EQ(2, visitor.last_window_update_delta_);
+}
+
+TEST_P(SpdyFramerTest, ReadCredentialFrame) {
+  SpdyCredential credential;
+  credential.slot = 3;
+  credential.proof = "proof";
+  credential.certs.push_back("a cert");
+  credential.certs.push_back("another cert");
+  credential.certs.push_back("final cert");
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyFrame> control_frame(
+      framer.CreateCredentialFrame(credential));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame->data()),
+      control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_);
+  EXPECT_EQ(credential.slot, visitor.credential_.slot);
+  EXPECT_EQ(credential.proof, visitor.credential_.proof);
+  EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
+  for (size_t i = 0; i < credential.certs.size(); i++) {
+    EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
+  }
+}
+
+TEST_P(SpdyFramerTest, ReadCredentialFrameOneByteAtATime) {
+  SpdyCredential credential;
+  credential.slot = 3;
+  credential.proof = "proof";
+  credential.certs.push_back("a cert");
+  credential.certs.push_back("another cert");
+  credential.certs.push_back("final cert");
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyFrame> control_frame(
+      framer.CreateCredentialFrame(credential));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  // Read one byte at a time to make sure we handle edge cases
+  unsigned char* data =
+      reinterpret_cast<unsigned char*>(control_frame->data());
+  for (size_t idx = 0;
+       idx < control_frame->length() + SpdyFrame::kHeaderSize;
+       ++idx) {
+    visitor.SimulateInFramer(data + idx, 1);
+    ASSERT_EQ(0, visitor.error_count_);
+  }
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_);
+  EXPECT_EQ(credential.slot, visitor.credential_.slot);
+  EXPECT_EQ(credential.proof, visitor.credential_.proof);
+  EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
+  for (size_t i = 0; i < credential.certs.size(); i++) {
+    EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
+  }
+}
+
+TEST_P(SpdyFramerTest, ReadCredentialFrameWithNoPayload) {
+  SpdyCredential credential;
+  credential.slot = 3;
+  credential.proof = "proof";
+  credential.certs.push_back("a cert");
+  credential.certs.push_back("another cert");
+  credential.certs.push_back("final cert");
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyFrame> control_frame(
+      framer.CreateCredentialFrame(credential));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  control_frame->set_length(0);
+  unsigned char* data =
+      reinterpret_cast<unsigned char*>(control_frame->data());
+  visitor.SimulateInFramer(data, SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) {
+  SpdyCredential credential;
+  credential.slot = 3;
+  credential.proof = "proof";
+  credential.certs.push_back("a cert");
+  credential.certs.push_back("another cert");
+  credential.certs.push_back("final cert");
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyFrame> control_frame(
+      framer.CreateCredentialFrame(credential));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  unsigned char* data =
+      reinterpret_cast<unsigned char*>(control_frame->data());
+  size_t offset = SpdyControlFrame::kHeaderSize + 4;
+  data[offset] = 0xFF;  // Proof length is past the end of the frame
+  visitor.SimulateInFramer(
+      data, control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadCredentialFrameWithCorruptCertificate) {
+  SpdyCredential credential;
+  credential.slot = 3;
+  credential.proof = "proof";
+  credential.certs.push_back("a cert");
+  credential.certs.push_back("another cert");
+  credential.certs.push_back("final cert");
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyFrame> control_frame(
+      framer.CreateCredentialFrame(credential));
+  EXPECT_TRUE(control_frame.get() != NULL);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  unsigned char* data =
+      reinterpret_cast<unsigned char*>(control_frame->data());
+  size_t offset = SpdyControlFrame::kHeaderSize + credential.proof.length();
+  data[offset] = 0xFF;  // Certificate length is past the end of the frame
+  visitor.SimulateInFramer(
+      data, control_frame->length() + SpdyControlFrame::kHeaderSize);
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadGarbage) {
+  SpdyFramer framer(spdy_version_);
+  unsigned char garbage_frame[256];
+  memset(garbage_frame, ~0, sizeof(garbage_frame));
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadGarbageWithValidVersion) {
+  SpdyFramer framer(spdy_version_);
+  char garbage_frame[256];
+  memset(garbage_frame, ~0, sizeof(garbage_frame));
+  SpdyControlFrame control_frame(&garbage_frame[0], false);
+  control_frame.set_version(spdy_version_);
+  TestSpdyVisitor visitor(spdy_version_);
+  visitor.use_compression_ = false;
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      sizeof(garbage_frame));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, StateToStringTest) {
+  EXPECT_STREQ("ERROR",
+               SpdyFramer::StateToString(SpdyFramer::SPDY_ERROR));
+  EXPECT_STREQ("DONE",
+               SpdyFramer::StateToString(SpdyFramer::SPDY_DONE));
+  EXPECT_STREQ("AUTO_RESET",
+               SpdyFramer::StateToString(SpdyFramer::SPDY_AUTO_RESET));
+  EXPECT_STREQ("RESET",
+               SpdyFramer::StateToString(SpdyFramer::SPDY_RESET));
+  EXPECT_STREQ("READING_COMMON_HEADER",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_READING_COMMON_HEADER));
+  EXPECT_STREQ("CONTROL_FRAME_PAYLOAD",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_CONTROL_FRAME_PAYLOAD));
+  EXPECT_STREQ("IGNORE_REMAINING_PAYLOAD",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_IGNORE_REMAINING_PAYLOAD));
+  EXPECT_STREQ("FORWARD_STREAM_FRAME",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_FORWARD_STREAM_FRAME));
+  EXPECT_STREQ("SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK));
+  EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_CONTROL_FRAME_HEADER_BLOCK));
+  EXPECT_STREQ("SPDY_CREDENTIAL_FRAME_PAYLOAD",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD));
+  EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD));
+  EXPECT_STREQ("UNKNOWN_STATE",
+               SpdyFramer::StateToString(
+                   SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD + 1));
+}
+
+TEST_P(SpdyFramerTest, ErrorCodeToStringTest) {
+  EXPECT_STREQ("NO_ERROR",
+               SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_NO_ERROR));
+  EXPECT_STREQ("INVALID_CONTROL_FRAME",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
+  EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
+  EXPECT_STREQ("ZLIB_INIT_FAILURE",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_ZLIB_INIT_FAILURE));
+  EXPECT_STREQ("UNSUPPORTED_VERSION",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_UNSUPPORTED_VERSION));
+  EXPECT_STREQ("DECOMPRESS_FAILURE",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_DECOMPRESS_FAILURE));
+  EXPECT_STREQ("COMPRESS_FAILURE",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_COMPRESS_FAILURE));
+  EXPECT_STREQ("SPDY_INVALID_DATA_FRAME_FLAGS",
+               SpdyFramer::ErrorCodeToString(
+                   SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS));
+  EXPECT_STREQ("UNKNOWN_ERROR",
+               SpdyFramer::ErrorCodeToString(SpdyFramer::LAST_ERROR));
+}
+
+TEST_P(SpdyFramerTest, StatusCodeToStringTest) {
+  EXPECT_STREQ("INVALID",
+               SpdyFramer::StatusCodeToString(INVALID));
+  EXPECT_STREQ("PROTOCOL_ERROR",
+               SpdyFramer::StatusCodeToString(PROTOCOL_ERROR));
+  EXPECT_STREQ("INVALID_STREAM",
+               SpdyFramer::StatusCodeToString(INVALID_STREAM));
+  EXPECT_STREQ("REFUSED_STREAM",
+               SpdyFramer::StatusCodeToString(REFUSED_STREAM));
+  EXPECT_STREQ("UNSUPPORTED_VERSION",
+               SpdyFramer::StatusCodeToString(UNSUPPORTED_VERSION));
+  EXPECT_STREQ("CANCEL",
+               SpdyFramer::StatusCodeToString(CANCEL));
+  EXPECT_STREQ("INTERNAL_ERROR",
+               SpdyFramer::StatusCodeToString(INTERNAL_ERROR));
+  EXPECT_STREQ("FLOW_CONTROL_ERROR",
+               SpdyFramer::StatusCodeToString(FLOW_CONTROL_ERROR));
+  EXPECT_STREQ("UNKNOWN_STATUS",
+               SpdyFramer::StatusCodeToString(NUM_STATUS_CODES));
+}
+
+TEST_P(SpdyFramerTest, ControlTypeToStringTest) {
+  EXPECT_STREQ("SYN_STREAM",
+               SpdyFramer::ControlTypeToString(SYN_STREAM));
+  EXPECT_STREQ("SYN_REPLY",
+               SpdyFramer::ControlTypeToString(SYN_REPLY));
+  EXPECT_STREQ("RST_STREAM",
+               SpdyFramer::ControlTypeToString(RST_STREAM));
+  EXPECT_STREQ("SETTINGS",
+               SpdyFramer::ControlTypeToString(SETTINGS));
+  EXPECT_STREQ("NOOP",
+               SpdyFramer::ControlTypeToString(NOOP));
+  EXPECT_STREQ("PING",
+               SpdyFramer::ControlTypeToString(PING));
+  EXPECT_STREQ("GOAWAY",
+               SpdyFramer::ControlTypeToString(GOAWAY));
+  EXPECT_STREQ("HEADERS",
+               SpdyFramer::ControlTypeToString(HEADERS));
+  EXPECT_STREQ("WINDOW_UPDATE",
+               SpdyFramer::ControlTypeToString(WINDOW_UPDATE));
+  EXPECT_STREQ("CREDENTIAL",
+               SpdyFramer::ControlTypeToString(CREDENTIAL));
+  EXPECT_STREQ("UNKNOWN_CONTROL_TYPE",
+               SpdyFramer::ControlTypeToString(NUM_CONTROL_FRAME_TYPES));
+}
+
+TEST_P(SpdyFramerTest, GetMinimumControlFrameSizeTest) {
+  EXPECT_EQ(SpdySynStreamControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   SYN_STREAM));
+  EXPECT_EQ(SpdySynReplyControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   SYN_REPLY));
+  EXPECT_EQ(SpdyRstStreamControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   RST_STREAM));
+  EXPECT_EQ(SpdySettingsControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   SETTINGS));
+
+#if defined(__LB_SHELL__) || defined(COBALT)
+  // Compiler quirk: <function> declared using a type with no linkage,
+  // must be defined in this translation unit
+  unsigned int spdy_frame_header_size = SpdyFrame::kHeaderSize;
+  EXPECT_EQ(spdy_frame_header_size,
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   NOOP));
+#else
+  EXPECT_EQ(SpdyFrame::kHeaderSize,
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   NOOP));
+#endif
+  EXPECT_EQ(SpdyPingControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   PING));
+  size_t goaway_size = SpdyGoAwayControlFrame::size();
+  if (IsSpdy2()) {
+    // SPDY 2 GOAWAY is smaller by 32 bits.
+    goaway_size -= 4;
+  }
+  EXPECT_EQ(goaway_size,
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   GOAWAY));
+  EXPECT_EQ(SpdyHeadersControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   HEADERS));
+  EXPECT_EQ(SpdyWindowUpdateControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   WINDOW_UPDATE));
+  EXPECT_EQ(SpdyCredentialControlFrame::size(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   CREDENTIAL));
+  EXPECT_EQ(numeric_limits<size_t>::max(),
+            SpdyFramer::GetMinimumControlFrameSize(spdy_version_,
+                                                   NUM_CONTROL_FRAME_TYPES));
+}
+
+TEST_P(SpdyFramerTest, CatchProbableHttpResponse) {
+  {
+    testing::StrictMock<test::MockVisitor> visitor;
+    SpdyFramer framer(spdy_version_);
+    framer.set_visitor(&visitor);
+
+    // This won't cause an error at the framer level.  It will cause
+    // flag validation errors at the Visitor::OnDataFrameHeader level.
+    EXPECT_CALL(visitor, OnDataFrameHeader(_));
+    framer.ProcessInput("HTTP/1.1", 8);
+    EXPECT_TRUE(framer.probable_http_response());
+    EXPECT_EQ(SpdyFramer::SPDY_FORWARD_STREAM_FRAME, framer.state());
+  }
+  {
+    testing::StrictMock<test::MockVisitor> visitor;
+    SpdyFramer framer(spdy_version_);
+    framer.set_visitor(&visitor);
+
+    // This won't cause an error at the framer level.  It will cause
+    // flag validation errors at the Visitor::OnDataFrameHeader level.
+    EXPECT_CALL(visitor, OnDataFrameHeader(_));
+    framer.ProcessInput("HTTP/1.0", 8);
+    EXPECT_TRUE(framer.probable_http_response());
+    EXPECT_EQ(SpdyFramer::SPDY_FORWARD_STREAM_FRAME, framer.state());
+  }
+}
+
+TEST_P(SpdyFramerTest, DataFrameFlags) {
+  for (int flags = 0; flags < 256; ++flags) {
+    SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+    testing::StrictMock<test::MockVisitor> visitor;
+    SpdyFramer framer(spdy_version_);
+    framer.set_visitor(&visitor);
+
+    scoped_ptr<SpdyFrame> frame(
+        framer.CreateDataFrame(1, "hello", 5, DATA_FLAG_NONE));
+    frame->set_flags(flags);
+
+    // Flags are just passed along since they need to be validated at
+    // a higher protocol layer.
+    EXPECT_CALL(visitor, OnDataFrameHeader(_));
+    EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, SpdyDataFlags()));
+    if (flags & DATA_FLAG_FIN) {
+      EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, DATA_FLAG_FIN));
+    }
+
+    size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+    framer.ProcessInput(frame->data(), frame_size);
+    EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+    EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+  }
+}
+
+TEST_P(SpdyFramerTest, EmptySynStream) {
+  SpdyHeaderBlock headers;
+
+  testing::StrictMock<test::MockVisitor> visitor;
+  SpdyFramer framer(spdy_version_);
+  framer.set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnControlFrameCompressed(_, _));
+  scoped_ptr<SpdySynStreamControlFrame>
+      frame(framer.CreateSynStream(1, 0, 1, 0, CONTROL_FLAG_NONE, true,
+                                   &headers));
+  // Adjust size to remove the name/value block.
+  frame->set_length(
+      SpdySynStreamControlFrame::size() - SpdyFrame::kHeaderSize);
+
+  EXPECT_CALL(visitor, OnSynStream(1, 0, 1, 0, false, false));
+  EXPECT_CALL(visitor, OnControlFrameHeaderData(1, NULL, 0));
+
+  size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+  framer.ProcessInput(frame->data(), frame_size);
+  EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+  EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+}
+
+TEST_P(SpdyFramerTest, SettingsFlagsAndId) {
+  const uint32 kId = 0x020304;
+  const uint32 kFlags = 0x01;
+  const uint32 kWireFormat = htonl(IsSpdy2() ? 0x04030201 : 0x01020304);
+
+  SettingsFlagsAndId id_and_flags =
+      SettingsFlagsAndId::FromWireFormat(spdy_version_, kWireFormat);
+  EXPECT_EQ(kId, id_and_flags.id());
+  EXPECT_EQ(kFlags, id_and_flags.flags());
+  EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(spdy_version_));
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_header_block.cc b/src/net/spdy/spdy_header_block.cc
new file mode 100644
index 0000000..3680cb4
--- /dev/null
+++ b/src/net/spdy/spdy_header_block.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_header_block.h"
+
+#include "base/values.h"
+
+namespace net {
+
+Value* SpdyHeaderBlockNetLogCallback(
+    const SpdyHeaderBlock* headers,
+    NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  DictionaryValue* headers_dict = new DictionaryValue();
+  for (SpdyHeaderBlock::const_iterator it = headers->begin();
+       it != headers->end(); ++it) {
+    headers_dict->SetWithoutPathExpansion(
+        it->first, new StringValue(it->second));
+  }
+  dict->Set("headers", headers_dict);
+  return dict;
+}
+
+bool SpdyHeaderBlockFromNetLogParam(
+    const base::Value* event_param,
+    SpdyHeaderBlock* headers) {
+  headers->clear();
+
+  const base::DictionaryValue* dict = NULL;
+  const base::DictionaryValue* header_dict = NULL;
+
+  if (!event_param ||
+      !event_param->GetAsDictionary(&dict) ||
+      !dict->GetDictionary("headers", &header_dict)) {
+    return false;
+  }
+
+  for (base::DictionaryValue::key_iterator it = header_dict->begin_keys();
+       it != header_dict->end_keys();
+       ++it) {
+    std::string value;
+    if (!header_dict->GetString(*it, &(*headers)[*it])) {
+      headers->clear();
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_header_block.h b/src/net/spdy/spdy_header_block.h
new file mode 100644
index 0000000..8ae8fa3
--- /dev/null
+++ b/src/net/spdy/spdy_header_block.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_HEADER_BLOCK_H_
+#define NET_SPDY_SPDY_HEADER_BLOCK_H_
+
+#include <map>
+#include <string>
+
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+
+namespace net {
+
+// A data structure for holding a set of headers from either a
+// SYN_STREAM or SYN_REPLY frame.
+typedef std::map<std::string, std::string> SpdyHeaderBlock;
+
+// Converts a SpdyHeaderBlock into NetLog event parameters.  Caller takes
+// ownership of returned value.
+NET_EXPORT base::Value* SpdyHeaderBlockNetLogCallback(
+    const SpdyHeaderBlock* headers,
+    NetLog::LogLevel log_level);
+
+// Converts NetLog event parameters into a SPDY header block and writes them
+// to |headers|.  |event_param| must have been created by
+// SpdyHeaderBlockNetLogCallback.  On failure, returns false and clears
+// |headers|.
+NET_EXPORT bool SpdyHeaderBlockFromNetLogParam(
+    const base::Value* event_param,
+    SpdyHeaderBlock* headers);
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_HEADER_BLOCK_H_
diff --git a/src/net/spdy/spdy_header_block_unittest.cc b/src/net/spdy/spdy_header_block_unittest.cc
new file mode 100644
index 0000000..3cfef16
--- /dev/null
+++ b/src/net/spdy/spdy_header_block_unittest.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_header_block.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "net/base/net_log.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(SpdyHeaderBlockTest, ToNetLogParamAndBackAgain) {
+  SpdyHeaderBlock headers;
+  headers["A"] = "a";
+  headers["B"] = "b";
+
+  scoped_ptr<Value> event_param(
+      SpdyHeaderBlockNetLogCallback(&headers, NetLog::LOG_ALL_BUT_BYTES));
+
+  SpdyHeaderBlock headers2;
+  ASSERT_TRUE(SpdyHeaderBlockFromNetLogParam(event_param.get(), &headers2));
+  EXPECT_EQ(headers, headers2);
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_http_stream.cc b/src/net/spdy/spdy_http_stream.cc
new file mode 100644
index 0000000..ab1b32f
--- /dev/null
+++ b/src/net/spdy/spdy_http_stream.cc
@@ -0,0 +1,534 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_http_stream.h"
+
+#include <algorithm>
+#include <list>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/stringprintf.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_log.h"
+#include "net/base/net_util.h"
+#include "net/base/upload_data_stream.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_info.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+
+namespace net {
+
+SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session,
+                               bool direct)
+    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+      stream_(NULL),
+      spdy_session_(spdy_session),
+      request_info_(NULL),
+      has_upload_data_(false),
+      response_info_(NULL),
+      download_finished_(false),
+      response_headers_received_(false),
+      user_buffer_len_(0),
+      buffered_read_callback_pending_(false),
+      more_read_data_pending_(false),
+      direct_(direct) { }
+
+void SpdyHttpStream::InitializeWithExistingStream(SpdyStream* spdy_stream) {
+  stream_ = spdy_stream;
+  stream_->SetDelegate(this);
+  response_headers_received_ = true;
+}
+
+SpdyHttpStream::~SpdyHttpStream() {
+  if (stream_)
+    stream_->DetachDelegate();
+}
+
+int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
+                                     const BoundNetLog& stream_net_log,
+                                     const CompletionCallback& callback) {
+  DCHECK(!stream_.get());
+  if (spdy_session_->IsClosed())
+   return ERR_CONNECTION_CLOSED;
+
+  request_info_ = request_info;
+  if (request_info_->method == "GET") {
+    int error = spdy_session_->GetPushStream(request_info_->url, &stream_,
+                                             stream_net_log);
+    if (error != OK)
+      return error;
+  }
+
+  if (stream_.get())
+    return OK;
+
+  return spdy_session_->CreateStream(request_info_->url,
+                                     request_info_->priority, &stream_,
+                                     stream_net_log, callback);
+}
+
+const HttpResponseInfo* SpdyHttpStream::GetResponseInfo() const {
+  return response_info_;
+}
+
+UploadProgress SpdyHttpStream::GetUploadProgress() const {
+  if (!request_info_ || !request_info_->upload_data_stream)
+    return UploadProgress();
+
+  return UploadProgress(request_info_->upload_data_stream->position(),
+                        request_info_->upload_data_stream->size());
+}
+
+int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
+  CHECK(!callback.is_null());
+  CHECK(!stream_->cancelled());
+
+  if (stream_->closed())
+    return stream_->response_status();
+
+  // Check if we already have the response headers. If so, return synchronously.
+  if(stream_->response_received()) {
+    CHECK(stream_->is_idle());
+    return OK;
+  }
+
+  // Still waiting for the response, return IO_PENDING.
+  CHECK(callback_.is_null());
+  callback_ = callback;
+  return ERR_IO_PENDING;
+}
+
+int SpdyHttpStream::ReadResponseBody(
+    IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
+  CHECK(stream_->is_idle());
+  CHECK(buf);
+  CHECK(buf_len);
+  CHECK(!callback.is_null());
+
+  // If we have data buffered, complete the IO immediately.
+  if (!response_body_.empty()) {
+    int bytes_read = 0;
+    while (!response_body_.empty() && buf_len > 0) {
+      scoped_refptr<IOBufferWithSize> data = response_body_.front();
+      const int bytes_to_copy = std::min(buf_len, data->size());
+      memcpy(&(buf->data()[bytes_read]), data->data(), bytes_to_copy);
+      buf_len -= bytes_to_copy;
+      if (bytes_to_copy == data->size()) {
+        response_body_.pop_front();
+      } else {
+        const int bytes_remaining = data->size() - bytes_to_copy;
+        IOBufferWithSize* new_buffer = new IOBufferWithSize(bytes_remaining);
+        memcpy(new_buffer->data(), &(data->data()[bytes_to_copy]),
+               bytes_remaining);
+        response_body_.pop_front();
+        response_body_.push_front(make_scoped_refptr(new_buffer));
+      }
+      bytes_read += bytes_to_copy;
+    }
+    stream_->IncreaseRecvWindowSize(bytes_read);
+    return bytes_read;
+  } else if (stream_->closed()) {
+    return stream_->response_status();
+  }
+
+  CHECK(callback_.is_null());
+  CHECK(!user_buffer_);
+  CHECK_EQ(0, user_buffer_len_);
+
+  callback_ = callback;
+  user_buffer_ = buf;
+  user_buffer_len_ = buf_len;
+  return ERR_IO_PENDING;
+}
+
+void SpdyHttpStream::Close(bool not_reusable) {
+  // Note: the not_reusable flag has no meaning for SPDY streams.
+
+  Cancel();
+}
+
+HttpStream* SpdyHttpStream::RenewStreamForAuth() {
+  return NULL;
+}
+
+bool SpdyHttpStream::IsResponseBodyComplete() const {
+  if (!stream_)
+    return false;
+  return stream_->closed();
+}
+
+bool SpdyHttpStream::CanFindEndOfResponse() const {
+  return true;
+}
+
+bool SpdyHttpStream::IsMoreDataBuffered() const {
+  return false;
+}
+
+bool SpdyHttpStream::IsConnectionReused() const {
+  return spdy_session_->IsReused();
+}
+
+void SpdyHttpStream::SetConnectionReused() {
+  // SPDY doesn't need an indicator here.
+}
+
+bool SpdyHttpStream::IsConnectionReusable() const {
+  // SPDY streams aren't considered reusable.
+  return false;
+}
+
+int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
+                                HttpResponseInfo* response,
+                                const CompletionCallback& callback) {
+  base::Time request_time = base::Time::Now();
+  CHECK(stream_.get());
+
+  stream_->SetDelegate(this);
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
+                                   headers.get(), stream_->GetProtocolVersion(),
+                                   direct_);
+  stream_->net_log().AddEvent(
+      NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS,
+      base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get()));
+  stream_->set_spdy_headers(headers.Pass());
+
+  stream_->SetRequestTime(request_time);
+  // This should only get called in the case of a request occurring
+  // during server push that has already begun but hasn't finished,
+  // so we set the response's request time to be the actual one
+  if (response_info_)
+    response_info_->request_time = request_time;
+
+  CHECK(!has_upload_data_);
+  has_upload_data_ = request_info_->upload_data_stream &&
+      (request_info_->upload_data_stream->size() ||
+       request_info_->upload_data_stream->is_chunked());
+  if (has_upload_data_) {
+    // Use kMaxSpdyFrameChunkSize as the buffer size, since the request
+    // body data is written with this size at a time.
+    raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize);
+    // The request body buffer is empty at first.
+    request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, 0);
+  }
+
+  CHECK(!callback.is_null());
+  CHECK(!stream_->cancelled());
+  CHECK(response);
+
+  if (!stream_->pushed() && stream_->closed()) {
+    if (stream_->response_status() == OK)
+      return ERR_FAILED;
+    else
+      return stream_->response_status();
+  }
+
+  // SendRequest can be called in two cases.
+  //
+  // a) A client initiated request. In this case, |response_info_| should be
+  //    NULL to start with.
+  // b) A client request which matches a response that the server has already
+  //    pushed.
+  if (push_response_info_.get()) {
+    *response = *(push_response_info_.get());
+    push_response_info_.reset();
+  } else {
+    DCHECK_EQ(static_cast<HttpResponseInfo*>(NULL), response_info_);
+  }
+
+  response_info_ = response;
+
+  // Put the peer's IP address and port into the response.
+  IPEndPoint address;
+  int result = stream_->GetPeerAddress(&address);
+  if (result != OK)
+    return result;
+  response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
+
+  result = stream_->SendRequest(has_upload_data_);
+  if (result == ERR_IO_PENDING) {
+    CHECK(callback_.is_null());
+    callback_ = callback;
+  }
+  return result;
+}
+
+void SpdyHttpStream::Cancel() {
+  if (spdy_session_)
+    spdy_session_->CancelPendingCreateStreams(&stream_);
+  callback_.Reset();
+  if (stream_)
+    stream_->Cancel();
+}
+
+int SpdyHttpStream::SendData() {
+  CHECK(request_info_ && request_info_->upload_data_stream);
+  CHECK_EQ(0, request_body_buf_->BytesRemaining());
+
+  // Read the data from the request body stream.
+  const int bytes_read = request_info_->upload_data_stream->Read(
+      raw_request_body_buf_, raw_request_body_buf_->size(),
+      base::Bind(
+          base::IgnoreResult(&SpdyHttpStream::OnRequestBodyReadCompleted),
+          weak_factory_.GetWeakPtr()));
+
+  if (bytes_read == ERR_IO_PENDING)
+    return ERR_IO_PENDING;
+  // ERR_IO_PENDING is the only possible error.
+  DCHECK_GE(bytes_read, 0);
+  return OnRequestBodyReadCompleted(bytes_read);
+}
+
+bool SpdyHttpStream::OnSendHeadersComplete(int status) {
+  if (!callback_.is_null())
+    DoCallback(status);
+  return !has_upload_data_;
+}
+
+int SpdyHttpStream::OnSendBody() {
+  CHECK(request_info_ && request_info_->upload_data_stream);
+  const bool eof = request_info_->upload_data_stream->IsEOF();
+  if (request_body_buf_->BytesRemaining() > 0) {
+    return stream_->WriteStreamData(
+        request_body_buf_,
+        request_body_buf_->BytesRemaining(),
+        eof ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+  }
+
+  // The entire body data has been sent.
+  if (eof)
+    return OK;
+
+  return SendData();
+}
+
+int SpdyHttpStream::OnSendBodyComplete(int status, bool* eof) {
+  // |status| is the number of bytes written to the SPDY stream.
+  CHECK(request_info_ && request_info_->upload_data_stream);
+  *eof = false;
+
+  if (status > 0) {
+    request_body_buf_->DidConsume(status);
+    if (request_body_buf_->BytesRemaining()) {
+      // Go back to OnSendBody() to send the remaining data.
+      return OK;
+    }
+  }
+
+  // Check if the entire body data has been sent.
+  *eof = (request_info_->upload_data_stream->IsEOF() &&
+          !request_body_buf_->BytesRemaining());
+  return OK;
+}
+
+int SpdyHttpStream::OnResponseReceived(const SpdyHeaderBlock& response,
+                                       base::Time response_time,
+                                       int status) {
+  if (!response_info_) {
+    DCHECK(stream_->pushed());
+    push_response_info_.reset(new HttpResponseInfo);
+    response_info_ = push_response_info_.get();
+  }
+
+  // If the response is already received, these headers are too late.
+  if (response_headers_received_) {
+    LOG(WARNING) << "SpdyHttpStream headers received after response started.";
+    return OK;
+  }
+
+  // TODO(mbelshe): This is the time of all headers received, not just time
+  // to first byte.
+  response_info_->response_time = base::Time::Now();
+
+  if (!SpdyHeadersToHttpResponse(response, stream_->GetProtocolVersion(),
+                                 response_info_)) {
+    // We might not have complete headers yet.
+    return ERR_INCOMPLETE_SPDY_HEADERS;
+  }
+
+  response_headers_received_ = true;
+  // Don't store the SSLInfo in the response here, HttpNetworkTransaction
+  // will take care of that part.
+  SSLInfo ssl_info;
+  NextProto protocol_negotiated = kProtoUnknown;
+  stream_->GetSSLInfo(&ssl_info,
+                      &response_info_->was_npn_negotiated,
+                      &protocol_negotiated);
+  response_info_->npn_negotiated_protocol =
+      SSLClientSocket::NextProtoToString(protocol_negotiated);
+  response_info_->request_time = stream_->GetRequestTime();
+  response_info_->vary_data.Init(*request_info_, *response_info_->headers);
+  // TODO(ahendrickson): This is recorded after the entire SYN_STREAM control
+  // frame has been received and processed.  Move to framer?
+  response_info_->response_time = response_time;
+
+  if (!callback_.is_null())
+    DoCallback(status);
+
+  return status;
+}
+
+void SpdyHttpStream::OnHeadersSent() {
+  // For HTTP streams, no HEADERS frame is sent from the client.
+  NOTREACHED();
+}
+
+int SpdyHttpStream::OnDataReceived(const char* data, int length) {
+  // SpdyStream won't call us with data if the header block didn't contain a
+  // valid set of headers.  So we don't expect to not have headers received
+  // here.
+  if (!response_headers_received_)
+    return ERR_INCOMPLETE_SPDY_HEADERS;
+
+  // Note that data may be received for a SpdyStream prior to the user calling
+  // ReadResponseBody(), therefore user_buffer_ may be NULL.  This may often
+  // happen for server initiated streams.
+  DCHECK(!stream_->closed() || stream_->pushed());
+  if (length > 0) {
+    // Save the received data.
+    IOBufferWithSize* io_buffer = new IOBufferWithSize(length);
+    memcpy(io_buffer->data(), data, length);
+    response_body_.push_back(make_scoped_refptr(io_buffer));
+
+    if (user_buffer_) {
+      // Handing small chunks of data to the caller creates measurable overhead.
+      // We buffer data in short time-spans and send a single read notification.
+      ScheduleBufferedReadCallback();
+    }
+  }
+  return OK;
+}
+
+void SpdyHttpStream::OnDataSent(int length) {
+  // For HTTP streams, no data is sent from the client while in the OPEN state,
+  // so it is never called.
+  NOTREACHED();
+}
+
+void SpdyHttpStream::OnClose(int status) {
+  bool invoked_callback = false;
+  if (status == net::OK) {
+    // We need to complete any pending buffered read now.
+    invoked_callback = DoBufferedReadCallback();
+  }
+  if (!invoked_callback && !callback_.is_null())
+    DoCallback(status);
+}
+
+void SpdyHttpStream::ScheduleBufferedReadCallback() {
+  // If there is already a scheduled DoBufferedReadCallback, don't issue
+  // another one.  Mark that we have received more data and return.
+  if (buffered_read_callback_pending_) {
+    more_read_data_pending_ = true;
+    return;
+  }
+
+  more_read_data_pending_ = false;
+  buffered_read_callback_pending_ = true;
+  const base::TimeDelta kBufferTime = base::TimeDelta::FromMilliseconds(1);
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(base::IgnoreResult(&SpdyHttpStream::DoBufferedReadCallback),
+                 weak_factory_.GetWeakPtr()),
+      kBufferTime);
+}
+
+// Checks to see if we should wait for more buffered data before notifying
+// the caller.  Returns true if we should wait, false otherwise.
+bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const {
+  // If the response is complete, there is no point in waiting.
+  if (stream_->closed())
+    return false;
+
+  int bytes_buffered = 0;
+  std::list<scoped_refptr<IOBufferWithSize> >::const_iterator it;
+  for (it = response_body_.begin();
+       it != response_body_.end() && bytes_buffered < user_buffer_len_;
+       ++it)
+    bytes_buffered += (*it)->size();
+
+  return bytes_buffered < user_buffer_len_;
+}
+
+bool SpdyHttpStream::DoBufferedReadCallback() {
+  weak_factory_.InvalidateWeakPtrs();
+  buffered_read_callback_pending_ = false;
+
+  // If the transaction is cancelled or errored out, we don't need to complete
+  // the read.
+  if (!stream_ || stream_->response_status() != OK || stream_->cancelled())
+    return false;
+
+  // When more_read_data_pending_ is true, it means that more data has
+  // arrived since we started waiting.  Wait a little longer and continue
+  // to buffer.
+  if (more_read_data_pending_ && ShouldWaitForMoreBufferedData()) {
+    ScheduleBufferedReadCallback();
+    return false;
+  }
+
+  int rv = 0;
+  if (user_buffer_) {
+    rv = ReadResponseBody(user_buffer_, user_buffer_len_, callback_);
+    CHECK_NE(rv, ERR_IO_PENDING);
+    user_buffer_ = NULL;
+    user_buffer_len_ = 0;
+    DoCallback(rv);
+    return true;
+  }
+  return false;
+}
+
+void SpdyHttpStream::DoCallback(int rv) {
+  CHECK_NE(rv, ERR_IO_PENDING);
+  CHECK(!callback_.is_null());
+
+  // Since Run may result in being called back, clear user_callback_ in advance.
+  CompletionCallback c = callback_;
+  callback_.Reset();
+  c.Run(rv);
+}
+
+int SpdyHttpStream::OnRequestBodyReadCompleted(int status) {
+  DCHECK_GE(status, 0);
+
+  request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, status);
+
+  const bool eof = request_info_->upload_data_stream->IsEOF();
+  return stream_->WriteStreamData(request_body_buf_,
+                                  request_body_buf_->BytesRemaining(),
+                                  eof ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) {
+  DCHECK(stream_);
+  bool using_npn;
+  NextProto protocol_negotiated = kProtoUnknown;
+  stream_->GetSSLInfo(ssl_info, &using_npn, &protocol_negotiated);
+}
+
+void SpdyHttpStream::GetSSLCertRequestInfo(
+    SSLCertRequestInfo* cert_request_info) {
+  DCHECK(stream_);
+  stream_->GetSSLCertRequestInfo(cert_request_info);
+}
+
+bool SpdyHttpStream::IsSpdyHttpStream() const {
+  return true;
+}
+
+void SpdyHttpStream::Drain(HttpNetworkSession* session) {
+  Close(false);
+  delete this;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_http_stream.h b/src/net/spdy/spdy_http_stream.h
new file mode 100644
index 0000000..ddd2ccb
--- /dev/null
+++ b/src/net/spdy/spdy_http_stream.h
@@ -0,0 +1,146 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_HTTP_STREAM_H_
+#define NET_SPDY_SPDY_HTTP_STREAM_H_
+
+#include <list>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_log.h"
+#include "net/http/http_stream.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+class DrainableIOBuffer;
+struct HttpRequestInfo;
+class HttpResponseInfo;
+class IOBuffer;
+class SpdySession;
+class UploadDataStream;
+
+// The SpdyHttpStream is a HTTP-specific type of stream known to a SpdySession.
+class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
+                                          public HttpStream {
+ public:
+  SpdyHttpStream(SpdySession* spdy_session, bool direct);
+  virtual ~SpdyHttpStream();
+
+  // Initializes this SpdyHttpStream by wrapping an existing SpdyStream.
+  void InitializeWithExistingStream(SpdyStream* spdy_stream);
+
+  SpdyStream* stream() { return stream_.get(); }
+
+  // Cancels any callbacks from being invoked and deletes the stream.
+  void Cancel();
+
+  // HttpStream implementation.
+  virtual int InitializeStream(const HttpRequestInfo* request_info,
+                               const BoundNetLog& net_log,
+                               const CompletionCallback& callback) OVERRIDE;
+  virtual int SendRequest(const HttpRequestHeaders& headers,
+                          HttpResponseInfo* response,
+                          const CompletionCallback& callback) OVERRIDE;
+  virtual UploadProgress GetUploadProgress() const OVERRIDE;
+  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE;
+  virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE;
+  virtual int ReadResponseBody(IOBuffer* buf,
+                               int buf_len,
+                               const CompletionCallback& callback) OVERRIDE;
+  virtual void Close(bool not_reusable) OVERRIDE;
+  virtual HttpStream* RenewStreamForAuth() OVERRIDE;
+  virtual bool IsResponseBodyComplete() const OVERRIDE;
+  virtual bool CanFindEndOfResponse() const OVERRIDE;
+  virtual bool IsMoreDataBuffered() const OVERRIDE;
+  virtual bool IsConnectionReused() const OVERRIDE;
+  virtual void SetConnectionReused() OVERRIDE;
+  virtual bool IsConnectionReusable() const OVERRIDE;
+  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
+  virtual void GetSSLCertRequestInfo(
+      SSLCertRequestInfo* cert_request_info) OVERRIDE;
+  virtual bool IsSpdyHttpStream() const OVERRIDE;
+  virtual void LogNumRttVsBytesMetrics() const OVERRIDE {}
+  virtual void Drain(HttpNetworkSession* session) OVERRIDE;
+
+  // SpdyStream::Delegate implementation.
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE;
+  virtual int OnSendBody() OVERRIDE;
+  virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE;
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE;
+  virtual void OnHeadersSent() OVERRIDE;
+  virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE;
+  virtual void OnDataSent(int length) OVERRIDE;
+  virtual void OnClose(int status) OVERRIDE;
+
+ private:
+  // Reads the data (whether chunked or not) from the request body stream and
+  // sends the data by calling WriteStreamData on the underlying SpdyStream.
+  int SendData();
+
+  // Call the user callback.
+  void DoCallback(int rv);
+
+  int OnRequestBodyReadCompleted(int status);
+
+  void ScheduleBufferedReadCallback();
+
+  // Returns true if the callback is invoked.
+  bool DoBufferedReadCallback();
+  bool ShouldWaitForMoreBufferedData() const;
+
+  base::WeakPtrFactory<SpdyHttpStream> weak_factory_;
+  scoped_refptr<SpdyStream> stream_;
+  scoped_refptr<SpdySession> spdy_session_;
+
+  // The request to send.
+  const HttpRequestInfo* request_info_;
+
+  bool has_upload_data_;
+
+  // |response_info_| is the HTTP response data object which is filled in
+  // when a SYN_REPLY comes in for the stream.
+  // It is not owned by this stream object, or point to |push_response_info_|.
+  HttpResponseInfo* response_info_;
+
+  scoped_ptr<HttpResponseInfo> push_response_info_;
+
+  bool download_finished_;
+  bool response_headers_received_;  // Indicates waiting for more HEADERS.
+
+  // We buffer the response body as it arrives asynchronously from the stream.
+  // TODO(mbelshe):  is this infinite buffering?
+  std::list<scoped_refptr<IOBufferWithSize> > response_body_;
+
+  CompletionCallback callback_;
+
+  // User provided buffer for the ReadResponseBody() response.
+  scoped_refptr<IOBuffer> user_buffer_;
+  int user_buffer_len_;
+
+  // Temporary buffer used to read the request body from UploadDataStream.
+  scoped_refptr<IOBufferWithSize> raw_request_body_buf_;
+  // Wraps raw_request_body_buf_ to read the remaining data progressively.
+  scoped_refptr<DrainableIOBuffer> request_body_buf_;
+
+  // Is there a scheduled read callback pending.
+  bool buffered_read_callback_pending_;
+  // Has more data been received from the network during the wait for the
+  // scheduled read callback.
+  bool more_read_data_pending_;
+
+  // Is this spdy stream direct to the origin server (or to a proxy).
+  bool direct_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyHttpStream);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_HTTP_STREAM_H_
diff --git a/src/net/spdy/spdy_http_stream_spdy2_unittest.cc b/src/net/spdy/spdy_http_stream_spdy2_unittest.cc
new file mode 100644
index 0000000..544f686
--- /dev/null
+++ b/src/net/spdy/spdy_http_stream_spdy2_unittest.cc
@@ -0,0 +1,375 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_http_stream.h"
+
+#include "crypto/ec_private_key.h"
+#include "crypto/ec_signature_creator.h"
+#include "crypto/signature_creator.h"
+#include "net/base/asn1_util.h"
+#include "net/base/default_server_bound_cert_store.h"
+#include "net/base/upload_data_stream.h"
+#include "net/base/upload_element_reader.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy2;
+
+namespace net {
+
+class SpdyHttpStreamSpdy2Test : public testing::Test {
+ public:
+  OrderedSocketData* data() { return data_.get(); }
+ protected:
+  SpdyHttpStreamSpdy2Test() {}
+
+  virtual void TearDown() {
+    crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
+    UploadDataStream::ResetMergeChunks();
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void set_merge_chunks(bool merge) {
+    UploadDataStream::set_merge_chunks(merge);
+  }
+
+  int InitSession(MockRead* reads, size_t reads_count,
+                  MockWrite* writes, size_t writes_count,
+                  HostPortPair& host_port_pair) {
+    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+    data_.reset(new OrderedSocketData(reads, reads_count,
+                                      writes, writes_count));
+    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
+    http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+    session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
+    transport_params_ = new TransportSocketParams(host_port_pair,
+                                                  MEDIUM, false, false,
+                                                  OnHostResolutionCallback());
+    TestCompletionCallback callback;
+    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+    EXPECT_EQ(ERR_IO_PENDING,
+              connection->Init(host_port_pair.ToString(),
+                               transport_params_,
+                               MEDIUM,
+                               callback.callback(),
+                               http_session_->GetTransportSocketPool(
+                                   HttpNetworkSession::NORMAL_SOCKET_POOL),
+                               BoundNetLog()));
+    EXPECT_EQ(OK, callback.WaitForResult());
+    return session_->InitializeWithSocket(connection.release(), false, OK);
+  }
+
+  SpdySessionDependencies session_deps_;
+  scoped_ptr<OrderedSocketData> data_;
+  scoped_refptr<HttpNetworkSession> http_session_;
+  scoped_refptr<SpdySession> session_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+};
+
+TEST_F(SpdyHttpStreamSpdy2Test, SendRequest) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 1),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(SYNCHRONOUS, 0, 3)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
+      host_port_pair));
+
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL("http://www.google.com/");
+  TestCompletionCallback callback;
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(
+      new SpdyHttpStream(session_.get(), true));
+  ASSERT_EQ(
+      OK,
+      http_stream->InitializeStream(&request, net_log, CompletionCallback()));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // This triggers the MockWrite and read 2
+  callback.WaitForResult();
+
+  // This triggers read 3. The empty read causes the session to shut down.
+  data()->CompleteRead();
+
+  // Because we abandoned the stream, we don't expect to find a session in the
+  // pool anymore.
+  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+TEST_F(SpdyHttpStreamSpdy2Test, SendChunkedPost) {
+  set_merge_chunks(false);
+
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0),
+    CreateMockWrite(*chunk1, 1),  // POST upload frames
+    CreateMockWrite(*chunk2, 2),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*chunk1, 4),
+    CreateMockRead(*chunk2, 5),
+    MockRead(SYNCHRONOUS, 0, 6)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
+                            host_port_pair));
+
+  UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, false);
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, true);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_stream;
+
+  ASSERT_EQ(OK, upload_stream.InitSync());
+
+  TestCompletionCallback callback;
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  SpdyHttpStream http_stream(session_.get(), true);
+  ASSERT_EQ(
+      OK,
+      http_stream.InitializeStream(&request, net_log, CompletionCallback()));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream.SendRequest(
+      headers, &response, callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // This triggers the MockWrite and read 2
+  callback.WaitForResult();
+
+  // This triggers read 3. The empty read causes the session to shut down.
+  data()->CompleteRead();
+  MessageLoop::current()->RunUntilIdle();
+
+  // Because we abandoned the stream, we don't expect to find a session in the
+  // pool anymore.
+  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+// Test to ensure the SpdyStream state machine does not get confused when a
+// chunk becomes available while a write is pending.
+TEST_F(SpdyHttpStreamSpdy2Test, DelayedSendChunkedPost) {
+  set_merge_chunks(false);
+
+  const char kUploadData1[] = "12345678";
+  const int kUploadData1Size = arraysize(kUploadData1)-1;
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> chunk2(
+      ConstructSpdyBodyFrame(1, kUploadData1, kUploadData1Size, false));
+  scoped_ptr<SpdyFrame> chunk3(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0),
+    CreateMockWrite(*chunk1, 1),  // POST upload frames
+    CreateMockWrite(*chunk2, 2),
+    CreateMockWrite(*chunk3, 3),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 4),
+    CreateMockRead(*chunk1, 5),
+    CreateMockRead(*chunk2, 6),
+    CreateMockRead(*chunk3, 7),
+    MockRead(ASYNC, 0, 8)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  DeterministicMockClientSocketFactory* socket_factory =
+      session_deps_.deterministic_socket_factory.get();
+  socket_factory->AddSocketDataProvider(&data);
+
+  http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+      &session_deps_);
+  session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
+  transport_params_ = new TransportSocketParams(host_port_pair,
+                                                MEDIUM, false, false,
+                                                OnHostResolutionCallback());
+
+  TestCompletionCallback callback;
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+
+  EXPECT_EQ(ERR_IO_PENDING,
+            connection->Init(host_port_pair.ToString(),
+                             transport_params_,
+                             MEDIUM,
+                             callback.callback(),
+                             http_session_->GetTransportSocketPool(
+                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
+                             BoundNetLog()));
+
+  callback.WaitForResult();
+  EXPECT_EQ(OK,
+            session_->InitializeWithSocket(connection.release(), false, OK));
+
+  UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_stream;
+
+  ASSERT_EQ(OK, upload_stream.InitSync());
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, false);
+
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(
+      new SpdyHttpStream(session_.get(), true));
+  ASSERT_EQ(OK, http_stream->InitializeStream(&request,
+                                              net_log,
+                                              CompletionCallback()));
+
+  HttpRequestHeaders headers;
+  HttpResponseInfo response;
+  // This will attempt to Write() the initial request and headers, which will
+  // complete asynchronously.
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // Complete the initial request write and the first chunk.
+  data.RunFor(2);
+  ASSERT_TRUE(callback.have_result());
+  EXPECT_GT(callback.WaitForResult(), 0);
+
+  // Now append the final two chunks which will enqueue two more writes.
+  upload_stream.AppendChunk(kUploadData1, kUploadData1Size, false);
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, true);
+
+  // Finish writing all the chunks.
+  data.RunFor(2);
+
+  // Read response headers.
+  data.RunFor(1);
+  ASSERT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback()));
+
+  // Read and check |chunk1| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize));
+  ASSERT_EQ(kUploadDataSize,
+            http_stream->ReadResponseBody(buf1,
+                                          kUploadDataSize,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize));
+
+  // Read and check |chunk2| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf2(new IOBuffer(kUploadData1Size));
+  ASSERT_EQ(kUploadData1Size,
+            http_stream->ReadResponseBody(buf2,
+                                          kUploadData1Size,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData1, std::string(buf2->data(), kUploadData1Size));
+
+  // Read and check |chunk3| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf3(new IOBuffer(kUploadDataSize));
+  ASSERT_EQ(kUploadDataSize,
+            http_stream->ReadResponseBody(buf3,
+                                          kUploadDataSize,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData, std::string(buf3->data(), kUploadDataSize));
+
+  // Finish reading the |EOF|.
+  data.RunFor(1);
+  ASSERT_TRUE(response.headers.get());
+  ASSERT_EQ(200, response.headers->response_code());
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+// Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
+TEST_F(SpdyHttpStreamSpdy2Test, SpdyURLTest) {
+  const char * const full_url = "http://www.google.com/foo?query=what#anchor";
+  const char * const base_url = "http://www.google.com/foo?query=what";
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(base_url, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 1),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(SYNCHRONOUS, 0, 3)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
+      host_port_pair));
+
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL(full_url);
+  TestCompletionCallback callback;
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true));
+  ASSERT_EQ(
+      OK,
+      http_stream->InitializeStream(&request, net_log, CompletionCallback()));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+
+  const SpdyHeaderBlock& spdy_header =
+    http_stream->stream()->spdy_headers();
+  if (spdy_header.find("url") != spdy_header.end())
+    EXPECT_EQ("/foo?query=what", spdy_header.find("url")->second);
+  else
+    FAIL() << "No url is set in spdy_header!";
+
+  // This triggers the MockWrite and read 2
+  callback.WaitForResult();
+
+  // This triggers read 3. The empty read causes the session to shut down.
+  data()->CompleteRead();
+
+  // Because we abandoned the stream, we don't expect to find a session in the
+  // pool anymore.
+  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+// TODO(willchan): Write a longer test for SpdyStream that exercises all
+// methods.
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_http_stream_spdy3_unittest.cc b/src/net/spdy/spdy_http_stream_spdy3_unittest.cc
new file mode 100644
index 0000000..70c406d
--- /dev/null
+++ b/src/net/spdy/spdy_http_stream_spdy3_unittest.cc
@@ -0,0 +1,729 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_http_stream.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "crypto/ec_private_key.h"
+#include "crypto/ec_signature_creator.h"
+#include "crypto/signature_creator.h"
+#include "net/base/asn1_util.h"
+#include "net/base/default_server_bound_cert_store.h"
+#include "net/base/upload_data_stream.h"
+#include "net/base/upload_element_reader.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
+#include "net/spdy/spdy_credential_builder.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy3;
+
+namespace net {
+
+class SpdyHttpStreamSpdy3Test : public testing::Test {
+ public:
+  OrderedSocketData* data() { return data_.get(); }
+
+ protected:
+  virtual void TearDown() {
+    UploadDataStream::ResetMergeChunks();
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void set_merge_chunks(bool merge) {
+    UploadDataStream::set_merge_chunks(merge);
+  }
+
+  int InitSession(MockRead* reads, size_t reads_count,
+                  MockWrite* writes, size_t writes_count,
+                  HostPortPair& host_port_pair) {
+    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+    data_.reset(new OrderedSocketData(reads, reads_count,
+                                      writes, writes_count));
+    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
+    http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+    session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
+    transport_params_ = new TransportSocketParams(host_port_pair,
+                                                  MEDIUM, false, false,
+                                                  OnHostResolutionCallback());
+    TestCompletionCallback callback;
+    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+    EXPECT_EQ(ERR_IO_PENDING,
+              connection->Init(host_port_pair.ToString(),
+                               transport_params_,
+                               MEDIUM,
+                               callback.callback(),
+                               http_session_->GetTransportSocketPool(
+                                   HttpNetworkSession::NORMAL_SOCKET_POOL),
+                               BoundNetLog()));
+    EXPECT_EQ(OK, callback.WaitForResult());
+    return session_->InitializeWithSocket(connection.release(), false, OK);
+  }
+
+  void TestSendCredentials(
+    ServerBoundCertService* server_bound_cert_service,
+    const std::string& cert,
+    const std::string& proof);
+
+  SpdySessionDependencies session_deps_;
+  scoped_ptr<OrderedSocketData> data_;
+  scoped_refptr<HttpNetworkSession> http_session_;
+  scoped_refptr<SpdySession> session_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+
+ private:
+  MockECSignatureCreatorFactory ec_signature_creator_factory_;
+};
+
+TEST_F(SpdyHttpStreamSpdy3Test, SendRequest) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 1),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(SYNCHRONOUS, 0, 3)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
+      host_port_pair));
+
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL("http://www.google.com/");
+  TestCompletionCallback callback;
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(
+      new SpdyHttpStream(session_.get(), true));
+  ASSERT_EQ(
+      OK,
+      http_stream->InitializeStream(&request, net_log, CompletionCallback()));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // This triggers the MockWrite and read 2
+  callback.WaitForResult();
+
+  // This triggers read 3. The empty read causes the session to shut down.
+  data()->CompleteRead();
+
+  // Because we abandoned the stream, we don't expect to find a session in the
+  // pool anymore.
+  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+TEST_F(SpdyHttpStreamSpdy3Test, SendChunkedPost) {
+  set_merge_chunks(false);
+
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0),
+    CreateMockWrite(*chunk1, 1),  // POST upload frames
+    CreateMockWrite(*chunk2, 2),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*chunk1, 4),
+    CreateMockRead(*chunk2, 5),
+    MockRead(SYNCHRONOUS, 0, 6)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
+                            host_port_pair));
+
+  UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, false);
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, true);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_stream;
+
+  ASSERT_EQ(OK, upload_stream.InitSync());
+
+  TestCompletionCallback callback;
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  SpdyHttpStream http_stream(session_.get(), true);
+  ASSERT_EQ(
+      OK,
+      http_stream.InitializeStream(&request, net_log, CompletionCallback()));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream.SendRequest(
+      headers, &response, callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // This triggers the MockWrite and read 2
+  callback.WaitForResult();
+
+  // This triggers read 3. The empty read causes the session to shut down.
+  data()->CompleteRead();
+  MessageLoop::current()->RunUntilIdle();
+
+  // Because we abandoned the stream, we don't expect to find a session in the
+  // pool anymore.
+  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+// Test to ensure the SpdyStream state machine does not get confused when a
+// chunk becomes available while a write is pending.
+TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPost) {
+  set_merge_chunks(false);
+
+  const char kUploadData1[] = "12345678";
+  const int kUploadData1Size = arraysize(kUploadData1)-1;
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> chunk2(
+      ConstructSpdyBodyFrame(1, kUploadData1, kUploadData1Size, false));
+  scoped_ptr<SpdyFrame> chunk3(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0),
+    CreateMockWrite(*chunk1, 1),  // POST upload frames
+    CreateMockWrite(*chunk2, 2),
+    CreateMockWrite(*chunk3, 3),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 4),
+    CreateMockRead(*chunk1, 5),
+    CreateMockRead(*chunk2, 6),
+    CreateMockRead(*chunk3, 7),
+    MockRead(ASYNC, 0, 8)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  DeterministicMockClientSocketFactory* socket_factory =
+      session_deps_.deterministic_socket_factory.get();
+  socket_factory->AddSocketDataProvider(&data);
+
+  http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+      &session_deps_);
+  session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
+  transport_params_ = new TransportSocketParams(host_port_pair,
+                                                MEDIUM, false, false,
+                                                OnHostResolutionCallback());
+
+  TestCompletionCallback callback;
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+
+  EXPECT_EQ(ERR_IO_PENDING,
+            connection->Init(host_port_pair.ToString(),
+                             transport_params_,
+                             MEDIUM,
+                             callback.callback(),
+                             http_session_->GetTransportSocketPool(
+                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
+                             BoundNetLog()));
+
+  callback.WaitForResult();
+  EXPECT_EQ(OK,
+            session_->InitializeWithSocket(connection.release(), false, OK));
+
+  UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_stream;
+
+  ASSERT_EQ(OK, upload_stream.InitSync());
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, false);
+
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(
+      new SpdyHttpStream(session_.get(), true));
+  ASSERT_EQ(OK, http_stream->InitializeStream(&request,
+                                              net_log,
+                                              CompletionCallback()));
+
+  HttpRequestHeaders headers;
+  HttpResponseInfo response;
+  // This will attempt to Write() the initial request and headers, which will
+  // complete asynchronously.
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // Complete the initial request write and the first chunk.
+  data.RunFor(2);
+  ASSERT_TRUE(callback.have_result());
+  EXPECT_GT(callback.WaitForResult(), 0);
+
+  // Now append the final two chunks which will enqueue two more writes.
+  upload_stream.AppendChunk(kUploadData1, kUploadData1Size, false);
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, true);
+
+  // Finish writing all the chunks.
+  data.RunFor(2);
+
+  // Read response headers.
+  data.RunFor(1);
+  ASSERT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback()));
+
+  // Read and check |chunk1| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize));
+  ASSERT_EQ(kUploadDataSize,
+            http_stream->ReadResponseBody(buf1,
+                                          kUploadDataSize,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize));
+
+  // Read and check |chunk2| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf2(new IOBuffer(kUploadData1Size));
+  ASSERT_EQ(kUploadData1Size,
+            http_stream->ReadResponseBody(buf2,
+                                          kUploadData1Size,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData1, std::string(buf2->data(), kUploadData1Size));
+
+  // Read and check |chunk3| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf3(new IOBuffer(kUploadDataSize));
+  ASSERT_EQ(kUploadDataSize,
+            http_stream->ReadResponseBody(buf3,
+                                          kUploadDataSize,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData, std::string(buf3->data(), kUploadDataSize));
+
+  // Finish reading the |EOF|.
+  data.RunFor(1);
+  ASSERT_TRUE(response.headers.get());
+  ASSERT_EQ(200, response.headers->response_code());
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+// Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be
+// made available is handled correctly.
+TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPostWithWindowUpdate) {
+  set_merge_chunks(false);
+
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0),
+    CreateMockWrite(*chunk1, 1),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> window_update(
+      ConstructSpdyWindowUpdate(1, kUploadDataSize));
+  MockRead reads[] = {
+    CreateMockRead(*window_update, 2),
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*chunk1, 4),
+    MockRead(ASYNC, 0, 5)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  DeterministicMockClientSocketFactory* socket_factory =
+      session_deps_.deterministic_socket_factory.get();
+  socket_factory->AddSocketDataProvider(&data);
+
+  http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+      &session_deps_);
+  session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
+  transport_params_ = new TransportSocketParams(host_port_pair,
+                                                MEDIUM, false, false,
+                                                OnHostResolutionCallback());
+
+  TestCompletionCallback callback;
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+
+  EXPECT_EQ(ERR_IO_PENDING,
+            connection->Init(host_port_pair.ToString(),
+                             transport_params_,
+                             MEDIUM,
+                             callback.callback(),
+                             http_session_->GetTransportSocketPool(
+                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
+                             BoundNetLog()));
+
+  callback.WaitForResult();
+  EXPECT_EQ(OK,
+            session_->InitializeWithSocket(connection.release(), false, OK));
+
+  UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_stream;
+
+  ASSERT_EQ(OK, upload_stream.InitSync());
+  upload_stream.AppendChunk(kUploadData, kUploadDataSize, true);
+
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(
+      new SpdyHttpStream(session_.get(), true));
+  ASSERT_EQ(OK, http_stream->InitializeStream(&request, net_log,
+                                              CompletionCallback()));
+
+  HttpRequestHeaders headers;
+  HttpResponseInfo response;
+  // This will attempt to Write() the initial request and headers, which will
+  // complete asynchronously.
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  // Complete the initial request write and first chunk.
+  data.RunFor(2);
+  ASSERT_TRUE(callback.have_result());
+  EXPECT_GT(callback.WaitForResult(), 0);
+
+  // Verify that the window size has decreased.
+  ASSERT_TRUE(http_stream->stream() != NULL);
+  EXPECT_NE(static_cast<int>(kSpdyStreamInitialWindowSize),
+            http_stream->stream()->send_window_size());
+
+  // Read window update.
+  data.RunFor(1);
+
+  // Verify the window update.
+  ASSERT_TRUE(http_stream->stream() != NULL);
+  EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize),
+            http_stream->stream()->send_window_size());
+
+  // Read response headers.
+  data.RunFor(1);
+  ASSERT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback()));
+
+  // Read and check |chunk1| response.
+  data.RunFor(1);
+  scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize));
+  ASSERT_EQ(kUploadDataSize,
+            http_stream->ReadResponseBody(buf1,
+                                          kUploadDataSize,
+                                          callback.callback()));
+  EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize));
+
+  // Finish reading the |EOF|.
+  data.RunFor(1);
+  ASSERT_TRUE(response.headers.get());
+  ASSERT_EQ(200, response.headers->response_code());
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+// Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
+TEST_F(SpdyHttpStreamSpdy3Test, SpdyURLTest) {
+  const char * const full_url = "http://www.google.com/foo?query=what#anchor";
+  const char * const base_url = "http://www.google.com/foo?query=what";
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(base_url, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 1),
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(SYNCHRONOUS, 0, 3)  // EOF
+  };
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
+      host_port_pair));
+
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL(full_url);
+  TestCompletionCallback callback;
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true));
+  ASSERT_EQ(
+      OK,
+      http_stream->InitializeStream(&request, net_log, CompletionCallback()));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+
+  const SpdyHeaderBlock& spdy_header =
+    http_stream->stream()->spdy_headers();
+  if (spdy_header.find(":path") != spdy_header.end())
+    EXPECT_EQ("/foo?query=what", spdy_header.find(":path")->second);
+  else
+    FAIL() << "No url is set in spdy_header!";
+
+  // This triggers the MockWrite and read 2
+  callback.WaitForResult();
+
+  // This triggers read 3. The empty read causes the session to shut down.
+  data()->CompleteRead();
+
+  // Because we abandoned the stream, we don't expect to find a session in the
+  // pool anymore.
+  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+namespace {
+
+void GetECServerBoundCertAndProof(
+    const std::string& origin,
+    ServerBoundCertService* server_bound_cert_service,
+    std::string* cert,
+    std::string* proof) {
+  TestCompletionCallback callback;
+  std::vector<uint8> requested_cert_types;
+  requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN);
+  SSLClientCertType cert_type;
+  std::string key;
+  ServerBoundCertService::RequestHandle request_handle;
+  int rv = server_bound_cert_service->GetDomainBoundCert(
+      origin, requested_cert_types, &cert_type, &key, cert, callback.callback(),
+      &request_handle);
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  EXPECT_EQ(OK, callback.WaitForResult());
+  EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type);
+
+  SpdyCredential credential;
+  SpdyCredentialBuilder::Build(MockClientSocket::kTlsUnique, cert_type, key,
+                               *cert, 2, &credential);
+
+  cert->assign(credential.certs[0]);
+  proof->assign(credential.proof);
+}
+
+}  // namespace
+
+// Constructs a standard SPDY SYN_STREAM frame for a GET request with
+// a credential set.
+SpdyFrame* ConstructCredentialRequestFrame(int slot, const GURL& url,
+                                           int stream_id) {
+  const SpdyHeaderInfo syn_headers = {
+    SYN_STREAM,
+    stream_id,
+    0,
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
+    slot,
+    CONTROL_FLAG_FIN,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+
+  // TODO(rch): this is ugly.  Clean up.
+  std::string str_path = url.PathForRequest();
+  std::string str_scheme = url.scheme();
+  std::string str_host = url.host();
+  if (url.has_port()) {
+    str_host += ":";
+    str_host += url.port();
+  }
+  scoped_array<char> req(new char[str_path.size() + 1]);
+  scoped_array<char> scheme(new char[str_scheme.size() + 1]);
+  scoped_array<char> host(new char[str_host.size() + 1]);
+  memcpy(req.get(), str_path.c_str(), str_path.size());
+  memcpy(scheme.get(), str_scheme.c_str(), str_scheme.size());
+  memcpy(host.get(), str_host.c_str(), str_host.size());
+  req.get()[str_path.size()] = '\0';
+  scheme.get()[str_scheme.size()] = '\0';
+  host.get()[str_host.size()] = '\0';
+
+  const char* const headers[] = {
+    ":method",
+    "GET",
+    ":path",
+    req.get(),
+    ":host",
+    host.get(),
+    ":scheme",
+    scheme.get(),
+    ":version",
+    "HTTP/1.1"
+  };
+  return ConstructSpdyPacket(
+      syn_headers, NULL, 0, headers, arraysize(headers)/2);
+}
+
+// TODO(rch): When openssl supports server bound certifictes, this
+// guard can be removed
+#if !defined(USE_OPENSSL)
+// Test that if we request a resource for a new origin on a session that
+// used domain bound certificates, that we send a CREDENTIAL frame for
+// the new domain before we send the new request.
+void SpdyHttpStreamSpdy3Test::TestSendCredentials(
+    ServerBoundCertService* server_bound_cert_service,
+    const std::string& cert,
+    const std::string& proof) {
+  const char* kUrl1 = "https://www.google.com/";
+  const char* kUrl2 = "https://www.gmail.com/";
+
+  SpdyCredential cred;
+  cred.slot = 2;
+  cred.proof = proof;
+  cred.certs.push_back(cert);
+
+  scoped_ptr<SpdyFrame> req(ConstructCredentialRequestFrame(
+      1, GURL(kUrl1), 1));
+  scoped_ptr<SpdyFrame> credential(ConstructSpdyCredential(cred));
+  scoped_ptr<SpdyFrame> req2(ConstructCredentialRequestFrame(
+      2, GURL(kUrl2), 3));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0),
+    CreateMockWrite(*credential.get(), 2),
+    CreateMockWrite(*req2.get(), 3),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*resp2, 4),
+    MockRead(SYNCHRONOUS, 0, 5)  // EOF
+  };
+
+  HostPortPair host_port_pair(HostPortPair::FromURL(GURL(kUrl1)));
+  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+
+  DeterministicMockClientSocketFactory* socket_factory =
+      session_deps_.deterministic_socket_factory.get();
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  socket_factory->AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.channel_id_sent = true;
+  ssl.server_bound_cert_service = server_bound_cert_service;
+  ssl.protocol_negotiated = kProtoSPDY3;
+  socket_factory->AddSSLSocketDataProvider(&ssl);
+  http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+      &session_deps_);
+  session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
+  transport_params_ = new TransportSocketParams(host_port_pair,
+                                                MEDIUM, false, false,
+                                                OnHostResolutionCallback());
+  TestCompletionCallback callback;
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  SSLConfig ssl_config;
+  scoped_refptr<SOCKSSocketParams> socks_params;
+  scoped_refptr<HttpProxySocketParams> http_proxy_params;
+  scoped_refptr<SSLSocketParams> ssl_params(
+      new SSLSocketParams(transport_params_,
+                          socks_params,
+                          http_proxy_params,
+                          ProxyServer::SCHEME_DIRECT,
+                          host_port_pair,
+                          ssl_config,
+                          0,
+                          false,
+                          false));
+  EXPECT_EQ(ERR_IO_PENDING,
+            connection->Init(host_port_pair.ToString(),
+                             ssl_params,
+                             MEDIUM,
+                             callback.callback(),
+                             http_session_->GetSSLSocketPool(
+                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
+                             BoundNetLog()));
+  callback.WaitForResult();
+  EXPECT_EQ(OK,
+            session_->InitializeWithSocket(connection.release(), true, OK));
+
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL(kUrl1);
+  HttpResponseInfo response;
+  HttpRequestHeaders headers;
+  BoundNetLog net_log;
+  scoped_ptr<SpdyHttpStream> http_stream(
+      new SpdyHttpStream(session_.get(), true));
+  ASSERT_EQ(
+      OK,
+      http_stream->InitializeStream(&request, net_log, CompletionCallback()));
+
+  //  EXPECT_FALSE(session_->NeedsCredentials(request.url));
+  //  GURL new_origin(kUrl2);
+  //  EXPECT_TRUE(session_->NeedsCredentials(new_origin));
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
+                                                     callback.callback()));
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
+
+  data.RunFor(2);
+  callback.WaitForResult();
+
+  // Start up second request for resource on a new origin.
+  scoped_ptr<SpdyHttpStream> http_stream2(
+      new SpdyHttpStream(session_.get(), true));
+  request.url = GURL(kUrl2);
+  ASSERT_EQ(
+      OK,
+      http_stream2->InitializeStream(&request, net_log, CompletionCallback()));
+  EXPECT_EQ(ERR_IO_PENDING, http_stream2->SendRequest(headers, &response,
+                                                      callback.callback()));
+  data.RunFor(2);
+  callback.WaitForResult();
+
+  EXPECT_EQ(ERR_IO_PENDING, http_stream2->ReadResponseHeaders(
+      callback.callback()));
+  data.RunFor(1);
+  EXPECT_EQ(OK, callback.WaitForResult());
+  ASSERT_TRUE(response.headers.get() != NULL);
+  ASSERT_EQ(200, response.headers->response_code());
+}
+
+TEST_F(SpdyHttpStreamSpdy3Test, SendCredentialsEC) {
+  scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool =
+      new base::SequencedWorkerPool(1, "SpdyHttpStreamSpdy3Test");
+  scoped_ptr<ServerBoundCertService> server_bound_cert_service(
+      new ServerBoundCertService(new DefaultServerBoundCertStore(NULL),
+                                 sequenced_worker_pool));
+  std::string cert;
+  std::string proof;
+  GetECServerBoundCertAndProof("http://www.gmail.com/",
+                               server_bound_cert_service.get(),
+                               &cert, &proof);
+
+  TestSendCredentials(server_bound_cert_service.get(), cert, proof);
+
+  sequenced_worker_pool->Shutdown();
+}
+
+#endif  // !defined(USE_OPENSSL)
+
+// TODO(willchan): Write a longer test for SpdyStream that exercises all
+// methods.
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_http_utils.cc b/src/net/spdy/spdy_http_utils.cc
new file mode 100644
index 0000000..8a51685
--- /dev/null
+++ b/src/net/spdy/spdy_http_utils.cc
@@ -0,0 +1,186 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_http_utils.h"
+
+#include <string>
+
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "base/time.h"
+#include "net/base/escape.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_util.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
+#include "net/http/http_util.h"
+
+namespace net {
+
+bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers,
+                               int protocol_version,
+                               HttpResponseInfo* response) {
+  std::string status_key = (protocol_version >= 3) ? ":status" : "status";
+  std::string version_key = (protocol_version >= 3) ? ":version" : "version";
+  std::string version;
+  std::string status;
+
+  // The "status" and "version" headers are required.
+  SpdyHeaderBlock::const_iterator it;
+  it = headers.find(status_key);
+  if (it == headers.end())
+    return false;
+  status = it->second;
+
+  it = headers.find(version_key);
+  if (it == headers.end())
+    return false;
+  version = it->second;
+
+  response->response_time = base::Time::Now();
+
+  std::string raw_headers(version);
+  raw_headers.push_back(' ');
+  raw_headers.append(status);
+  raw_headers.push_back('\0');
+  for (it = headers.begin(); it != headers.end(); ++it) {
+    // For each value, if the server sends a NUL-separated
+    // list of values, we separate that back out into
+    // individual headers for each value in the list.
+    // e.g.
+    //    Set-Cookie "foo\0bar"
+    // becomes
+    //    Set-Cookie: foo\0
+    //    Set-Cookie: bar\0
+    std::string value = it->second;
+    size_t start = 0;
+    size_t end = 0;
+    do {
+      end = value.find('\0', start);
+      std::string tval;
+      if (end != value.npos)
+        tval = value.substr(start, (end - start));
+      else
+        tval = value.substr(start);
+      if (protocol_version >= 3 && it->first[0] == ':')
+        raw_headers.append(it->first.substr(1));
+      else
+        raw_headers.append(it->first);
+      raw_headers.push_back(':');
+      raw_headers.append(tval);
+      raw_headers.push_back('\0');
+      start = end + 1;
+    } while (end != value.npos);
+  }
+
+  response->headers = new HttpResponseHeaders(raw_headers);
+  response->was_fetched_via_spdy = true;
+  return true;
+}
+
+void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
+                                      const HttpRequestHeaders& request_headers,
+                                      SpdyHeaderBlock* headers,
+                                      int protocol_version,
+                                      bool direct) {
+
+  HttpRequestHeaders::Iterator it(request_headers);
+  while (it.GetNext()) {
+    std::string name = StringToLowerASCII(it.name());
+    if (name == "connection" || name == "proxy-connection" ||
+        name == "transfer-encoding") {
+      continue;
+    }
+    if (headers->find(name) == headers->end()) {
+      (*headers)[name] = it.value();
+    } else {
+      std::string new_value = (*headers)[name];
+      new_value.append(1, '\0');  // +=() doesn't append 0's
+      new_value += it.value();
+      (*headers)[name] = new_value;
+    }
+  }
+  static const char kHttpProtocolVersion[] = "HTTP/1.1";
+
+  if (protocol_version < 3) {
+    (*headers)["version"] = kHttpProtocolVersion;
+    (*headers)["method"] = info.method;
+    (*headers)["host"] = GetHostAndOptionalPort(info.url);
+    (*headers)["scheme"] = info.url.scheme();
+    if (direct)
+      (*headers)["url"] = HttpUtil::PathForRequest(info.url);
+    else
+      (*headers)["url"] = HttpUtil::SpecForRequest(info.url);
+  } else {
+    (*headers)[":version"] = kHttpProtocolVersion;
+    (*headers)[":method"] = info.method;
+    (*headers)[":host"] = GetHostAndOptionalPort(info.url);
+    (*headers)[":scheme"] = info.url.scheme();
+    (*headers)[":path"] = HttpUtil::PathForRequest(info.url);
+    headers->erase("host"); // this is kinda insane, spdy 3 spec.
+  }
+
+}
+
+COMPILE_ASSERT(HIGHEST - LOWEST < 4 &&
+               HIGHEST - MINIMUM_PRIORITY < 5,
+               request_priority_incompatible_with_spdy);
+
+SpdyPriority ConvertRequestPriorityToSpdyPriority(
+    const RequestPriority priority,
+    int protocol_version) {
+  DCHECK_GE(priority, MINIMUM_PRIORITY);
+  DCHECK_LT(priority, NUM_PRIORITIES);
+  if (protocol_version == 2) {
+    // SPDY 2 only has 2 bits of priority, but we have 5 RequestPriorities.
+    // Map IDLE => 3, LOWEST => 2, LOW => 2, MEDIUM => 1, HIGHEST => 0.
+    if (priority > LOWEST) {
+      return static_cast<SpdyPriority>(HIGHEST - priority);
+    } else {
+      return static_cast<SpdyPriority>(HIGHEST - priority - 1);
+    }
+  } else {
+    return static_cast<SpdyPriority>(HIGHEST - priority);
+  }
+}
+
+GURL GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers,
+                           int protocol_version,
+                           bool pushed) {
+  // SPDY 2 server push urls are specified in a single "url" header.
+  if (pushed && protocol_version == 2) {
+      std::string url;
+      SpdyHeaderBlock::const_iterator it;
+      it = headers.find("url");
+      if (it != headers.end())
+        url = it->second;
+      return GURL(url);
+  }
+
+  const char* scheme_header = protocol_version >= 3 ? ":scheme" : "scheme";
+  const char* host_header = protocol_version >= 3 ? ":host" : "host";
+  const char* path_header = protocol_version >= 3 ? ":path" : "url";
+
+  std::string scheme;
+  std::string host_port;
+  std::string path;
+  SpdyHeaderBlock::const_iterator it;
+  it = headers.find(scheme_header);
+  if (it != headers.end())
+    scheme = it->second;
+  it = headers.find(host_header);
+  if (it != headers.end())
+    host_port = it->second;
+  it = headers.find(path_header);
+  if (it != headers.end())
+    path = it->second;
+
+  std::string url =  (scheme.empty() || host_port.empty() || path.empty())
+      ? "" : scheme + "://" + host_port + path;
+  return GURL(url);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_http_utils.h b/src/net/spdy/spdy_http_utils.h
new file mode 100644
index 0000000..fabf4a2
--- /dev/null
+++ b/src/net/spdy/spdy_http_utils.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_HTTP_UTILS_H_
+#define NET_SPDY_SPDY_HTTP_UTILS_H_
+
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+#include "net/base/request_priority.h"
+#include "net/spdy/spdy_framer.h"
+#include "net/spdy/spdy_header_block.h"
+
+namespace net {
+
+class HttpResponseInfo;
+struct HttpRequestInfo;
+class HttpRequestHeaders;
+
+// Convert a SpdyHeaderBlock into an HttpResponseInfo.
+// |headers| input parameter with the SpdyHeaderBlock.
+// |response| output parameter for the HttpResponseInfo.
+// Returns true if successfully converted.  False if the SpdyHeaderBlock is
+// incomplete (e.g. missing 'status' or 'version').
+bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers,
+                               int protocol_version,
+                               HttpResponseInfo* response);
+
+// Create a SpdyHeaderBlock for a Spdy SYN_STREAM Frame from
+// HttpRequestInfo and HttpRequestHeaders.
+void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
+                                      const HttpRequestHeaders& request_headers,
+                                      SpdyHeaderBlock* headers,
+                                      int protocol_version,
+                                      bool direct);
+
+// Returns the URL associated with the |headers| by assembling the
+// scheme, host and path from the protocol specific keys.
+GURL GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers,
+                           int protocol_version,
+                           bool pushed);
+
+NET_EXPORT_PRIVATE SpdyPriority ConvertRequestPriorityToSpdyPriority(
+    RequestPriority priority,
+    int protocol_version);
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_HTTP_UTILS_H_
diff --git a/src/net/spdy/spdy_http_utils_unittest.cc b/src/net/spdy/spdy_http_utils_unittest.cc
new file mode 100644
index 0000000..2419de1
--- /dev/null
+++ b/src/net/spdy/spdy_http_utils_unittest.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_http_utils.h"
+
+#include "testing/platform_test.h"
+
+namespace net {
+
+namespace test {
+
+TEST(SpdyHttpUtilsTest, ConvertRequestPriorityToSpdy2Priority) {
+  EXPECT_EQ(0, ConvertRequestPriorityToSpdyPriority(HIGHEST, 2));
+  EXPECT_EQ(1, ConvertRequestPriorityToSpdyPriority(MEDIUM, 2));
+  EXPECT_EQ(2, ConvertRequestPriorityToSpdyPriority(LOW, 2));
+  EXPECT_EQ(2, ConvertRequestPriorityToSpdyPriority(LOWEST, 2));
+  EXPECT_EQ(3, ConvertRequestPriorityToSpdyPriority(IDLE, 2));
+}
+TEST(SpdyHttpUtilsTest, ConvertRequestPriorityToSpdy3Priority) {
+  EXPECT_EQ(0, ConvertRequestPriorityToSpdyPriority(HIGHEST, 3));
+  EXPECT_EQ(1, ConvertRequestPriorityToSpdyPriority(MEDIUM, 3));
+  EXPECT_EQ(2, ConvertRequestPriorityToSpdyPriority(LOW, 3));
+  EXPECT_EQ(3, ConvertRequestPriorityToSpdyPriority(LOWEST, 3));
+  EXPECT_EQ(4, ConvertRequestPriorityToSpdyPriority(IDLE, 3));
+}
+
+}  // namespace test
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_io_buffer.cc b/src/net/spdy/spdy_io_buffer.cc
new file mode 100644
index 0000000..f0c14b1
--- /dev/null
+++ b/src/net/spdy/spdy_io_buffer.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_io_buffer.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+// static
+uint64 SpdyIOBuffer::order_ = 0;
+
+SpdyIOBuffer::SpdyIOBuffer(
+    IOBuffer* buffer, int size, RequestPriority priority, SpdyStream* stream)
+  : buffer_(new DrainableIOBuffer(buffer, size)),
+    priority_(priority),
+    position_(++order_),
+    stream_(stream) {}
+
+SpdyIOBuffer::SpdyIOBuffer() : priority_(HIGHEST), position_(0), stream_(NULL) {
+}
+
+SpdyIOBuffer::SpdyIOBuffer(const SpdyIOBuffer& rhs) {
+  buffer_ = rhs.buffer_;
+  priority_ = rhs.priority_;
+  position_ = rhs.position_;
+  stream_ = rhs.stream_;
+}
+
+SpdyIOBuffer::~SpdyIOBuffer() {}
+
+SpdyIOBuffer& SpdyIOBuffer::operator=(const SpdyIOBuffer& rhs) {
+  buffer_ = rhs.buffer_;
+  priority_ = rhs.priority_;
+  position_ = rhs.position_;
+  stream_ = rhs.stream_;
+  return *this;
+}
+
+void SpdyIOBuffer::release() {
+  buffer_ = NULL;
+  stream_ = NULL;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_io_buffer.h b/src/net/spdy/spdy_io_buffer.h
new file mode 100644
index 0000000..9bbee16
--- /dev/null
+++ b/src/net/spdy/spdy_io_buffer.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_IO_BUFFER_H_
+#define NET_SPDY_SPDY_IO_BUFFER_H_
+
+#include "base/memory/ref_counted.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_export.h"
+#include "net/base/request_priority.h"
+
+namespace net {
+
+class SpdyStream;
+
+// A class for managing SPDY IO buffers.  These buffers need to be prioritized
+// so that the SpdySession sends them in the right order.  Further, they need
+// to track the SpdyStream which they are associated with so that incremental
+// completion of the IO can notify the appropriate stream of completion.
+class NET_EXPORT_PRIVATE SpdyIOBuffer {
+ public:
+  // Constructor
+  // |buffer| is the actual data buffer.
+  // |size| is the size of the data buffer.
+  // |priority| is the priority of this buffer.
+  // |stream| is a pointer to the stream which is managing this buffer.
+  SpdyIOBuffer(IOBuffer* buffer, int size, RequestPriority priority,
+               SpdyStream* stream);
+  // Declare this instead of using the default so that we avoid needing to
+  // include spdy_stream.h.
+  SpdyIOBuffer(const SpdyIOBuffer& rhs);
+  SpdyIOBuffer();
+  ~SpdyIOBuffer();
+  // Declare this instead of using the default so that we avoid needing to
+  // include spdy_stream.h.
+  SpdyIOBuffer& operator=(const SpdyIOBuffer& rhs);
+
+  // Accessors.
+  DrainableIOBuffer* buffer() const { return buffer_; }
+  size_t size() const { return buffer_->size(); }
+  void release();
+  RequestPriority priority() const { return priority_; }
+  const scoped_refptr<SpdyStream>& stream() const { return stream_; }
+
+  // Comparison operator to support sorting.
+  bool operator<(const SpdyIOBuffer& other) const {
+    if (priority_ != other.priority_)
+      return priority_ < other.priority_;
+    return position_ > other.position_;
+  }
+
+ private:
+  scoped_refptr<DrainableIOBuffer> buffer_;
+  RequestPriority priority_;
+  uint64 position_;
+  scoped_refptr<SpdyStream> stream_;
+  static uint64 order_;  // Maintains a FIFO order for equal priorities.
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_IO_BUFFER_H_
diff --git a/src/net/spdy/spdy_network_transaction_spdy2_unittest.cc b/src/net/spdy/spdy_network_transaction_spdy2_unittest.cc
new file mode 100644
index 0000000..07708dc
--- /dev/null
+++ b/src/net/spdy/spdy_network_transaction_spdy2_unittest.cc
@@ -0,0 +1,5780 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/http_network_transaction.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_vector.h"
+#include "net/base/auth.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/upload_bytes_element_reader.h"
+#include "net/base/upload_data_stream.h"
+#include "net/base/upload_file_element_reader.h"
+#include "net/http/http_network_session_peer.h"
+#include "net/http/http_transaction_unittest.h"
+#include "net/socket/client_socket_pool_base.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_stream.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy2;
+
+//-----------------------------------------------------------------------------
+
+namespace net {
+
+enum SpdyNetworkTransactionSpdy2TestTypes {
+  SPDYNPN,
+  SPDYNOSSL,
+  SPDYSSL,
+};
+
+class SpdyNetworkTransactionSpdy2Test
+    : public ::testing::TestWithParam<SpdyNetworkTransactionSpdy2TestTypes> {
+ protected:
+
+  virtual void SetUp() {
+    google_get_request_initialized_ = false;
+    google_post_request_initialized_ = false;
+    google_chunked_post_request_initialized_ = false;
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+  }
+
+  virtual void TearDown() {
+    UploadDataStream::ResetMergeChunks();
+    // Empty the current queue.
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void set_merge_chunks(bool merge) {
+    UploadDataStream::set_merge_chunks(merge);
+  }
+
+  struct TransactionHelperResult {
+    int rv;
+    std::string status_line;
+    std::string response_data;
+    HttpResponseInfo response_info;
+  };
+
+  // A helper class that handles all the initial npn/ssl setup.
+  class NormalSpdyTransactionHelper {
+   public:
+    NormalSpdyTransactionHelper(const HttpRequestInfo& request,
+                                const BoundNetLog& log,
+                                SpdyNetworkTransactionSpdy2TestTypes test_type,
+                                SpdySessionDependencies* session_deps)
+        : request_(request),
+          session_deps_(session_deps == NULL ?
+                        new SpdySessionDependencies() : session_deps),
+          session_(SpdySessionDependencies::SpdyCreateSession(
+                       session_deps_.get())),
+          log_(log),
+          test_type_(test_type),
+          deterministic_(false),
+          spdy_enabled_(true) {
+      switch (test_type_) {
+        case SPDYNOSSL:
+        case SPDYSSL:
+          port_ = 80;
+          break;
+        case SPDYNPN:
+          port_ = 443;
+          break;
+        default:
+          NOTREACHED();
+      }
+    }
+
+    ~NormalSpdyTransactionHelper() {
+      // Any test which doesn't close the socket by sending it an EOF will
+      // have a valid session left open, which leaks the entire session pool.
+      // This is just fine - in fact, some of our tests intentionally do this
+      // so that we can check consistency of the SpdySessionPool as the test
+      // finishes.  If we had put an EOF on the socket, the SpdySession would
+      // have closed and we wouldn't be able to check the consistency.
+
+      // Forcefully close existing sessions here.
+      session()->spdy_session_pool()->CloseAllSessions();
+    }
+
+    void SetDeterministic() {
+      session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+          session_deps_.get());
+      deterministic_ = true;
+    }
+
+    void SetSpdyDisabled() {
+      spdy_enabled_ = false;
+      port_ = 80;
+    }
+
+    void RunPreTestSetup() {
+      if (!session_deps_.get())
+        session_deps_.reset(new SpdySessionDependencies());
+      if (!session_.get())
+        session_ = SpdySessionDependencies::SpdyCreateSession(
+            session_deps_.get());
+      HttpStreamFactory::set_use_alternate_protocols(false);
+      HttpStreamFactory::set_force_spdy_over_ssl(false);
+      HttpStreamFactory::set_force_spdy_always(false);
+
+      std::vector<std::string> next_protos;
+      next_protos.push_back("http/1.1");
+      next_protos.push_back("spdy/2");
+
+      switch (test_type_) {
+        case SPDYNPN:
+          session_->http_server_properties()->SetAlternateProtocol(
+              HostPortPair("www.google.com", 80), 443,
+              NPN_SPDY_2);
+          HttpStreamFactory::set_use_alternate_protocols(true);
+          HttpStreamFactory::SetNextProtos(next_protos);
+          break;
+        case SPDYNOSSL:
+          HttpStreamFactory::set_force_spdy_over_ssl(false);
+          HttpStreamFactory::set_force_spdy_always(true);
+          break;
+        case SPDYSSL:
+          HttpStreamFactory::set_force_spdy_over_ssl(true);
+          HttpStreamFactory::set_force_spdy_always(true);
+          break;
+        default:
+          NOTREACHED();
+      }
+
+      // We're now ready to use SSL-npn SPDY.
+      trans_.reset(new HttpNetworkTransaction(session_));
+    }
+
+    // Start the transaction, read some data, finish.
+    void RunDefaultTest() {
+      output_.rv = trans_->Start(&request_, callback.callback(), log_);
+
+      // We expect an IO Pending or some sort of error.
+      EXPECT_LT(output_.rv, 0);
+      if (output_.rv != ERR_IO_PENDING)
+        return;
+
+      output_.rv = callback.WaitForResult();
+      if (output_.rv != OK) {
+        session_->spdy_session_pool()->CloseCurrentSessions(net::ERR_ABORTED);
+        return;
+      }
+
+      // Verify responses.
+      const HttpResponseInfo* response = trans_->GetResponseInfo();
+      ASSERT_TRUE(response != NULL);
+      ASSERT_TRUE(response->headers != NULL);
+      EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+      EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy);
+      if (test_type_ == SPDYNPN && spdy_enabled_) {
+        EXPECT_TRUE(response->was_npn_negotiated);
+      } else {
+        EXPECT_TRUE(!response->was_npn_negotiated);
+      }
+      // If SPDY is not enabled, a HTTP request should not be diverted
+      // over a SSL session.
+      if (!spdy_enabled_) {
+        EXPECT_EQ(request_.url.SchemeIs("https"),
+                  response->was_npn_negotiated);
+      }
+      EXPECT_EQ("127.0.0.1", response->socket_address.host());
+      EXPECT_EQ(port_, response->socket_address.port());
+      output_.status_line = response->headers->GetStatusLine();
+      output_.response_info = *response;  // Make a copy so we can verify.
+      output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
+    }
+
+    // Most tests will want to call this function. In particular, the MockReads
+    // should end with an empty read, and that read needs to be processed to
+    // ensure proper deletion of the spdy_session_pool.
+    void VerifyDataConsumed() {
+      for (DataVector::iterator it = data_vector_.begin();
+          it != data_vector_.end(); ++it) {
+        EXPECT_TRUE((*it)->at_read_eof()) << "Read count: "
+                                          << (*it)->read_count()
+                                          << " Read index: "
+                                          << (*it)->read_index();
+        EXPECT_TRUE((*it)->at_write_eof()) << "Write count: "
+                                           << (*it)->write_count()
+                                           << " Write index: "
+                                           << (*it)->write_index();
+      }
+    }
+
+    // Occasionally a test will expect to error out before certain reads are
+    // processed. In that case we want to explicitly ensure that the reads were
+    // not processed.
+    void VerifyDataNotConsumed() {
+      for (DataVector::iterator it = data_vector_.begin();
+          it != data_vector_.end(); ++it) {
+        EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: "
+                                           << (*it)->read_count()
+                                           << " Read index: "
+                                           << (*it)->read_index();
+        EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: "
+                                            << (*it)->write_count()
+                                            << " Write index: "
+                                            << (*it)->write_index();
+      }
+    }
+
+    void RunToCompletion(StaticSocketDataProvider* data) {
+      RunPreTestSetup();
+      AddData(data);
+      RunDefaultTest();
+      VerifyDataConsumed();
+    }
+
+    void AddData(StaticSocketDataProvider* data) {
+      DCHECK(!deterministic_);
+      data_vector_.push_back(data);
+      SSLSocketDataProvider* ssl_provider =
+          new SSLSocketDataProvider(ASYNC, OK);
+      if (test_type_ == SPDYNPN)
+        ssl_provider->SetNextProto(kProtoSPDY2);
+
+      ssl_vector_.push_back(ssl_provider);
+      if (test_type_ == SPDYNPN || test_type_ == SPDYSSL)
+        session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_provider);
+
+      session_deps_->socket_factory->AddSocketDataProvider(data);
+      if (test_type_ == SPDYNPN) {
+        MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
+        StaticSocketDataProvider* hanging_non_alternate_protocol_socket =
+            new StaticSocketDataProvider(NULL, 0, NULL, 0);
+        hanging_non_alternate_protocol_socket->set_connect_data(
+            never_finishing_connect);
+        session_deps_->socket_factory->AddSocketDataProvider(
+            hanging_non_alternate_protocol_socket);
+        alternate_vector_.push_back(hanging_non_alternate_protocol_socket);
+      }
+    }
+
+    void AddDeterministicData(DeterministicSocketData* data) {
+      DCHECK(deterministic_);
+      data_vector_.push_back(data);
+      SSLSocketDataProvider* ssl_provider =
+          new SSLSocketDataProvider(ASYNC, OK);
+      if (test_type_ == SPDYNPN)
+        ssl_provider->SetNextProto(kProtoSPDY2);
+
+      ssl_vector_.push_back(ssl_provider);
+      if (test_type_ == SPDYNPN || test_type_ == SPDYSSL) {
+        session_deps_->deterministic_socket_factory->
+            AddSSLSocketDataProvider(ssl_provider);
+      }
+      session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
+      if (test_type_ == SPDYNPN) {
+        MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
+        DeterministicSocketData* hanging_non_alternate_protocol_socket =
+            new DeterministicSocketData(NULL, 0, NULL, 0);
+        hanging_non_alternate_protocol_socket->set_connect_data(
+            never_finishing_connect);
+        session_deps_->deterministic_socket_factory->AddSocketDataProvider(
+            hanging_non_alternate_protocol_socket);
+        alternate_deterministic_vector_.push_back(
+            hanging_non_alternate_protocol_socket);
+      }
+    }
+
+    void SetSession(const scoped_refptr<HttpNetworkSession>& session) {
+      session_ = session;
+    }
+    HttpNetworkTransaction* trans() { return trans_.get(); }
+    void ResetTrans() { trans_.reset(); }
+    TransactionHelperResult& output() { return output_; }
+    const HttpRequestInfo& request() const { return request_; }
+    const scoped_refptr<HttpNetworkSession>& session() const {
+      return session_;
+    }
+    scoped_ptr<SpdySessionDependencies>& session_deps() {
+      return session_deps_;
+    }
+    int port() const { return port_; }
+    SpdyNetworkTransactionSpdy2TestTypes test_type() const {
+      return test_type_;
+    }
+
+   private:
+    typedef std::vector<StaticSocketDataProvider*> DataVector;
+    typedef ScopedVector<SSLSocketDataProvider> SSLVector;
+    typedef ScopedVector<StaticSocketDataProvider> AlternateVector;
+    typedef ScopedVector<DeterministicSocketData> AlternateDeterministicVector;
+    HttpRequestInfo request_;
+    scoped_ptr<SpdySessionDependencies> session_deps_;
+    scoped_refptr<HttpNetworkSession> session_;
+    TransactionHelperResult output_;
+    scoped_ptr<StaticSocketDataProvider> first_transaction_;
+    SSLVector ssl_vector_;
+    TestCompletionCallback callback;
+    scoped_ptr<HttpNetworkTransaction> trans_;
+    scoped_ptr<HttpNetworkTransaction> trans_http_;
+    DataVector data_vector_;
+    AlternateVector alternate_vector_;
+    AlternateDeterministicVector alternate_deterministic_vector_;
+    const BoundNetLog& log_;
+    SpdyNetworkTransactionSpdy2TestTypes test_type_;
+    int port_;
+    bool deterministic_;
+    bool spdy_enabled_;
+  };
+
+  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
+                                             int expected_status);
+
+  void ConnectStatusHelper(const MockRead& status);
+
+  const HttpRequestInfo& CreateGetPushRequest() {
+    google_get_push_request_.method = "GET";
+    google_get_push_request_.url = GURL("http://www.google.com/foo.dat");
+    google_get_push_request_.load_flags = 0;
+    return google_get_push_request_;
+  }
+
+  const HttpRequestInfo& CreateGetRequest() {
+    if (!google_get_request_initialized_) {
+      google_get_request_.method = "GET";
+      google_get_request_.url = GURL(kDefaultURL);
+      google_get_request_.load_flags = 0;
+      google_get_request_initialized_ = true;
+    }
+    return google_get_request_;
+  }
+
+  const HttpRequestInfo& CreateGetRequestWithUserAgent() {
+    if (!google_get_request_initialized_) {
+      google_get_request_.method = "GET";
+      google_get_request_.url = GURL(kDefaultURL);
+      google_get_request_.load_flags = 0;
+      google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
+      google_get_request_initialized_ = true;
+    }
+    return google_get_request_;
+  }
+
+  const HttpRequestInfo& CreatePostRequest() {
+    if (!google_post_request_initialized_) {
+      ScopedVector<UploadElementReader> element_readers;
+      element_readers.push_back(
+          new UploadBytesElementReader(kUploadData, kUploadDataSize));
+      upload_data_stream_.reset(new UploadDataStream(&element_readers, 0));
+
+      google_post_request_.method = "POST";
+      google_post_request_.url = GURL(kDefaultURL);
+      google_post_request_.upload_data_stream = upload_data_stream_.get();
+      google_post_request_initialized_ = true;
+    }
+    return google_post_request_;
+  }
+
+  const HttpRequestInfo& CreateFilePostRequest() {
+    if (!google_post_request_initialized_) {
+      FilePath file_path;
+      CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
+      CHECK_EQ(static_cast<int>(kUploadDataSize),
+               file_util::WriteFile(file_path, kUploadData, kUploadDataSize));
+
+      ScopedVector<UploadElementReader> element_readers;
+      element_readers.push_back(new UploadFileElementReader(
+          file_path, 0, kUploadDataSize, base::Time()));
+      upload_data_stream_.reset(new UploadDataStream(&element_readers, 0));
+
+      google_post_request_.method = "POST";
+      google_post_request_.url = GURL(kDefaultURL);
+      google_post_request_.upload_data_stream = upload_data_stream_.get();
+      google_post_request_initialized_ = true;
+    }
+    return google_post_request_;
+  }
+
+  const HttpRequestInfo& CreateComplexPostRequest() {
+    if (!google_post_request_initialized_) {
+      const int kFileRangeOffset = 1;
+      const int kFileRangeLength = 3;
+      CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
+
+      FilePath file_path;
+      CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
+      CHECK_EQ(static_cast<int>(kUploadDataSize),
+               file_util::WriteFile(file_path, kUploadData, kUploadDataSize));
+
+      ScopedVector<UploadElementReader> element_readers;
+      element_readers.push_back(
+          new UploadBytesElementReader(kUploadData, kFileRangeOffset));
+      element_readers.push_back(new UploadFileElementReader(
+          file_path, kFileRangeOffset, kFileRangeLength, base::Time()));
+      element_readers.push_back(new UploadBytesElementReader(
+          kUploadData + kFileRangeOffset + kFileRangeLength,
+          kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
+      upload_data_stream_.reset(new UploadDataStream(&element_readers, 0));
+
+      google_post_request_.method = "POST";
+      google_post_request_.url = GURL(kDefaultURL);
+      google_post_request_.upload_data_stream = upload_data_stream_.get();
+      google_post_request_initialized_ = true;
+    }
+    return google_post_request_;
+  }
+
+  const HttpRequestInfo& CreateChunkedPostRequest() {
+    if (!google_chunked_post_request_initialized_) {
+      upload_data_stream_.reset(
+          new UploadDataStream(UploadDataStream::CHUNKED, 0));
+      upload_data_stream_->AppendChunk(kUploadData, kUploadDataSize, false);
+      upload_data_stream_->AppendChunk(kUploadData, kUploadDataSize, true);
+
+      google_chunked_post_request_.method = "POST";
+      google_chunked_post_request_.url = GURL(kDefaultURL);
+      google_chunked_post_request_.upload_data_stream =
+          upload_data_stream_.get();
+      google_chunked_post_request_initialized_ = true;
+    }
+    return google_chunked_post_request_;
+  }
+
+  // Read the result of a particular transaction, knowing that we've got
+  // multiple transactions in the read pipeline; so as we read, we may have
+  // to skip over data destined for other transactions while we consume
+  // the data for |trans|.
+  int ReadResult(HttpNetworkTransaction* trans,
+                 StaticSocketDataProvider* data,
+                 std::string* result) {
+    const int kSize = 3000;
+
+    int bytes_read = 0;
+    scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize));
+    TestCompletionCallback callback;
+    while (true) {
+      int rv = trans->Read(buf, kSize, callback.callback());
+      if (rv == ERR_IO_PENDING) {
+        // Multiple transactions may be in the data set.  Keep pulling off
+        // reads until we complete our callback.
+        while (!callback.have_result()) {
+          data->CompleteRead();
+          MessageLoop::current()->RunUntilIdle();
+        }
+        rv = callback.WaitForResult();
+      } else if (rv <= 0) {
+        break;
+      }
+      result->append(buf->data(), rv);
+      bytes_read += rv;
+    }
+    return bytes_read;
+  }
+
+  void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
+    // This lengthy block is reaching into the pool to dig out the active
+    // session.  Once we have the session, we verify that the streams are
+    // all closed and not leaked at this point.
+    const GURL& url = helper.request().url;
+    int port = helper.test_type() == SPDYNPN ? 443 : 80;
+    HostPortPair host_port_pair(url.host(), port);
+    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+    BoundNetLog log;
+    const scoped_refptr<HttpNetworkSession>& session = helper.session();
+    SpdySessionPool* pool(session->spdy_session_pool());
+    EXPECT_TRUE(pool->HasSession(pair));
+    scoped_refptr<SpdySession> spdy_session(pool->Get(pair, log));
+    ASSERT_TRUE(spdy_session.get() != NULL);
+    EXPECT_EQ(0u, spdy_session->num_active_streams());
+    EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
+  }
+
+  void RunServerPushTest(OrderedSocketData* data,
+                         HttpResponseInfo* response,
+                         HttpResponseInfo* push_response,
+                         std::string& expected) {
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunPreTestSetup();
+    helper.AddData(data);
+
+    HttpNetworkTransaction* trans = helper.trans();
+
+    // Start the transaction with basic parameters.
+    TestCompletionCallback callback;
+    int rv = trans->Start(
+        &CreateGetRequest(), callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    rv = callback.WaitForResult();
+
+    // Request the pushed path.
+    scoped_ptr<HttpNetworkTransaction> trans2(
+        new HttpNetworkTransaction(helper.session()));
+    rv = trans2->Start(
+        &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    MessageLoop::current()->RunUntilIdle();
+
+    // The data for the pushed path may be coming in more than 1 packet. Compile
+    // the results into a single string.
+
+    // Read the server push body.
+    std::string result2;
+    ReadResult(trans2.get(), data, &result2);
+    // Read the response body.
+    std::string result;
+    ReadResult(trans, data, &result);
+
+    // Verify that we consumed all test data.
+    EXPECT_TRUE(data->at_read_eof());
+    EXPECT_TRUE(data->at_write_eof());
+
+    // Verify that the received push data is same as the expected push data.
+    EXPECT_EQ(result2.compare(expected), 0) << "Received data: "
+                                            << result2
+                                            << "||||| Expected data: "
+                                            << expected;
+
+    // Verify the SYN_REPLY.
+    // Copy the response info, because trans goes away.
+    *response = *trans->GetResponseInfo();
+    *push_response = *trans2->GetResponseInfo();
+
+    VerifyStreamsClosed(helper);
+  }
+
+  static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper,
+                                    int result) {
+    helper->ResetTrans();
+  }
+
+  static void StartTransactionCallback(
+      const scoped_refptr<HttpNetworkSession>& session,
+      int result) {
+    scoped_ptr<HttpNetworkTransaction> trans(
+        new HttpNetworkTransaction(session));
+    TestCompletionCallback callback;
+    HttpRequestInfo request;
+    request.method = "GET";
+    request.url = GURL("http://www.google.com/");
+    request.load_flags = 0;
+    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    callback.WaitForResult();
+  }
+
+ private:
+  scoped_ptr<UploadDataStream> upload_data_stream_;
+  bool google_get_request_initialized_;
+  bool google_post_request_initialized_;
+  bool google_chunked_post_request_initialized_;
+  HttpRequestInfo google_get_request_;
+  HttpRequestInfo google_post_request_;
+  HttpRequestInfo google_chunked_post_request_;
+  HttpRequestInfo google_get_push_request_;
+  base::ScopedTempDir temp_dir_;
+};
+
+//-----------------------------------------------------------------------------
+// All tests are run with three different connection types: SPDY after NPN
+// negotiation, SPDY without SSL, and SPDY with SSL.
+INSTANTIATE_TEST_CASE_P(Spdy,
+                        SpdyNetworkTransactionSpdy2Test,
+                        ::testing::Values(SPDYNOSSL, SPDYSSL, SPDYNPN));
+
+
+// Verify HttpNetworkTransaction constructor.
+TEST_P(SpdyNetworkTransactionSpdy2Test, Constructor) {
+  SpdySessionDependencies session_deps;
+  scoped_refptr<HttpNetworkSession> session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+  scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, Get) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, GetAtEachPriority) {
+  for (RequestPriority p = MINIMUM_PRIORITY; p < NUM_PRIORITIES;
+       p = RequestPriority(p + 1)) {
+    // Construct the request.
+    scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, p));
+    MockWrite writes[] = { CreateMockWrite(*req) };
+
+    const int spdy_prio = reinterpret_cast<SpdySynStreamControlFrame*>(
+        req.get())->priority();
+    // this repeats the RequestPriority-->SpdyPriority mapping from
+    // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
+    // sure it's being done right.
+    switch(p) {
+      case HIGHEST:
+        EXPECT_EQ(0, spdy_prio);
+        break;
+      case MEDIUM:
+        EXPECT_EQ(1, spdy_prio);
+        break;
+      case LOW:
+      case LOWEST:
+        EXPECT_EQ(2, spdy_prio);
+        break;
+      case IDLE:
+        EXPECT_EQ(3, spdy_prio);
+        break;
+      default:
+        FAIL();
+    }
+
+    scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*resp),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                              writes, arraysize(writes));
+    HttpRequestInfo http_req = CreateGetRequest();
+    http_req.priority = p;
+
+    NormalSpdyTransactionHelper helper(http_req, BoundNetLog(),
+                                       GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!", out.response_data);
+  }
+}
+
+// Start three gets simultaniously; making sure that multiplexed
+// streams work properly.
+
+// This can't use the TransactionHelper method, since it only
+// handles a single transaction, and finishes them as soon
+// as it launches them.
+
+// TODO(gavinp): create a working generalized TransactionHelper that
+// can allow multiple streams in flight.
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ThreeGets) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
+  scoped_ptr<SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+    CreateMockWrite(*req3),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body),
+    CreateMockRead(*resp2, 4),
+    CreateMockRead(*body2),
+    CreateMockRead(*resp3, 7),
+    CreateMockRead(*body3),
+
+    CreateMockRead(*fbody),
+    CreateMockRead(*fbody2),
+    CreateMockRead(*fbody3),
+
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because three get requests are sent out, so
+  // there needs to be three sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  TestCompletionCallback callback3;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  out.rv = callback3.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+
+  trans2->GetResponseInfo();
+
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  helper.VerifyDataConsumed();
+  EXPECT_EQ(OK, out.rv);
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, TwoGetsLateBinding) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body),
+    CreateMockRead(*resp2, 4),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody),
+    CreateMockRead(*fbody2),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
+
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+  data_placeholder.set_connect_data(never_finishing_connect);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because two get requests are sent out, so
+  // there needs to be two sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  EXPECT_TRUE(response2->headers != NULL);
+  EXPECT_TRUE(response2->was_fetched_via_spdy);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, TwoGetsLateBindingFromPreconnect) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body),
+    CreateMockRead(*resp2, 4),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody),
+    CreateMockRead(*fbody2),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  OrderedSocketData preconnect_data(reads, arraysize(reads),
+                                    writes, arraysize(writes));
+
+  MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING);
+
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+  data_placeholder.set_connect_data(never_finishing_connect);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&preconnect_data);
+  // We require placeholder data because 3 connections are attempted (first is
+  // the preconnect, 2nd and 3rd are the never finished connections.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+
+  HttpRequestInfo httpreq = CreateGetRequest();
+
+  // Preconnect the first.
+  SSLConfig preconnect_ssl_config;
+  helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
+  HttpStreamFactory* http_stream_factory =
+      helper.session()->http_stream_factory();
+  if (http_stream_factory->has_next_protos()) {
+    preconnect_ssl_config.next_protos = http_stream_factory->next_protos();
+  }
+
+  http_stream_factory->PreconnectStreams(
+      1, httpreq, preconnect_ssl_config, preconnect_ssl_config);
+
+  out.rv = trans1->Start(&httpreq, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans2->Start(&httpreq, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  EXPECT_TRUE(response2->headers != NULL);
+  EXPECT_TRUE(response2->was_fetched_via_spdy);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  helper.VerifyDataConsumed();
+}
+
+// Similar to ThreeGets above, however this test adds a SETTINGS
+// frame.  The SETTINGS frame is read during the IO loop waiting on
+// the first transaction completion, and sets a maximum concurrent
+// stream limit of 1.  This means that our IO loop exists after the
+// second transaction completes, so we can assert on read_index().
+TEST_P(SpdyNetworkTransactionSpdy2Test, ThreeGetsWithMaxConcurrent) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
+  scoped_ptr<SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+    CreateMockWrite(*req3),
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fbody),
+    CreateMockRead(*resp2, 7),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody2),
+    CreateMockRead(*resp3, 12),
+    CreateMockRead(*body3),
+    CreateMockRead(*fbody3),
+
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  {
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunPreTestSetup();
+    helper.AddData(&data);
+    // We require placeholder data because three get requests are sent out, so
+    // there needs to be three sets of SSL connection data.
+    helper.AddData(&data_placeholder);
+    helper.AddData(&data_placeholder);
+    scoped_ptr<HttpNetworkTransaction> trans1(
+        new HttpNetworkTransaction(helper.session()));
+    scoped_ptr<HttpNetworkTransaction> trans2(
+        new HttpNetworkTransaction(helper.session()));
+    scoped_ptr<HttpNetworkTransaction> trans3(
+        new HttpNetworkTransaction(helper.session()));
+
+    TestCompletionCallback callback1;
+    TestCompletionCallback callback2;
+    TestCompletionCallback callback3;
+
+    HttpRequestInfo httpreq1 = CreateGetRequest();
+    HttpRequestInfo httpreq2 = CreateGetRequest();
+    HttpRequestInfo httpreq3 = CreateGetRequest();
+
+    out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+    ASSERT_EQ(out.rv, ERR_IO_PENDING);
+    // Run transaction 1 through quickly to force a read of our SETTINGS
+    // frame.
+    out.rv = callback1.WaitForResult();
+    ASSERT_EQ(OK, out.rv);
+
+    out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+    ASSERT_EQ(out.rv, ERR_IO_PENDING);
+    out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+    ASSERT_EQ(out.rv, ERR_IO_PENDING);
+    out.rv = callback2.WaitForResult();
+    ASSERT_EQ(OK, out.rv);
+    EXPECT_EQ(7U, data.read_index());  // i.e. the third trans was queued
+
+    out.rv = callback3.WaitForResult();
+    ASSERT_EQ(OK, out.rv);
+
+    const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+    ASSERT_TRUE(response1 != NULL);
+    EXPECT_TRUE(response1->headers != NULL);
+    EXPECT_TRUE(response1->was_fetched_via_spdy);
+    out.status_line = response1->headers->GetStatusLine();
+    out.response_info = *response1;
+    out.rv = ReadTransaction(trans1.get(), &out.response_data);
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!hello!", out.response_data);
+
+    const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+    out.status_line = response2->headers->GetStatusLine();
+    out.response_info = *response2;
+    out.rv = ReadTransaction(trans2.get(), &out.response_data);
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!hello!", out.response_data);
+
+    const HttpResponseInfo* response3 = trans3->GetResponseInfo();
+    out.status_line = response3->headers->GetStatusLine();
+    out.response_info = *response3;
+    out.rv = ReadTransaction(trans3.get(), &out.response_data);
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!hello!", out.response_data);
+
+    helper.VerifyDataConsumed();
+  }
+  EXPECT_EQ(OK, out.rv);
+}
+
+// Similar to ThreeGetsWithMaxConcurrent above, however this test adds
+// a fourth transaction.  The third and fourth transactions have
+// different data ("hello!" vs "hello!hello!") and because of the
+// user specified priority, we expect to see them inverted in
+// the response from the server.
+TEST_P(SpdyNetworkTransactionSpdy2Test, FourGetsWithMaxConcurrentPriority) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> req4(
+      ConstructSpdyGet(NULL, 0, false, 5, HIGHEST));
+  scoped_ptr<SpdyFrame> resp4(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> fbody4(ConstructSpdyBodyFrame(5, true));
+
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 7, LOWEST));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 7));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(7, false));
+  scoped_ptr<SpdyFrame> fbody3(ConstructSpdyBodyFrame(7, true));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = { CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+    CreateMockWrite(*req4),
+    CreateMockWrite(*req3),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fbody),
+    CreateMockRead(*resp2, 7),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody2),
+    CreateMockRead(*resp4, 13),
+    CreateMockRead(*fbody4),
+    CreateMockRead(*resp3, 16),
+    CreateMockRead(*body3),
+    CreateMockRead(*fbody3),
+
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+      BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because four get requests are sent out, so
+  // there needs to be four sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans4(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  TestCompletionCallback callback3;
+  TestCompletionCallback callback4;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+  HttpRequestInfo httpreq4 = CreateGetRequest();
+  httpreq4.priority = HIGHEST;
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans4->Start(&httpreq4, callback4.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  EXPECT_EQ(data.read_index(), 7U);  // i.e. the third & fourth trans queued
+
+  out.rv = callback3.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  // notice: response3 gets two hellos, response4 gets one
+  // hello, so we know dequeuing priority was respected.
+  const HttpResponseInfo* response3 = trans3->GetResponseInfo();
+  out.status_line = response3->headers->GetStatusLine();
+  out.response_info = *response3;
+  out.rv = ReadTransaction(trans3.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  out.rv = callback4.WaitForResult();
+  EXPECT_EQ(OK, out.rv);
+  const HttpResponseInfo* response4 = trans4->GetResponseInfo();
+  out.status_line = response4->headers->GetStatusLine();
+  out.response_info = *response4;
+  out.rv = ReadTransaction(trans4.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+  helper.VerifyDataConsumed();
+  EXPECT_EQ(OK, out.rv);
+}
+
+// Similar to ThreeGetsMaxConcurrrent above, however, this test
+// deletes a session in the middle of the transaction to insure
+// that we properly remove pendingcreatestream objects from
+// the spdy_session
+TEST_P(SpdyNetworkTransactionSpdy2Test, ThreeGetsWithMaxConcurrentDelete) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = { CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fbody),
+    CreateMockRead(*resp2, 7),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody2),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+      BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because three get requests are sent out, so
+  // there needs to be three sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  TestCompletionCallback callback3;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  delete trans3.release();
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  EXPECT_EQ(8U, data.read_index());
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  ASSERT_TRUE(response1 != NULL);
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  ASSERT_TRUE(response2 != NULL);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+  helper.VerifyDataConsumed();
+  EXPECT_EQ(OK, out.rv);
+}
+
+namespace {
+
+// The KillerCallback will delete the transaction on error as part of the
+// callback.
+class KillerCallback : public TestCompletionCallbackBase {
+ public:
+  explicit KillerCallback(HttpNetworkTransaction* transaction)
+      : transaction_(transaction),
+        ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+            base::Bind(&KillerCallback::OnComplete, base::Unretained(this)))) {
+  }
+
+  virtual ~KillerCallback() {}
+
+  const CompletionCallback& callback() const { return callback_; }
+
+ private:
+  void OnComplete(int result) {
+    if (result < 0)
+      delete transaction_;
+
+    SetResult(result);
+  }
+
+  HttpNetworkTransaction* transaction_;
+  CompletionCallback callback_;
+};
+
+}  // namespace
+
+// Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
+// closes the socket while we have a pending transaction waiting for
+// a pending stream creation.  http://crbug.com/52901
+TEST_P(SpdyNetworkTransactionSpdy2Test, ThreeGetsWithMaxConcurrentSocketClose) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fin_body(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = { CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fin_body),
+    CreateMockRead(*resp2, 7),
+    MockRead(ASYNC, ERR_CONNECTION_RESET, 0),  // Abort!
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+      BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because three get requests are sent out, so
+  // there needs to be three sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  HttpNetworkTransaction trans1(helper.session());
+  HttpNetworkTransaction trans2(helper.session());
+  HttpNetworkTransaction* trans3(new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  KillerCallback callback3(trans3);
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+
+  out.rv = trans1.Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  out.rv = trans2.Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback3.WaitForResult();
+  ASSERT_EQ(ERR_ABORTED, out.rv);
+
+  EXPECT_EQ(6U, data.read_index());
+
+  const HttpResponseInfo* response1 = trans1.GetResponseInfo();
+  ASSERT_TRUE(response1 != NULL);
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(&trans1, &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response2 = trans2.GetResponseInfo();
+  ASSERT_TRUE(response2 != NULL);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(&trans2, &out.response_data);
+  EXPECT_EQ(ERR_CONNECTION_RESET, out.rv);
+
+  helper.VerifyDataConsumed();
+}
+
+// Test that a simple PUT request works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, Put) {
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "PUT";
+  request.url = GURL("http://www.google.com/");
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,             // Kind = Syn
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_FIN,       // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  const char* const kPutHeaders[] = {
+    "method", "PUT",
+    "url", "/",
+    "host", "www.google.com",
+    "scheme", "http",
+    "version", "HTTP/1.1",
+    "content-length", "0"
+  };
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0,
+    kPutHeaders, arraysize(kPutHeaders) / 2));
+  MockWrite writes[] = {
+    CreateMockWrite(*req)
+  };
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  const SpdyHeaderInfo kSynReplyHeader = {
+    SYN_REPLY,              // Kind = SynReply
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_NONE,      // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  static const char* const kStandardGetHeaders[] = {
+    "status", "200",
+    "version", "HTTP/1.1"
+    "content-length", "1234"
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader,
+      NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+}
+
+// Test that a simple HEAD request works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, Head) {
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "HEAD";
+  request.url = GURL("http://www.google.com/");
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,             // Kind = Syn
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_FIN,       // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  const char* const kHeadHeaders[] = {
+    "method", "HEAD",
+    "url", "/",
+    "host", "www.google.com",
+    "scheme", "http",
+    "version", "HTTP/1.1",
+    "content-length", "0"
+  };
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0,
+    kHeadHeaders, arraysize(kHeadHeaders) / 2));
+  MockWrite writes[] = {
+    CreateMockWrite(*req)
+  };
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  const SpdyHeaderInfo kSynReplyHeader = {
+    SYN_REPLY,              // Kind = SynReply
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_NONE,      // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  static const char* const kStandardGetHeaders[] = {
+    "status", "200",
+    "version", "HTTP/1.1"
+    "content-length", "1234"
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader,
+      NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+}
+
+// Test that a simple POST works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, Post) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),  // POST upload frame
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreatePostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a POST with a file works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, FilePost) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),  // POST upload frame
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateFilePostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a complex POST works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, ComplexPost) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),  // POST upload frame
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateComplexPostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a chunked POST works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, ChunkedPost) {
+  set_merge_chunks(false);
+
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*chunk1),
+    CreateMockWrite(*chunk2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*chunk1),
+    CreateMockRead(*chunk2),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+}
+
+// Test that a POST without any post data works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, NullPost) {
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  // Create an empty UploadData.
+  request.upload_data_stream = NULL;
+
+  // When request.upload_data_stream is NULL for post, content-length is
+  // expected to be 0.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(0, NULL, 0));
+  // Set the FIN bit since there will be no body.
+  req->set_flags(CONTROL_FLAG_FIN);
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a simple POST works.
+TEST_P(SpdyNetworkTransactionSpdy2Test, EmptyPost) {
+  // Create an empty UploadDataStream.
+  ScopedVector<UploadElementReader> element_readers;
+  UploadDataStream stream(&element_readers, 0);
+
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &stream;
+
+  const uint64 kContentLength = 0;
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kContentLength, NULL, 0));
+  // Set the FIN bit since there will be no body.
+  req->set_flags(CONTROL_FLAG_FIN);
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads), writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// While we're doing a post, the server sends back a SYN_REPLY.
+TEST_P(SpdyNetworkTransactionSpdy2Test, PostWithEarlySynReply) {
+  static const char upload[] = { "hello!" };
+  ScopedVector<UploadElementReader> element_readers;
+  element_readers.push_back(
+      new UploadBytesElementReader(upload, sizeof(upload)));
+  UploadDataStream stream(&element_readers, 0);
+
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &stream;
+
+  scoped_ptr<SpdyFrame> stream_reply(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> stream_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream_reply, 1),
+    MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 0),
+    CreateMockWrite(*body, 2),
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreatePostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreatePostRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  data.RunFor(2);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
+  data.RunFor(1);
+}
+
+// The client upon cancellation tries to send a RST_STREAM frame. The mock
+// socket causes the TCP write to return zero. This test checks that the client
+// tries to queue up the RST_STREAM frame again.
+TEST_P(SpdyNetworkTransactionSpdy2Test, SocketWriteReturnsZero) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, CANCEL));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0, SYNCHRONOUS),
+    MockWrite(SYNCHRONOUS, 0, 0, 2),
+    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp.get(), 1, ASYNC),
+    MockRead(ASYNC, 0, 0, 4)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  data.SetStop(2);
+  data.Run();
+  helper.ResetTrans();
+  data.SetStop(20);
+  data.Run();
+
+  helper.VerifyDataConsumed();
+}
+
+// Test that the transaction doesn't crash when we don't have a reply.
+TEST_P(SpdyNetworkTransactionSpdy2Test, ResponseWithoutSynReply) {
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads), NULL, 0);
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv);
+}
+
+// Test that the transaction doesn't crash when we get two replies on the same
+// stream ID. See http://crbug.com/45639.
+TEST_P(SpdyNetworkTransactionSpdy2Test, ResponseWithTwoSynReplies) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  std::string response_data;
+  rv = ReadTransaction(trans, &response_data);
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
+
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ResetReplyWithTransferEncoding) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*rst),
+  };
+
+  const char* const headers[] = {
+    "transfer-encoding", "chuncked"
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(headers, 1, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+
+  helper.session()->spdy_session_pool()->CloseAllSessions();
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ResetPushWithTransferEncoding) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*rst),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  const char* const headers[] = {"url", "http://www.google.com/1",
+                                 "transfer-encoding", "chunked"};
+  scoped_ptr<SpdyFrame> push(ConstructSpdyPush(headers, arraysize(headers) / 2,
+                                               2, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*push),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  helper.session()->spdy_session_pool()->CloseAllSessions();
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, CancelledTransaction) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    // This following read isn't used by the test, except during the
+    // RunUntilIdle() call at the end since the SpdySession survives the
+    // HttpNetworkTransaction and still tries to continue Read()'ing.  Any
+    // MockRead will do here.
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  helper.ResetTrans();  // Cancel the transaction.
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+  helper.VerifyDataNotConsumed();
+}
+
+// Verify that the client sends a Rst Frame upon cancelling the stream.
+TEST_P(SpdyNetworkTransactionSpdy2Test, CancelledTransactionSendRst) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, CANCEL));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 0, SYNCHRONOUS),
+    CreateMockWrite(*rst, 2, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 0, 3)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(),
+                                     GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  data.SetStop(2);
+  data.Run();
+  helper.ResetTrans();
+  data.SetStop(20);
+  data.Run();
+
+  helper.VerifyDataConsumed();
+}
+
+// Verify that the client can correctly deal with the user callback attempting
+// to start another transaction on a session that is closing down. See
+// http://crbug.com/47455
+TEST_P(SpdyNetworkTransactionSpdy2Test, StartTransactionOnReadCallback) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+  MockWrite writes2[] = { CreateMockWrite(*req) };
+
+  // The indicated length of this packet is longer than its actual length. When
+  // the session receives an empty packet after this one, it shuts down the
+  // session, and calls the read callback with the incomplete data.
+  const uint8 kGetBodyFrame2[] = {
+    0x00, 0x00, 0x00, 0x01,
+    0x01, 0x00, 0x00, 0x07,
+    'h', 'e', 'l', 'l', 'o', '!',
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+    MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2),
+             arraysize(kGetBodyFrame2), 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
+    MockRead(ASYNC, 0, 0, 6),  // EOF
+  };
+  MockRead reads2[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(ASYNC, 0, 0, 3),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  DelayedSocketData data2(1, reads2, arraysize(reads2),
+                          writes2, arraysize(writes2));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  helper.AddData(&data2);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+
+  const int kSize = 3000;
+  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
+  rv = trans->Read(
+      buf, kSize,
+      base::Bind(&SpdyNetworkTransactionSpdy2Test::StartTransactionCallback,
+                 helper.session()));
+  // This forces an err_IO_pending, which sets the callback.
+  data.CompleteRead();
+  // This finishes the read.
+  data.CompleteRead();
+  helper.VerifyDataConsumed();
+}
+
+// Verify that the client can correctly deal with the user callback deleting the
+// transaction. Failures will usually be valgrind errors. See
+// http://crbug.com/46925
+TEST_P(SpdyNetworkTransactionSpdy2Test, DeleteSessionOnReadCallback) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp.get(), 2),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+    CreateMockRead(*body.get(), 4),
+    MockRead(ASYNC, 0, 0, 5),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+
+  // Setup a user callback which will delete the session, and clear out the
+  // memory holding the stream object. Note that the callback deletes trans.
+  const int kSize = 3000;
+  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
+  rv = trans->Read(
+      buf, kSize,
+      base::Bind(&SpdyNetworkTransactionSpdy2Test::DeleteSessionCallback,
+                 base::Unretained(&helper)));
+  ASSERT_EQ(ERR_IO_PENDING, rv);
+  data.CompleteRead();
+
+  // Finish running rest of tasks.
+  MessageLoop::current()->RunUntilIdle();
+  helper.VerifyDataConsumed();
+}
+
+// Send a spdy request to www.google.com that gets redirected to www.foo.com.
+TEST_P(SpdyNetworkTransactionSpdy2Test, RedirectGetRequest) {
+  // These are headers which the net::URLRequest tacks on.
+  const char* const kExtraHeaders[] = {
+    "accept-encoding",
+    "gzip,deflate",
+  };
+  const SpdyHeaderInfo kSynStartHeader = MakeSpdyHeader(SYN_STREAM);
+  const char* const kStandardGetHeaders[] = {
+    "host",
+    "www.google.com",
+    "method",
+    "GET",
+    "scheme",
+    "http",
+    "url",
+    "/",
+    "user-agent",
+    "",
+    "version",
+    "HTTP/1.1"
+  };
+  const char* const kStandardGetHeaders2[] = {
+    "host",
+    "www.foo.com",
+    "method",
+    "GET",
+    "scheme",
+    "http",
+    "url",
+    "/index.php",
+    "user-agent",
+    "",
+    "version",
+    "HTTP/1.1"
+  };
+
+  // Setup writes/reads to www.google.com
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPacket(
+      kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2,
+      kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyPacket(
+      kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2,
+      kStandardGetHeaders2, arraysize(kStandardGetHeaders2) / 2));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReplyRedirect(1));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(ASYNC, 0, 0, 3)  // EOF
+  };
+
+  // Setup writes/reads to www.foo.com
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes2[] = {
+    CreateMockWrite(*req2, 1),
+  };
+  MockRead reads2[] = {
+    CreateMockRead(*resp2, 2),
+    CreateMockRead(*body2, 3),
+    MockRead(ASYNC, 0, 0, 4)  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data2(reads2, arraysize(reads2),
+                          writes2, arraysize(writes2));
+
+  // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
+  HttpStreamFactory::set_force_spdy_over_ssl(false);
+  HttpStreamFactory::set_force_spdy_always(true);
+  TestDelegate d;
+  {
+    SpdyURLRequestContext spdy_url_request_context;
+    net::URLRequest r(
+        GURL("http://www.google.com/"), &d, &spdy_url_request_context);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data2);
+
+    d.set_quit_on_redirect(true);
+    r.Start();
+    MessageLoop::current()->Run();
+
+    EXPECT_EQ(1, d.received_redirect_count());
+
+    r.FollowDeferredRedirect();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d.response_started_count());
+    EXPECT_FALSE(d.received_data_before_response());
+    EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status());
+    std::string contents("hello!");
+    EXPECT_EQ(contents, d.data_received());
+  }
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+  EXPECT_TRUE(data2.at_read_eof());
+  EXPECT_TRUE(data2.at_write_eof());
+}
+
+// Detect response with upper case headers and reset the stream.
+TEST_P(SpdyNetworkTransactionSpdy2Test, UpperCaseHeaders) {
+  scoped_ptr<SpdyFrame>
+      syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      rst(ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*syn, 0),
+    CreateMockWrite(*rst, 2),
+  };
+
+  const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
+  scoped_ptr<SpdyFrame>
+      reply(ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
+  MockRead reads[] = {
+    CreateMockRead(*reply, 1),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+}
+
+// Detect response with upper case headers in a HEADERS frame and reset the
+// stream.
+TEST_P(SpdyNetworkTransactionSpdy2Test, UpperCaseHeadersInHeadersFrame) {
+  scoped_ptr<SpdyFrame>
+      syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      rst(ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*syn, 0),
+    CreateMockWrite(*rst, 2),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    "status", "200 OK",
+    "version", "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "X-UpperCase", "yes",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+}
+
+// Detect push stream with upper case headers and reset the stream.
+TEST_P(SpdyNetworkTransactionSpdy2Test, UpperCaseHeadersOnPush) {
+  scoped_ptr<SpdyFrame>
+      syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*syn, 0),
+    CreateMockWrite(*rst, 2),
+  };
+
+  scoped_ptr<SpdyFrame>
+      reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  const char* const extra_headers[] = {"X-UpperCase", "yes"};
+  scoped_ptr<SpdyFrame>
+      push(ConstructSpdyPush(extra_headers, 1, 2, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*reply, 1),
+    CreateMockRead(*push, 1),
+    CreateMockRead(*body, 1),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+}
+
+// Send a spdy request to www.google.com. Get a pushed stream that redirects to
+// www.foo.com.
+TEST_P(SpdyNetworkTransactionSpdy2Test, RedirectServerPush) {
+  // These are headers which the net::URLRequest tacks on.
+  const char* const kExtraHeaders[] = {
+    "accept-encoding",
+    "gzip,deflate",
+  };
+  const SpdyHeaderInfo kSynStartHeader = MakeSpdyHeader(SYN_STREAM);
+  const char* const kStandardGetHeaders[] = {
+    "host",
+    "www.google.com",
+    "method",
+    "GET",
+    "scheme",
+    "http",
+    "url",
+    "/",
+    "user-agent",
+    "",
+    "version",
+    "HTTP/1.1"
+  };
+
+  // Setup writes/reads to www.google.com
+  scoped_ptr<SpdyFrame> req(
+      ConstructSpdyPacket(kSynStartHeader,
+                          kExtraHeaders,
+                          arraysize(kExtraHeaders) / 2,
+                          kStandardGetHeaders,
+                          arraysize(kStandardGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> rep(
+      ConstructSpdyPush(NULL,
+                        0,
+                        2,
+                        1,
+                        "http://www.google.com/foo.dat",
+                        "301 Moved Permanently",
+                        "http://www.foo.com/index.php"));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(2, CANCEL));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+    CreateMockWrite(*rst, 6),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    CreateMockRead(*rep, 3),
+    CreateMockRead(*body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
+    MockRead(ASYNC, 0, 0, 7)  // EOF
+  };
+
+  // Setup writes/reads to www.foo.com
+  const char* const kStandardGetHeaders2[] = {
+    "host",
+    "www.foo.com",
+    "method",
+    "GET",
+    "scheme",
+    "http",
+    "url",
+    "/index.php",
+    "user-agent",
+    "",
+    "version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame> req2(
+      ConstructSpdyPacket(kSynStartHeader,
+                          kExtraHeaders,
+                          arraysize(kExtraHeaders) / 2,
+                          kStandardGetHeaders2,
+                          arraysize(kStandardGetHeaders2) / 2));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes2[] = {
+    CreateMockWrite(*req2, 1),
+  };
+  MockRead reads2[] = {
+    CreateMockRead(*resp2, 2),
+    CreateMockRead(*body2, 3),
+    MockRead(ASYNC, 0, 0, 5)  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data2(reads2, arraysize(reads2),
+                          writes2, arraysize(writes2));
+
+  // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
+  HttpStreamFactory::set_force_spdy_over_ssl(false);
+  HttpStreamFactory::set_force_spdy_always(true);
+  TestDelegate d;
+  TestDelegate d2;
+  SpdyURLRequestContext spdy_url_request_context;
+  {
+    net::URLRequest r(
+        GURL("http://www.google.com/"), &d, &spdy_url_request_context);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data);
+
+    r.Start();
+    MessageLoop::current()->Run();
+
+    EXPECT_EQ(0, d.received_redirect_count());
+    std::string contents("hello!");
+    EXPECT_EQ(contents, d.data_received());
+
+    net::URLRequest r2(
+        GURL("http://www.google.com/foo.dat"), &d2, &spdy_url_request_context);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data2);
+
+    d2.set_quit_on_redirect(true);
+    r2.Start();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d2.received_redirect_count());
+
+    r2.FollowDeferredRedirect();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d2.response_started_count());
+    EXPECT_FALSE(d2.received_data_before_response());
+    EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status());
+    std::string contents2("hello!");
+    EXPECT_EQ(contents2, d2.data_received());
+  }
+  data.CompleteRead();
+  data2.CompleteRead();
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+  EXPECT_TRUE(data2.at_read_eof());
+  EXPECT_TRUE(data2.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushSingleDataFrame) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushBeforeSynReply) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_reply, 3),
+    CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushSingleDataFrame2) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushServerAborted) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  scoped_ptr<SpdyFrame>
+    stream2_rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream2_rst, 4),
+    CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushDuplicate) {
+  // Verify that we don't leak streams and that we properly send a reset
+  // if the server pushes the same stream twice.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream3_rst(ConstructSpdyRstStream(4, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream3_rst, 5),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  scoped_ptr<SpdyFrame>
+      stream3_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    4,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream3_syn, 4),
+    CreateMockRead(*stream1_body, 6, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 7),
+    MockRead(ASYNC, ERR_IO_PENDING, 8),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushMultipleDataFrame) {
+  static const unsigned char kPushBodyFrame1[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x1F,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  static const char kPushBodyFrame2[] = " my darling";
+  static const char kPushBodyFrame3[] = " hello";
+  static const char kPushBodyFrame4[] = " my baby";
+
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame1),
+             arraysize(kPushBodyFrame1), 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame2),
+             arraysize(kPushBodyFrame2) - 1, 5),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame3),
+             arraysize(kPushBodyFrame3) - 1, 6),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame4),
+             arraysize(kPushBodyFrame4) - 1, 7),
+    CreateMockRead(*stream1_body, 8, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 9),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed my darling hello my baby");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test,
+       ServerPushMultipleDataFrameInterrupted) {
+  static const unsigned char kPushBodyFrame1[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x1F,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  static const char kPushBodyFrame2[] = " my darling";
+  static const char kPushBodyFrame3[] = " hello";
+  static const char kPushBodyFrame4[] = " my baby";
+
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame1),
+             arraysize(kPushBodyFrame1), 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame2),
+             arraysize(kPushBodyFrame2) - 1, 5),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame3),
+             arraysize(kPushBodyFrame3) - 1, 7),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame4),
+             arraysize(kPushBodyFrame4) - 1, 8),
+    CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 10)  // Force a pause.
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed my darling hello my baby");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushInvalidAssociatedStreamID0) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream2_rst(ConstructSpdyRstStream(2, REFUSED_STREAM));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream2_rst, 4),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    0,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushInvalidAssociatedStreamID9) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream2_rst(ConstructSpdyRstStream(2, INVALID_STREAM));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream2_rst, 4),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    9,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushNoURL) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream2_rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream2_rst, 4),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL, 0, 2, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+// Verify that various SynReply headers parse correctly through the
+// HTTP layer.
+TEST_P(SpdyNetworkTransactionSpdy2Test, SynReplyHeaders) {
+  struct SynReplyHeadersTests {
+    int num_headers;
+    const char* extra_headers[5];
+    const char* expected_headers;
+  } test_cases[] = {
+    // This uses a multi-valued cookie header.
+    { 2,
+      { "cookie", "val1",
+        "cookie", "val2",  // will get appended separated by NULL
+        NULL
+      },
+      "cookie: val1\n"
+      "cookie: val2\n"
+      "hello: bye\n"
+      "status: 200\n"
+      "version: HTTP/1.1\n"
+    },
+    // This is the minimalist set of headers.
+    { 0,
+      { NULL },
+      "hello: bye\n"
+      "status: 200\n"
+      "version: HTTP/1.1\n"
+    },
+    // Headers with a comma separated list.
+    { 1,
+      { "cookie", "val1,val2",
+        NULL
+      },
+      "cookie: val1,val2\n"
+      "hello: bye\n"
+      "status: 200\n"
+      "version: HTTP/1.1\n"
+    }
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    scoped_ptr<SpdyFrame> req(
+        ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+    MockWrite writes[] = { CreateMockWrite(*req) };
+
+    scoped_ptr<SpdyFrame> resp(
+        ConstructSpdyGetSynReply(test_cases[i].extra_headers,
+                                 test_cases[i].num_headers,
+                                 1));
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*resp),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!", out.response_data);
+
+    scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
+    EXPECT_TRUE(headers.get() != NULL);
+    void* iter = NULL;
+    std::string name, value, lines;
+    while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+      lines.append(name);
+      lines.append(": ");
+      lines.append(value);
+      lines.append("\n");
+    }
+    EXPECT_EQ(std::string(test_cases[i].expected_headers), lines);
+  }
+}
+
+// Verify that various SynReply headers parse vary fields correctly
+// through the HTTP layer, and the response matches the request.
+TEST_P(SpdyNetworkTransactionSpdy2Test, SynReplyHeadersVary) {
+  static const SpdyHeaderInfo syn_reply_info = {
+    SYN_REPLY,                              // Syn Reply
+    1,                                      // Stream ID
+    0,                                      // Associated Stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_NONE,                      // Control Flags
+    false,                                  // Compressed
+    INVALID,                                // Status
+    NULL,                                   // Data
+    0,                                      // Data Length
+    DATA_FLAG_NONE                          // Data Flags
+  };
+  // Modify the following data to change/add test cases:
+  struct SynReplyTests {
+    const SpdyHeaderInfo* syn_reply;
+    bool vary_matches;
+    int num_headers[2];
+    const char* extra_headers[2][16];
+  } test_cases[] = {
+    // Test the case of a multi-valued cookie.  When the value is delimited
+    // with NUL characters, it needs to be unfolded into multiple headers.
+    {
+      &syn_reply_info,
+      true,
+      { 1, 4 },
+      { { "cookie",   "val1,val2",
+          NULL
+        },
+        { "vary",     "cookie",
+          "status",   "200",
+          "url",      "/index.php",
+          "version",  "HTTP/1.1",
+          NULL
+        }
+      }
+    }, {    // Multiple vary fields.
+      &syn_reply_info,
+      true,
+      { 2, 5 },
+      { { "friend",   "barney",
+          "enemy",    "snaggletooth",
+          NULL
+        },
+        { "vary",     "friend",
+          "vary",     "enemy",
+          "status",   "200",
+          "url",      "/index.php",
+          "version",  "HTTP/1.1",
+          NULL
+        }
+      }
+    }, {    // Test a '*' vary field.
+      &syn_reply_info,
+      false,
+      { 1, 4 },
+      { { "cookie",   "val1,val2",
+          NULL
+        },
+        { "vary",     "*",
+          "status",   "200",
+          "url",      "/index.php",
+          "version",  "HTTP/1.1",
+          NULL
+        }
+      }
+    }, {    // Multiple comma-separated vary fields.
+      &syn_reply_info,
+      true,
+      { 2, 4 },
+      { { "friend",   "barney",
+          "enemy",    "snaggletooth",
+          NULL
+        },
+        { "vary",     "friend,enemy",
+          "status",   "200",
+          "url",      "/index.php",
+          "version",  "HTTP/1.1",
+          NULL
+        }
+      }
+    }
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    // Construct the request.
+    scoped_ptr<SpdyFrame> frame_req(
+      ConstructSpdyGet(test_cases[i].extra_headers[0],
+                       test_cases[i].num_headers[0],
+                       false, 1, LOWEST));
+
+    MockWrite writes[] = {
+      CreateMockWrite(*frame_req),
+    };
+
+    // Construct the reply.
+    scoped_ptr<SpdyFrame> frame_reply(
+      ConstructSpdyPacket(*test_cases[i].syn_reply,
+                          test_cases[i].extra_headers[1],
+                          test_cases[i].num_headers[1],
+                          NULL,
+                          0));
+
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*frame_reply),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    // Attach the headers to the request.
+    int header_count = test_cases[i].num_headers[0];
+
+    HttpRequestInfo request = CreateGetRequest();
+    for (int ct = 0; ct < header_count; ct++) {
+      const char* header_key = test_cases[i].extra_headers[0][ct * 2];
+      const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1];
+      request.extra_headers.SetHeader(header_key, header_value);
+    }
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(request,
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+
+    EXPECT_EQ(OK, out.rv) << i;
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i;
+    EXPECT_EQ("hello!", out.response_data) << i;
+
+    // Test the response information.
+    EXPECT_TRUE(out.response_info.response_time >
+                out.response_info.request_time) << i;
+    base::TimeDelta test_delay = out.response_info.response_time -
+                                 out.response_info.request_time;
+    base::TimeDelta min_expected_delay;
+    min_expected_delay.FromMilliseconds(10);
+    EXPECT_GT(test_delay.InMillisecondsF(),
+              min_expected_delay.InMillisecondsF()) << i;
+    EXPECT_EQ(out.response_info.vary_data.is_valid(),
+              test_cases[i].vary_matches) << i;
+
+    // Check the headers.
+    scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
+    ASSERT_TRUE(headers.get() != NULL) << i;
+    void* iter = NULL;
+    std::string name, value, lines;
+    while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+      lines.append(name);
+      lines.append(": ");
+      lines.append(value);
+      lines.append("\n");
+    }
+
+    // Construct the expected header reply string.
+    char reply_buffer[256] = "";
+    ConstructSpdyReplyString(test_cases[i].extra_headers[1],
+                             test_cases[i].num_headers[1],
+                             reply_buffer,
+                             256);
+
+    EXPECT_EQ(std::string(reply_buffer), lines) << i;
+  }
+}
+
+// Verify that we don't crash on invalid SynReply responses.
+TEST_P(SpdyNetworkTransactionSpdy2Test, InvalidSynReply) {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_REPLY,              // Kind = SynReply
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_NONE,      // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+
+  struct InvalidSynReplyTests {
+    int num_headers;
+    const char* headers[10];
+  } test_cases[] = {
+    // SYN_REPLY missing status header
+    { 4,
+      { "cookie", "val1",
+        "cookie", "val2",
+        "url", "/index.php",
+        "version", "HTTP/1.1",
+        NULL
+      },
+    },
+    // SYN_REPLY missing version header
+    { 2,
+      { "status", "200",
+        "url", "/index.php",
+        NULL
+      },
+    },
+    // SYN_REPLY with no headers
+    { 0, { NULL }, },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    scoped_ptr<SpdyFrame> req(
+        ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+    MockWrite writes[] = {
+      CreateMockWrite(*req),
+    };
+
+    scoped_ptr<SpdyFrame> resp(
+        ConstructSpdyPacket(kSynStartHeader,
+                            NULL, 0,
+                            test_cases[i].headers,
+                            test_cases[i].num_headers));
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*resp),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+    EXPECT_EQ(ERR_INCOMPLETE_SPDY_HEADERS, out.rv);
+  }
+}
+
+// Verify that we don't crash on some corrupt frames.
+TEST_P(SpdyNetworkTransactionSpdy2Test, CorruptFrameSessionError) {
+  // This is the length field that's too short.
+  scoped_ptr<SpdyFrame> syn_reply_wrong_length(
+      ConstructSpdyGetSynReply(NULL, 0, 1));
+  syn_reply_wrong_length->set_length(syn_reply_wrong_length->length() - 4);
+
+  struct SynReplyTests {
+    const SpdyFrame* syn_reply;
+  } test_cases[] = {
+    { syn_reply_wrong_length.get(), },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    scoped_ptr<SpdyFrame> req(
+        ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+    MockWrite writes[] = {
+      CreateMockWrite(*req),
+      MockWrite(ASYNC, 0, 0)  // EOF
+    };
+
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*test_cases[i].syn_reply),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+    EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+  }
+}
+
+// Test that we shutdown correctly on write errors.
+TEST_P(SpdyNetworkTransactionSpdy2Test, WriteError) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    // We'll write 10 bytes successfully
+    MockWrite(ASYNC, req->data(), 10),
+    // Followed by ERROR!
+    MockWrite(ASYNC, ERR_FAILED),
+  };
+
+  DelayedSocketData data(2, NULL, 0,
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_FAILED, out.rv);
+  data.Reset();
+}
+
+// Test that partial writes work.
+TEST_P(SpdyNetworkTransactionSpdy2Test, PartialWrite) {
+  // Chop the SYN_STREAM frame into 5 chunks.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  const int kChunks = 5;
+  scoped_array<MockWrite> writes(ChopWriteFrame(*req.get(), kChunks));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(kChunks, reads, arraysize(reads),
+                         writes.get(), kChunks);
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// In this test, we enable compression, but get a uncompressed SynReply from
+// the server.  Verify that teardown is all clean.
+TEST_P(SpdyNetworkTransactionSpdy2Test, DecompressFailureOnSynReply) {
+  scoped_ptr<SpdyFrame> compressed(
+      ConstructSpdyGet(NULL, 0, true, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*compressed),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  SpdySessionDependencies* session_deps = new SpdySessionDependencies();
+  session_deps->enable_compression = true;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), session_deps);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+  data.Reset();
+}
+
+// Test that the NetLog contains good data for a simple GET request.
+TEST_P(SpdyNetworkTransactionSpdy2Test, NetLog) {
+  static const char* const kExtraHeaders[] = {
+    "user-agent",   "Chrome",
+  };
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(kExtraHeaders, 1, false, 1,
+                                                   LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  CapturingBoundNetLog log;
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(),
+                                     log.bound(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  // Check that the NetLog was filled reasonably.
+  // This test is intentionally non-specific about the exact ordering of the
+  // log; instead we just check to make sure that certain events exist, and that
+  // they are in the right order.
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_LT(0u, entries.size());
+  int pos = 0;
+  pos = net::ExpectLogContainsSomewhere(entries, 0,
+      net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
+      net::NetLog::PHASE_BEGIN);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
+      net::NetLog::PHASE_END);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
+      net::NetLog::PHASE_BEGIN);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
+      net::NetLog::PHASE_END);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
+      net::NetLog::PHASE_BEGIN);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
+      net::NetLog::PHASE_END);
+
+  // Check that we logged all the headers correctly
+  pos = net::ExpectLogContainsSomewhere(
+      entries, 0,
+      net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
+      net::NetLog::PHASE_NONE);
+
+  ListValue* header_list;
+  ASSERT_TRUE(entries[pos].params.get());
+  ASSERT_TRUE(entries[pos].params->GetList("headers", &header_list));
+
+  std::vector<std::string> expected;
+  expected.push_back("host: www.google.com");
+  expected.push_back("url: /");
+  expected.push_back("scheme: http");
+  expected.push_back("version: HTTP/1.1");
+  expected.push_back("method: GET");
+  expected.push_back("user-agent: Chrome");
+  EXPECT_EQ(expected.size(), header_list->GetSize());
+  for (std::vector<std::string>::const_iterator it = expected.begin();
+       it != expected.end();
+       ++it) {
+    base::StringValue header(*it);
+    EXPECT_NE(header_list->end(), header_list->Find(header)) <<
+        "Header not found: " << *it;
+  }
+}
+
+// Since we buffer the IO from the stream to the renderer, this test verifies
+// that when we read out the maximum amount of data (e.g. we received 50 bytes
+// on the network, but issued a Read for only 5 of those bytes) that the data
+// flow still works correctly.
+TEST_P(SpdyNetworkTransactionSpdy2Test, BufferFull) {
+  BufferedSpdyFramer framer(2, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // 2 data frames in a single read.
+  scoped_ptr<SpdyFrame> data_frame_1(
+      framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE));
+  scoped_ptr<SpdyFrame> data_frame_2(
+      framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE));
+  const SpdyFrame* data_frames[2] = {
+    data_frame_1.get(),
+    data_frame_2.get(),
+  };
+  char combined_data_frames[100];
+  int combined_data_frames_len =
+      CombineFrames(data_frames, arraysize(data_frames),
+                    combined_data_frames, arraysize(combined_data_frames));
+  scoped_ptr<SpdyFrame> last_frame(
+      framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
+    MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
+    CreateMockRead(*last_frame),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  TestCompletionCallback callback;
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 3;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      data.CompleteRead();
+      rv = read_callback.WaitForResult();
+    }
+    if (rv > 0) {
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      NOTREACHED();
+    }
+  } while (rv > 0);
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("goodbye world", out.response_data);
+}
+
+// Verify that basic buffering works; when multiple data frames arrive
+// at the same time, ensure that we don't notify a read completion for
+// each data frame individually.
+TEST_P(SpdyNetworkTransactionSpdy2Test, Buffering) {
+  BufferedSpdyFramer framer(2, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // 4 data frames in a single read.
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+  scoped_ptr<SpdyFrame> data_frame_fin(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
+  const SpdyFrame* data_frames[4] = {
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame_fin.get()
+  };
+  char combined_data_frames[100];
+  int combined_data_frames_len =
+      CombineFrames(data_frames, arraysize(data_frames),
+                    combined_data_frames, arraysize(combined_data_frames));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
+    MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  int reads_completed = 0;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 14;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      data.CompleteRead();
+      rv = read_callback.WaitForResult();
+    }
+    if (rv > 0) {
+      EXPECT_EQ(kSmallReadSize, rv);
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      FAIL() << "Unexpected read error: " << rv;
+    }
+    reads_completed++;
+  } while (rv > 0);
+
+  EXPECT_EQ(3, reads_completed);  // Reads are: 14 bytes, 14 bytes, 0 bytes.
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("messagemessagemessagemessage", out.response_data);
+}
+
+// Verify the case where we buffer data but read it after it has been buffered.
+TEST_P(SpdyNetworkTransactionSpdy2Test, BufferedAll) {
+  BufferedSpdyFramer framer(2, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // 5 data frames in a single read.
+  scoped_ptr<SpdyFrame> syn_reply(
+      ConstructSpdyGetSynReply(NULL, 0, 1));
+  syn_reply->set_flags(CONTROL_FLAG_NONE);  // turn off FIN bit
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+  scoped_ptr<SpdyFrame> data_frame_fin(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
+  const SpdyFrame* frames[5] = {
+    syn_reply.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame_fin.get()
+  };
+  char combined_frames[200];
+  int combined_frames_len =
+      CombineFrames(frames, arraysize(frames),
+                    combined_frames, arraysize(combined_frames));
+
+  MockRead reads[] = {
+    MockRead(ASYNC, combined_frames, combined_frames_len),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  int reads_completed = 0;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 14;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv > 0) {
+      EXPECT_EQ(kSmallReadSize, rv);
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      FAIL() << "Unexpected read error: " << rv;
+    }
+    reads_completed++;
+  } while (rv > 0);
+
+  EXPECT_EQ(3, reads_completed);
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("messagemessagemessagemessage", out.response_data);
+}
+
+// Verify the case where we buffer data and close the connection.
+TEST_P(SpdyNetworkTransactionSpdy2Test, BufferedClosed) {
+  BufferedSpdyFramer framer(2, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // All data frames in a single read.
+  // NOTE: We don't FIN the stream.
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+  const SpdyFrame* data_frames[4] = {
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get()
+  };
+  char combined_data_frames[100];
+  int combined_data_frames_len =
+      CombineFrames(data_frames, arraysize(data_frames),
+                    combined_data_frames, arraysize(combined_data_frames));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
+    MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  int reads_completed = 0;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 14;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      data.CompleteRead();
+      rv = read_callback.WaitForResult();
+    }
+    if (rv > 0) {
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      // This test intentionally closes the connection, and will get an error.
+      EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
+      break;
+    }
+    reads_completed++;
+  } while (rv > 0);
+
+  EXPECT_EQ(0, reads_completed);
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+}
+
+// Verify the case where we buffer data and cancel the transaction.
+TEST_P(SpdyNetworkTransactionSpdy2Test, BufferedCancelled) {
+  BufferedSpdyFramer framer(2, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // NOTE: We don't FIN the stream.
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
+    CreateMockRead(*data_frame),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  do {
+    const int kReadSize = 256;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize));
+    rv = trans->Read(buf, kReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      // Complete the read now, which causes buffering to start.
+      data.CompleteRead();
+      // Destroy the transaction, causing the stream to get cancelled
+      // and orphaning the buffered IO task.
+      helper.ResetTrans();
+      break;
+    }
+    // We shouldn't get here in this test.
+    FAIL() << "Unexpected read: " << rv;
+  } while (rv > 0);
+
+  // Flush the MessageLoop; this will cause the buffered IO task
+  // to run for the final time.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+}
+
+// Test that if the server requests persistence of settings, that we save
+// the settings in the HttpServerProperties.
+TEST_P(SpdyNetworkTransactionSpdy2Test, SettingsSaved) {
+  static const SpdyHeaderInfo kSynReplyInfo = {
+    SYN_REPLY,                              // Syn Reply
+    1,                                      // Stream ID
+    0,                                      // Associated Stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_NONE,                      // Control Flags
+    false,                                  // Compressed
+    INVALID,                                // Status
+    NULL,                                   // Data
+    0,                                      // Data Length
+    DATA_FLAG_NONE                          // Data Flags
+  };
+  static const char* const kExtraHeaders[] = {
+    "status",   "200",
+    "version",  "HTTP/1.1"
+  };
+
+  BoundNetLog net_log;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(), net_log,
+                                     GetParam(), NULL);
+  helper.RunPreTestSetup();
+
+  // Verify that no settings exist initially.
+  HostPortPair host_port_pair("www.google.com", helper.port());
+  SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+  EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
+      host_port_pair).empty());
+
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // Construct the reply.
+  scoped_ptr<SpdyFrame> reply(
+    ConstructSpdyPacket(kSynReplyInfo,
+                        kExtraHeaders,
+                        arraysize(kExtraHeaders) / 2,
+                        NULL,
+                        0));
+
+  const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
+  unsigned int kSampleValue1 = 0x0a0a0a0a;
+  const SpdySettingsIds kSampleId2 = SETTINGS_DOWNLOAD_BANDWIDTH;
+  unsigned int kSampleValue2 = 0x0b0b0b0b;
+  const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME;
+  unsigned int kSampleValue3 = 0x0c0c0c0c;
+  scoped_ptr<SpdyFrame> settings_frame;
+  {
+    // Construct the SETTINGS frame.
+    SettingsMap settings;
+    // First add a persisted setting.
+    settings[kSampleId1] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue1);
+    // Next add a non-persisted setting.
+    settings[kSampleId2] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kSampleValue2);
+    // Next add another persisted setting.
+    settings[kSampleId3] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue3);
+    settings_frame.reset(ConstructSpdySettings(settings));
+  }
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*reply),
+    CreateMockRead(*body),
+    CreateMockRead(*settings_frame),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  helper.AddData(&data);
+  helper.RunDefaultTest();
+  helper.VerifyDataConsumed();
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  {
+    // Verify we had two persisted settings.
+    const SettingsMap& settings_map =
+        spdy_session_pool->http_server_properties()->GetSpdySettings(
+            host_port_pair);
+    ASSERT_EQ(2u, settings_map.size());
+
+    // Verify the first persisted setting.
+    SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
+    EXPECT_TRUE(it1 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value1 = it1->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
+    EXPECT_EQ(kSampleValue1, flags_and_value1.second);
+
+    // Verify the second persisted setting.
+    SettingsMap::const_iterator it3 = settings_map.find(kSampleId3);
+    EXPECT_TRUE(it3 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value3 = it3->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first);
+    EXPECT_EQ(kSampleValue3, flags_and_value3.second);
+  }
+}
+
+// Test that when there are settings saved that they are sent back to the
+// server upon session establishment.
+TEST_P(SpdyNetworkTransactionSpdy2Test, SettingsPlayback) {
+  static const SpdyHeaderInfo kSynReplyInfo = {
+    SYN_REPLY,                              // Syn Reply
+    1,                                      // Stream ID
+    0,                                      // Associated Stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_NONE,                      // Control Flags
+    false,                                  // Compressed
+    INVALID,                                // Status
+    NULL,                                   // Data
+    0,                                      // Data Length
+    DATA_FLAG_NONE                          // Data Flags
+  };
+  static const char* kExtraHeaders[] = {
+    "status",   "200",
+    "version",  "HTTP/1.1"
+  };
+
+  BoundNetLog net_log;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(), net_log,
+                                     GetParam(), NULL);
+  helper.RunPreTestSetup();
+
+  // Verify that no settings exist initially.
+  HostPortPair host_port_pair("www.google.com", helper.port());
+  SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+  EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
+      host_port_pair).empty());
+
+  const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
+  unsigned int kSampleValue1 = 0x0a0a0a0a;
+  const SpdySettingsIds kSampleId2 = SETTINGS_ROUND_TRIP_TIME;
+  unsigned int kSampleValue2 = 0x0c0c0c0c;
+
+  // First add a persisted setting.
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      host_port_pair,
+      kSampleId1,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      kSampleValue1);
+
+  // Next add another persisted setting.
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      host_port_pair,
+      kSampleId2,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      kSampleValue2);
+
+  EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings(
+      host_port_pair).size());
+
+  // Construct the SETTINGS frame.
+  const SettingsMap& settings =
+      spdy_session_pool->http_server_properties()->GetSpdySettings(
+          host_port_pair);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+    CreateMockWrite(*req),
+  };
+
+  // Construct the reply.
+  scoped_ptr<SpdyFrame> reply(
+    ConstructSpdyPacket(kSynReplyInfo,
+                        kExtraHeaders,
+                        arraysize(kExtraHeaders) / 2,
+                        NULL,
+                        0));
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*reply),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  helper.AddData(&data);
+  helper.RunDefaultTest();
+  helper.VerifyDataConsumed();
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  {
+    // Verify we had two persisted settings.
+    const SettingsMap& settings_map =
+        spdy_session_pool->http_server_properties()->GetSpdySettings(
+            host_port_pair);
+    ASSERT_EQ(2u, settings_map.size());
+
+    // Verify the first persisted setting.
+    SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
+    EXPECT_TRUE(it1 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value1 = it1->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
+    EXPECT_EQ(kSampleValue1, flags_and_value1.second);
+
+    // Verify the second persisted setting.
+    SettingsMap::const_iterator it2 = settings_map.find(kSampleId2);
+    EXPECT_TRUE(it2 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value2 = it2->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first);
+    EXPECT_EQ(kSampleValue2, flags_and_value2.second);
+  }
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, GoAwayWithActiveStream) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> go_away(ConstructSpdyGoAway());
+  MockRead reads[] = {
+    CreateMockRead(*go_away),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_ABORTED, out.rv);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, CloseWithActiveStream) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  BoundNetLog log;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     log, GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  TransactionHelperResult out;
+  out.rv = trans->Start(&CreateGetRequest(), callback.callback(), log);
+
+  EXPECT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.rv = ReadTransaction(trans, &out.response_data);
+  EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv);
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+}
+
+// Test to make sure we can correctly connect through a proxy.
+TEST_P(SpdyNetworkTransactionSpdy2Test, ProxyConnect) {
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.session_deps().reset(new SpdySessionDependencies(
+      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")));
+  helper.SetSession(make_scoped_refptr(
+      SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
+  helper.RunPreTestSetup();
+  HttpNetworkTransaction* trans = helper.trans();
+
+  const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+
+  MockWrite writes_SPDYNPN[] = {
+    MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
+    CreateMockWrite(*req, 2),
+  };
+  MockRead reads_SPDYNPN[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*body.get(), 4),
+    MockRead(ASYNC, 0, 0, 5),
+  };
+
+  MockWrite writes_SPDYSSL[] = {
+    MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
+    CreateMockWrite(*req, 2),
+  };
+  MockRead reads_SPDYSSL[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*body.get(), 4),
+    MockRead(ASYNC, 0, 0, 5),
+  };
+
+  MockWrite writes_SPDYNOSSL[] = {
+    CreateMockWrite(*req, 0),
+  };
+
+  MockRead reads_SPDYNOSSL[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body.get(), 2),
+    MockRead(ASYNC, 0, 0, 3),
+  };
+
+  scoped_ptr<OrderedSocketData> data;
+  switch(GetParam()) {
+    case SPDYNOSSL:
+      data.reset(new OrderedSocketData(reads_SPDYNOSSL,
+                                       arraysize(reads_SPDYNOSSL),
+                                       writes_SPDYNOSSL,
+                                       arraysize(writes_SPDYNOSSL)));
+      break;
+    case SPDYSSL:
+      data.reset(new OrderedSocketData(reads_SPDYSSL,
+                                       arraysize(reads_SPDYSSL),
+                                       writes_SPDYSSL,
+                                       arraysize(writes_SPDYSSL)));
+      break;
+    case SPDYNPN:
+      data.reset(new OrderedSocketData(reads_SPDYNPN,
+                                       arraysize(reads_SPDYNPN),
+                                       writes_SPDYNPN,
+                                       arraysize(writes_SPDYNPN)));
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  helper.AddData(data.get());
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  std::string response_data;
+  ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
+  EXPECT_EQ("hello!", response_data);
+  helper.VerifyDataConsumed();
+}
+
+// Test to make sure we can correctly connect through a proxy to www.google.com,
+// if there already exists a direct spdy connection to www.google.com. See
+// http://crbug.com/49874
+TEST_P(SpdyNetworkTransactionSpdy2Test, DirectConnectProxyReconnect) {
+  // When setting up the first transaction, we store the SpdySessionPool so that
+  // we can use the same pool in the second transaction.
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  // Use a proxy service which returns a proxy fallback list from DIRECT to
+  // myproxy:70. For this test there will be no fallback, so it is equivalent
+  // to simply DIRECT. The reason for appending the second proxy is to verify
+  // that the session pool key used does is just "DIRECT".
+  helper.session_deps().reset(new SpdySessionDependencies(
+      ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70")));
+  helper.SetSession(make_scoped_refptr(
+      SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
+
+  SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+  helper.RunPreTestSetup();
+
+  // Construct and send a simple GET request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    CreateMockRead(*body, 3),
+    MockRead(ASYNC, ERR_IO_PENDING, 4),  // Force a pause
+    MockRead(ASYNC, 0, 5)  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  TransactionHelperResult out;
+  out.rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+
+  EXPECT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.rv = ReadTransaction(trans, &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  out.status_line = response->headers->GetStatusLine();
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  // Check that the SpdySession is still in the SpdySessionPool.
+  HostPortPair host_port_pair("www.google.com", helper.port());
+  HostPortProxyPair session_pool_key_direct(
+      host_port_pair, ProxyServer::Direct());
+  EXPECT_TRUE(spdy_session_pool->HasSession(session_pool_key_direct));
+  HostPortProxyPair session_pool_key_proxy(
+      host_port_pair,
+      ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP));
+  EXPECT_FALSE(spdy_session_pool->HasSession(session_pool_key_proxy));
+
+  // Set up data for the proxy connection.
+  const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(
+      "http://www.google.com/foo.dat", false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+
+  MockWrite writes_SPDYNPN[] = {
+    MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
+    CreateMockWrite(*req2, 2),
+  };
+  MockRead reads_SPDYNPN[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp2, 3),
+    CreateMockRead(*body2, 4),
+    MockRead(ASYNC, 0, 5)  // EOF
+  };
+
+  MockWrite writes_SPDYNOSSL[] = {
+    CreateMockWrite(*req2, 0),
+  };
+  MockRead reads_SPDYNOSSL[] = {
+    CreateMockRead(*resp2, 1),
+    CreateMockRead(*body2, 2),
+    MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  MockWrite writes_SPDYSSL[] = {
+    MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
+    CreateMockWrite(*req2, 2),
+  };
+  MockRead reads_SPDYSSL[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp2, 3),
+    CreateMockRead(*body2, 4),
+    MockRead(ASYNC, 0, 0, 5),
+  };
+
+  scoped_ptr<OrderedSocketData> data_proxy;
+  switch(GetParam()) {
+    case SPDYNPN:
+      data_proxy.reset(new OrderedSocketData(reads_SPDYNPN,
+                                             arraysize(reads_SPDYNPN),
+                                             writes_SPDYNPN,
+                                             arraysize(writes_SPDYNPN)));
+      break;
+    case SPDYNOSSL:
+      data_proxy.reset(new OrderedSocketData(reads_SPDYNOSSL,
+                                             arraysize(reads_SPDYNOSSL),
+                                             writes_SPDYNOSSL,
+                                             arraysize(writes_SPDYNOSSL)));
+      break;
+    case SPDYSSL:
+      data_proxy.reset(new OrderedSocketData(reads_SPDYSSL,
+                                             arraysize(reads_SPDYSSL),
+                                             writes_SPDYSSL,
+                                             arraysize(writes_SPDYSSL)));
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  // Create another request to www.google.com, but this time through a proxy.
+  HttpRequestInfo request_proxy;
+  request_proxy.method = "GET";
+  request_proxy.url = GURL("http://www.google.com/foo.dat");
+  request_proxy.load_flags = 0;
+  scoped_ptr<SpdySessionDependencies> ssd_proxy(new SpdySessionDependencies());
+  // Ensure that this transaction uses the same SpdySessionPool.
+  scoped_refptr<HttpNetworkSession> session_proxy(
+      SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get()));
+  NormalSpdyTransactionHelper helper_proxy(request_proxy,
+                                           BoundNetLog(), GetParam(), NULL);
+  HttpNetworkSessionPeer session_peer(session_proxy);
+  scoped_ptr<net::ProxyService> proxy_service(
+          ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+  session_peer.SetProxyService(proxy_service.get());
+  helper_proxy.session_deps().swap(ssd_proxy);
+  helper_proxy.SetSession(session_proxy);
+  helper_proxy.RunPreTestSetup();
+  helper_proxy.AddData(data_proxy.get());
+
+  HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
+  TestCompletionCallback callback_proxy;
+  int rv = trans_proxy->Start(
+      &request_proxy, callback_proxy.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback_proxy.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
+  EXPECT_TRUE(response_proxy.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine());
+
+  std::string response_data;
+  ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data));
+  EXPECT_EQ("hello!", response_data);
+
+  data.CompleteRead();
+  helper_proxy.VerifyDataConsumed();
+}
+
+// When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
+// on a new connection, if the connection was previously known to be good.
+// This can happen when a server reboots without saying goodbye, or when
+// we're behind a NAT that masked the RST.
+TEST_P(SpdyNetworkTransactionSpdy2Test, VerifyRetryOnConnectionReset) {
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, ERR_IO_PENDING),
+    MockRead(ASYNC, ERR_CONNECTION_RESET),
+  };
+
+  MockRead reads2[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  // This test has a couple of variants.
+  enum {
+    // Induce the RST while waiting for our transaction to send.
+    VARIANT_RST_DURING_SEND_COMPLETION,
+    // Induce the RST while waiting for our transaction to read.
+    // In this case, the send completed - everything copied into the SNDBUF.
+    VARIANT_RST_DURING_READ_COMPLETION
+  };
+
+  for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
+       variant <= VARIANT_RST_DURING_READ_COMPLETION;
+       ++variant) {
+    DelayedSocketData data1(1, reads, arraysize(reads), NULL, 0);
+
+    DelayedSocketData data2(1, reads2, arraysize(reads2), NULL, 0);
+
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.AddData(&data1);
+    helper.AddData(&data2);
+    helper.RunPreTestSetup();
+
+    for (int i = 0; i < 2; ++i) {
+      scoped_ptr<HttpNetworkTransaction> trans(
+          new HttpNetworkTransaction(helper.session()));
+
+      TestCompletionCallback callback;
+      int rv = trans->Start(
+          &helper.request(), callback.callback(), BoundNetLog());
+      EXPECT_EQ(ERR_IO_PENDING, rv);
+      // On the second transaction, we trigger the RST.
+      if (i == 1) {
+        if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
+          // Writes to the socket complete asynchronously on SPDY by running
+          // through the message loop.  Complete the write here.
+          MessageLoop::current()->RunUntilIdle();
+        }
+
+        // Now schedule the ERR_CONNECTION_RESET.
+        EXPECT_EQ(3u, data1.read_index());
+        data1.CompleteRead();
+        EXPECT_EQ(4u, data1.read_index());
+      }
+      rv = callback.WaitForResult();
+      EXPECT_EQ(OK, rv);
+
+      const HttpResponseInfo* response = trans->GetResponseInfo();
+      ASSERT_TRUE(response != NULL);
+      EXPECT_TRUE(response->headers != NULL);
+      EXPECT_TRUE(response->was_fetched_via_spdy);
+      std::string response_data;
+      rv = ReadTransaction(trans.get(), &response_data);
+      EXPECT_EQ(OK, rv);
+      EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+      EXPECT_EQ("hello!", response_data);
+    }
+
+    helper.VerifyDataConsumed();
+  }
+}
+
+// Test that turning SPDY on and off works properly.
+TEST_P(SpdyNetworkTransactionSpdy2Test, SpdyOnOffToggle) {
+  net::HttpStreamFactory::set_spdy_enabled(true);
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead spdy_reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, spdy_reads, arraysize(spdy_reads),
+                         spdy_writes, arraysize(spdy_writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  net::HttpStreamFactory::set_spdy_enabled(false);
+  MockRead http_reads[] = {
+    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+    MockRead("hello from http"),
+    MockRead(SYNCHRONOUS, OK),
+  };
+  DelayedSocketData data2(1, http_reads, arraysize(http_reads), NULL, 0);
+  NormalSpdyTransactionHelper helper2(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper2.SetSpdyDisabled();
+  helper2.RunToCompletion(&data2);
+  TransactionHelperResult out2 = helper2.output();
+  EXPECT_EQ(OK, out2.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line);
+  EXPECT_EQ("hello from http", out2.response_data);
+
+  net::HttpStreamFactory::set_spdy_enabled(true);
+}
+
+// Tests that Basic authentication works over SPDY
+TEST_P(SpdyNetworkTransactionSpdy2Test, SpdyBasicAuth) {
+  net::HttpStreamFactory::set_spdy_enabled(true);
+
+  // The first request will be a bare GET, the second request will be a
+  // GET with an Authorization header.
+  scoped_ptr<SpdyFrame> req_get(
+      ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  const char* const kExtraAuthorizationHeaders[] = {
+    "authorization",
+    "Basic Zm9vOmJhcg==",
+  };
+  scoped_ptr<SpdyFrame> req_get_authorization(
+      ConstructSpdyGet(
+          kExtraAuthorizationHeaders,
+          arraysize(kExtraAuthorizationHeaders) / 2,
+          false, 3, LOWEST));
+  MockWrite spdy_writes[] = {
+    CreateMockWrite(*req_get, 1),
+    CreateMockWrite(*req_get_authorization, 4),
+  };
+
+  // The first response is a 401 authentication challenge, and the second
+  // response will be a 200 response since the second request includes a valid
+  // Authorization header.
+  const char* const kExtraAuthenticationHeaders[] = {
+    "www-authenticate",
+    "Basic realm=\"MyRealm\""
+  };
+  scoped_ptr<SpdyFrame> resp_authentication(
+      ConstructSpdySynReplyError(
+          "401 Authentication Required",
+          kExtraAuthenticationHeaders,
+          arraysize(kExtraAuthenticationHeaders) / 2,
+          1));
+  scoped_ptr<SpdyFrame> body_authentication(
+      ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true));
+  MockRead spdy_reads[] = {
+    CreateMockRead(*resp_authentication, 2),
+    CreateMockRead(*body_authentication, 3),
+    CreateMockRead(*resp_data, 5),
+    CreateMockRead(*body_data, 6),
+    MockRead(ASYNC, 0, 7),
+  };
+
+  OrderedSocketData data(spdy_reads, arraysize(spdy_reads),
+                         spdy_writes, arraysize(spdy_writes));
+  HttpRequestInfo request(CreateGetRequest());
+  BoundNetLog net_log;
+  NormalSpdyTransactionHelper helper(request, net_log, GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+  TestCompletionCallback callback;
+  const int rv_start = trans->Start(&request, callback.callback(), net_log);
+  EXPECT_EQ(ERR_IO_PENDING, rv_start);
+  const int rv_start_complete = callback.WaitForResult();
+  EXPECT_EQ(OK, rv_start_complete);
+
+  // Make sure the response has an auth challenge.
+  const HttpResponseInfo* const response_start = trans->GetResponseInfo();
+  ASSERT_TRUE(response_start != NULL);
+  ASSERT_TRUE(response_start->headers != NULL);
+  EXPECT_EQ(401, response_start->headers->response_code());
+  EXPECT_TRUE(response_start->was_fetched_via_spdy);
+  AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get();
+  ASSERT_TRUE(auth_challenge != NULL);
+  EXPECT_FALSE(auth_challenge->is_proxy);
+  EXPECT_EQ("basic", auth_challenge->scheme);
+  EXPECT_EQ("MyRealm", auth_challenge->realm);
+
+  // Restart with a username/password.
+  AuthCredentials credentials(ASCIIToUTF16("foo"), ASCIIToUTF16("bar"));
+  TestCompletionCallback callback_restart;
+  const int rv_restart = trans->RestartWithAuth(
+      credentials, callback_restart.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv_restart);
+  const int rv_restart_complete = callback_restart.WaitForResult();
+  EXPECT_EQ(OK, rv_restart_complete);
+  // TODO(cbentzel): This is actually the same response object as before, but
+  // data has changed.
+  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
+  ASSERT_TRUE(response_restart != NULL);
+  ASSERT_TRUE(response_restart->headers != NULL);
+  EXPECT_EQ(200, response_restart->headers->response_code());
+  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushWithHeaders) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    "url",
+    "http://www.google.com/foo.dat",
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+    "status",
+    "200",
+    "version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame>
+    stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                          arraysize(kInitialHeaders) / 2,
+                                          false,
+                                          2,
+                                          LOWEST,
+                                          SYN_STREAM,
+                                          CONTROL_FLAG_NONE,
+                                          NULL,
+                                          0,
+                                          1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                2,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream2_headers, 4),
+    CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 6),
+    MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushClaimBeforeHeaders) {
+  // We push a stream and attempt to claim it before the headers come down.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    "url",
+    "http://www.google.com/foo.dat",
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+    "status",
+    "200",
+    "version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                            arraysize(kInitialHeaders) / 2,
+                                            false,
+                                            2,
+                                            LOWEST,
+                                            SYN_STREAM,
+                                            CONTROL_FLAG_NONE,
+                                            NULL,
+                                            0,
+                                            1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                2,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 1),
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_body, 3),
+    CreateMockRead(*stream2_headers, 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, 0, 6),  // EOF
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.AddDeterministicData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+  // and the body of the primary stream, but before we've received the HEADERS
+  // for the pushed stream.
+  data.SetStop(3);
+
+  // Start the transaction.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.Run();
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Request the pushed path.  At this point, we've received the push, but the
+  // headers are not yet complete.
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(
+      &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.RunFor(3);
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read the server push body.
+  std::string result2;
+  ReadResult(trans2.get(), &data, &result2);
+  // Read the response body.
+  std::string result;
+  ReadResult(trans, &data, &result);
+
+  // Verify that the received push data is same as the expected push data.
+  EXPECT_EQ(result2.compare(expected_push_result), 0)
+      << "Received data: "
+      << result2
+      << "||||| Expected data: "
+      << expected_push_result;
+
+  // Verify the SYN_REPLY.
+  // Copy the response info, because trans goes away.
+  response = *trans->GetResponseInfo();
+  response2 = *trans2->GetResponseInfo();
+
+  VerifyStreamsClosed(helper);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+
+  // Read the final EOF (which will close the session)
+  data.RunFor(1);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushWithTwoHeaderFrames) {
+  // We push a stream and attempt to claim it before the headers come down.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    "url",
+    "http://www.google.com/foo.dat",
+  };
+  static const char* const kMiddleHeaders[] = {
+    "hello",
+    "bye",
+  };
+  static const char* const kLateHeaders[] = {
+    "status",
+    "200",
+    "version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                            arraysize(kInitialHeaders) / 2,
+                                            false,
+                                            2,
+                                            LOWEST,
+                                            SYN_STREAM,
+                                            CONTROL_FLAG_NONE,
+                                            NULL,
+                                            0,
+                                            1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders,
+                                                 arraysize(kMiddleHeaders) / 2,
+                                                 false,
+                                                 2,
+                                                 LOWEST,
+                                                 HEADERS,
+                                                 CONTROL_FLAG_NONE,
+                                                 NULL,
+                                                 0,
+                                                 0));
+  scoped_ptr<SpdyFrame>
+      stream2_headers2(ConstructSpdyControlFrame(kLateHeaders,
+                                                 arraysize(kLateHeaders) / 2,
+                                                 false,
+                                                 2,
+                                                 LOWEST,
+                                                 HEADERS,
+                                                 CONTROL_FLAG_NONE,
+                                                 NULL,
+                                                 0,
+                                                 0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 1),
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_body, 3),
+    CreateMockRead(*stream2_headers1, 4),
+    CreateMockRead(*stream2_headers2, 5),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 6),
+    MockRead(ASYNC, 0, 7),  // EOF
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.AddDeterministicData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+  // the first HEADERS frame, and the body of the primary stream, but before
+  // we've received the final HEADERS for the pushed stream.
+  data.SetStop(4);
+
+  // Start the transaction.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.Run();
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Request the pushed path.  At this point, we've received the push, but the
+  // headers are not yet complete.
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(
+      &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.RunFor(3);
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read the server push body.
+  std::string result2;
+  ReadResult(trans2.get(), &data, &result2);
+  // Read the response body.
+  std::string result;
+  ReadResult(trans, &data, &result);
+
+  // Verify that the received push data is same as the expected push data.
+  EXPECT_EQ(result2.compare(expected_push_result), 0)
+      << "Received data: "
+      << result2
+      << "||||| Expected data: "
+      << expected_push_result;
+
+  // Verify the SYN_REPLY.
+  // Copy the response info, because trans goes away.
+  response = *trans->GetResponseInfo();
+  response2 = *trans2->GetResponseInfo();
+
+  VerifyStreamsClosed(helper);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+
+  // Verify we got all the headers
+  EXPECT_TRUE(response2.headers->HasHeaderValue(
+      "url",
+      "http://www.google.com/foo.dat"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
+
+  // Read the final EOF (which will close the session)
+  data.RunFor(1);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushWithNoStatusHeaderFrames) {
+  // We push a stream and attempt to claim it before the headers come down.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    "url",
+    "http://www.google.com/foo.dat",
+  };
+  static const char* const kMiddleHeaders[] = {
+    "hello",
+    "bye",
+  };
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                            arraysize(kInitialHeaders) / 2,
+                                            false,
+                                            2,
+                                            LOWEST,
+                                            SYN_STREAM,
+                                            CONTROL_FLAG_NONE,
+                                            NULL,
+                                            0,
+                                            1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders,
+                                                 arraysize(kMiddleHeaders) / 2,
+                                                 false,
+                                                 2,
+                                                 LOWEST,
+                                                 HEADERS,
+                                                 CONTROL_FLAG_NONE,
+                                                 NULL,
+                                                 0,
+                                                 0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 1),
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_body, 3),
+    CreateMockRead(*stream2_headers1, 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, 0, 6),  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.AddDeterministicData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+  // the first HEADERS frame, and the body of the primary stream, but before
+  // we've received the final HEADERS for the pushed stream.
+  data.SetStop(4);
+
+  // Start the transaction.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.Run();
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Request the pushed path.  At this point, we've received the push, but the
+  // headers are not yet complete.
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(
+      &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.RunFor(2);
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read the server push body.
+  std::string result2;
+  ReadResult(trans2.get(), &data, &result2);
+  // Read the response body.
+  std::string result;
+  ReadResult(trans, &data, &result);
+  EXPECT_EQ("hello!", result);
+
+  // Verify that we haven't received any push data.
+  EXPECT_EQ("", result2);
+
+  // Verify the SYN_REPLY.
+  // Copy the response info, because trans goes away.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  ASSERT_TRUE(trans2->GetResponseInfo() == NULL);
+
+  VerifyStreamsClosed(helper);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Read the final EOF (which will close the session).
+  data.RunFor(1);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, SynReplyWithHeaders) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  static const char* const kInitialHeaders[] = {
+    "status",
+    "200 OK",
+    "version",
+    "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, SynReplyWithLateHeaders) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  static const char* const kInitialHeaders[] = {
+    "status",
+    "200 OK",
+    "version",
+    "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_body),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body2),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, SynReplyWithDuplicateLateHeaders) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  static const char* const kInitialHeaders[] = {
+    "status",
+    "200 OK",
+    "version",
+    "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "status",
+    "500 Server Error",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_body),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body2),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushCrossOriginCorrectness) {
+  // In this test we want to verify that we can't accidentally push content
+  // which can't be pushed by this content server.
+  // This test assumes that:
+  //   - if we're requesting http://www.foo.com/barbaz
+  //   - the browser has made a connection to "www.foo.com".
+
+  // A list of the URL to fetch, followed by the URL being pushed.
+  static const char* const kTestCases[] = {
+    "http://www.google.com/foo.html",
+    "http://www.google.com:81/foo.js",     // Bad port
+
+    "http://www.google.com/foo.html",
+    "https://www.google.com/foo.js",       // Bad protocol
+
+    "http://www.google.com/foo.html",
+    "ftp://www.google.com/foo.js",         // Invalid Protocol
+
+    "http://www.google.com/foo.html",
+    "http://blat.www.google.com/foo.js",   // Cross subdomain
+
+    "http://www.google.com/foo.html",
+    "http://www.foo.com/foo.js",           // Cross domain
+  };
+
+
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+
+  for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
+    const char* url_to_fetch = kTestCases[index];
+    const char* url_to_push = kTestCases[index + 1];
+
+    scoped_ptr<SpdyFrame>
+        stream1_syn(ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
+    scoped_ptr<SpdyFrame>
+        stream1_body(ConstructSpdyBodyFrame(1, true));
+    scoped_ptr<SpdyFrame> push_rst(
+        ConstructSpdyRstStream(2, REFUSED_STREAM));
+    MockWrite writes[] = {
+      CreateMockWrite(*stream1_syn, 1),
+      CreateMockWrite(*push_rst, 4),
+    };
+
+    scoped_ptr<SpdyFrame>
+        stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+    scoped_ptr<SpdyFrame>
+        stream2_syn(ConstructSpdyPush(NULL,
+                                      0,
+                                      2,
+                                      1,
+                                      url_to_push));
+    scoped_ptr<SpdyFrame> rst(
+        ConstructSpdyRstStream(2, CANCEL));
+
+    MockRead reads[] = {
+      CreateMockRead(*stream1_reply, 2),
+      CreateMockRead(*stream2_syn, 3),
+      CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
+      MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+               arraysize(kPushBodyFrame), 6),
+      MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
+    };
+
+    HttpResponseInfo response;
+    OrderedSocketData data(reads, arraysize(reads),
+                           writes, arraysize(writes));
+
+    HttpRequestInfo request;
+    request.method = "GET";
+    request.url = GURL(url_to_fetch);
+    request.load_flags = 0;
+
+    // Enable cross-origin push. Since we are not using a proxy, this should
+    // not actually enable cross-origin SPDY push.
+    scoped_ptr<SpdySessionDependencies> session_deps(
+        new SpdySessionDependencies());
+    session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
+    NormalSpdyTransactionHelper helper(request,
+                                       BoundNetLog(), GetParam(),
+                                       session_deps.release());
+    helper.RunPreTestSetup();
+    helper.AddData(&data);
+
+    HttpNetworkTransaction* trans = helper.trans();
+
+    // Start the transaction with basic parameters.
+    TestCompletionCallback callback;
+
+    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    rv = callback.WaitForResult();
+
+    // Read the response body.
+    std::string result;
+    ReadResult(trans, &data, &result);
+
+    // Verify that we consumed all test data.
+    EXPECT_TRUE(data.at_read_eof());
+    EXPECT_TRUE(data.at_write_eof());
+
+    // Verify the SYN_REPLY.
+    // Copy the response info, because trans goes away.
+    response = *trans->GetResponseInfo();
+
+    VerifyStreamsClosed(helper);
+
+    // Verify the SYN_REPLY.
+    EXPECT_TRUE(response.headers != NULL);
+    EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+  }
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, RetryAfterRefused) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+    CreateMockWrite(*req2, 3),
+  };
+
+  scoped_ptr<SpdyFrame> refused(
+      ConstructSpdyRstStream(1, REFUSED_STREAM));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(3, true));
+  MockRead reads[] = {
+    CreateMockRead(*refused, 2),
+    CreateMockRead(*resp, 4),
+    CreateMockRead(*body, 5),
+    MockRead(ASYNC, 0, 6)  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy2Test, OutOfOrderSynStream) {
+  // This first request will start to establish the SpdySession.
+  // Then we will start the second (MEDIUM priority) and then third
+  // (HIGHEST priority) request in such a way that the third will actually
+  // start before the second, causing the second to be numbered differently
+  // than the order they were created.
+  scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, HIGHEST));
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, MEDIUM));
+  MockWrite writes[] = {
+    CreateMockWrite(*req1, 0),
+    CreateMockWrite(*req2, 3),
+    CreateMockWrite(*req3, 4),
+  };
+
+  scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp1, 1),
+    CreateMockRead(*body1, 2),
+    CreateMockRead(*resp2, 5),
+    CreateMockRead(*body2, 6),
+    CreateMockRead(*resp3, 7),
+    CreateMockRead(*body3, 8),
+    MockRead(ASYNC, 0, 9)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+
+  // Start the first transaction to set up the SpdySession
+  HttpNetworkTransaction* trans = helper.trans();
+  TestCompletionCallback callback;
+  HttpRequestInfo info1 = CreateGetRequest();
+  info1.priority = LOWEST;
+  int rv = trans->Start(&info1, callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Run the message loop, but do not allow the write to complete.
+  // This leaves the SpdySession with a write pending, which prevents
+  // SpdySession from attempting subsequent writes until this write completes.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Now, start both new transactions
+  HttpRequestInfo info2 = CreateGetRequest();
+  info2.priority = MEDIUM;
+  TestCompletionCallback callback2;
+    scoped_ptr<HttpNetworkTransaction> trans2(
+        new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  MessageLoop::current()->RunUntilIdle();
+
+  HttpRequestInfo info3 = CreateGetRequest();
+  info3.priority = HIGHEST;
+  TestCompletionCallback callback3;
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  MessageLoop::current()->RunUntilIdle();
+
+  // We now have two SYN_STREAM frames queued up which will be
+  // dequeued only once the first write completes, which we
+  // now allow to happen.
+  data.RunFor(2);
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  // And now we can allow everything else to run to completion.
+  data.SetStop(10);
+  data.Run();
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ(OK, callback3.WaitForResult());
+
+  helper.VerifyDataConsumed();
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_network_transaction_spdy3_unittest.cc b/src/net/spdy/spdy_network_transaction_spdy3_unittest.cc
new file mode 100644
index 0000000..197ba7d
--- /dev/null
+++ b/src/net/spdy/spdy_network_transaction_spdy3_unittest.cc
@@ -0,0 +1,6364 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/http_network_transaction.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_vector.h"
+#include "net/base/auth.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/upload_bytes_element_reader.h"
+#include "net/base/upload_data_stream.h"
+#include "net/base/upload_file_element_reader.h"
+#include "net/http/http_network_session_peer.h"
+#include "net/http/http_transaction_unittest.h"
+#include "net/socket/client_socket_pool_base.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_stream.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy3;
+
+//-----------------------------------------------------------------------------
+
+namespace net {
+
+enum SpdyNetworkTransactionSpdy3TestTypes {
+  SPDYNPN,
+  SPDYNOSSL,
+  SPDYSSL,
+};
+
+class SpdyNetworkTransactionSpdy3Test
+    : public ::testing::TestWithParam<SpdyNetworkTransactionSpdy3TestTypes> {
+ protected:
+
+  virtual void SetUp() {
+    google_get_request_initialized_ = false;
+    google_post_request_initialized_ = false;
+    google_chunked_post_request_initialized_ = false;
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+  }
+
+  virtual void TearDown() {
+    UploadDataStream::ResetMergeChunks();
+    // Empty the current queue.
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void set_merge_chunks(bool merge) {
+    UploadDataStream::set_merge_chunks(merge);
+  }
+
+  struct TransactionHelperResult {
+    int rv;
+    std::string status_line;
+    std::string response_data;
+    HttpResponseInfo response_info;
+  };
+
+  // A helper class that handles all the initial npn/ssl setup.
+  class NormalSpdyTransactionHelper {
+   public:
+    NormalSpdyTransactionHelper(const HttpRequestInfo& request,
+                                const BoundNetLog& log,
+                                SpdyNetworkTransactionSpdy3TestTypes test_type,
+                                SpdySessionDependencies* session_deps)
+        : request_(request),
+          session_deps_(session_deps == NULL ?
+                        new SpdySessionDependencies() : session_deps),
+          session_(SpdySessionDependencies::SpdyCreateSession(
+                       session_deps_.get())),
+          log_(log),
+          test_type_(test_type),
+          deterministic_(false),
+          spdy_enabled_(true) {
+      switch (test_type_) {
+        case SPDYNOSSL:
+        case SPDYSSL:
+          port_ = 80;
+          break;
+        case SPDYNPN:
+          port_ = 443;
+          break;
+        default:
+          NOTREACHED();
+      }
+    }
+
+    ~NormalSpdyTransactionHelper() {
+      // Any test which doesn't close the socket by sending it an EOF will
+      // have a valid session left open, which leaks the entire session pool.
+      // This is just fine - in fact, some of our tests intentionally do this
+      // so that we can check consistency of the SpdySessionPool as the test
+      // finishes.  If we had put an EOF on the socket, the SpdySession would
+      // have closed and we wouldn't be able to check the consistency.
+
+      // Forcefully close existing sessions here.
+      session()->spdy_session_pool()->CloseAllSessions();
+    }
+
+    void SetDeterministic() {
+      session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+          session_deps_.get());
+      deterministic_ = true;
+    }
+
+    void SetSpdyDisabled() {
+      spdy_enabled_ = false;
+      port_ = 80;
+    }
+
+    void RunPreTestSetup() {
+      if (!session_deps_.get())
+        session_deps_.reset(new SpdySessionDependencies());
+      if (!session_.get())
+        session_ = SpdySessionDependencies::SpdyCreateSession(
+            session_deps_.get());
+      HttpStreamFactory::set_use_alternate_protocols(false);
+      HttpStreamFactory::set_force_spdy_over_ssl(false);
+      HttpStreamFactory::set_force_spdy_always(false);
+
+      std::vector<std::string> next_protos;
+      next_protos.push_back("http/1.1");
+      next_protos.push_back("spdy/2");
+      next_protos.push_back("spdy/3");
+
+      switch (test_type_) {
+        case SPDYNPN:
+          session_->http_server_properties()->SetAlternateProtocol(
+              HostPortPair("www.google.com", 80), 443,
+              NPN_SPDY_3);
+          HttpStreamFactory::set_use_alternate_protocols(true);
+          HttpStreamFactory::SetNextProtos(next_protos);
+          break;
+        case SPDYNOSSL:
+          HttpStreamFactory::set_force_spdy_over_ssl(false);
+          HttpStreamFactory::set_force_spdy_always(true);
+          break;
+        case SPDYSSL:
+          HttpStreamFactory::set_force_spdy_over_ssl(true);
+          HttpStreamFactory::set_force_spdy_always(true);
+          break;
+        default:
+          NOTREACHED();
+      }
+
+      // We're now ready to use SSL-npn SPDY.
+      trans_.reset(new HttpNetworkTransaction(session_));
+    }
+
+    // Start the transaction, read some data, finish.
+    void RunDefaultTest() {
+      output_.rv = trans_->Start(&request_, callback.callback(), log_);
+
+      // We expect an IO Pending or some sort of error.
+      EXPECT_LT(output_.rv, 0);
+      if (output_.rv != ERR_IO_PENDING)
+        return;
+
+      output_.rv = callback.WaitForResult();
+      if (output_.rv != OK) {
+        session_->spdy_session_pool()->CloseCurrentSessions(net::ERR_ABORTED);
+        return;
+      }
+
+      // Verify responses.
+      const HttpResponseInfo* response = trans_->GetResponseInfo();
+      ASSERT_TRUE(response != NULL);
+      ASSERT_TRUE(response->headers != NULL);
+      EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+      EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy);
+      if (test_type_ == SPDYNPN && spdy_enabled_) {
+        EXPECT_TRUE(response->was_npn_negotiated);
+      } else {
+        EXPECT_TRUE(!response->was_npn_negotiated);
+      }
+      // If SPDY is not enabled, a HTTP request should not be diverted
+      // over a SSL session.
+      if (!spdy_enabled_) {
+        EXPECT_EQ(request_.url.SchemeIs("https"),
+                  response->was_npn_negotiated);
+      }
+      EXPECT_EQ("127.0.0.1", response->socket_address.host());
+      EXPECT_EQ(port_, response->socket_address.port());
+      output_.status_line = response->headers->GetStatusLine();
+      output_.response_info = *response;  // Make a copy so we can verify.
+      output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
+    }
+
+    // Most tests will want to call this function. In particular, the MockReads
+    // should end with an empty read, and that read needs to be processed to
+    // ensure proper deletion of the spdy_session_pool.
+    void VerifyDataConsumed() {
+      for (DataVector::iterator it = data_vector_.begin();
+          it != data_vector_.end(); ++it) {
+        EXPECT_TRUE((*it)->at_read_eof()) << "Read count: "
+                                          << (*it)->read_count()
+                                          << " Read index: "
+                                          << (*it)->read_index();
+        EXPECT_TRUE((*it)->at_write_eof()) << "Write count: "
+                                           << (*it)->write_count()
+                                           << " Write index: "
+                                           << (*it)->write_index();
+      }
+    }
+
+    // Occasionally a test will expect to error out before certain reads are
+    // processed. In that case we want to explicitly ensure that the reads were
+    // not processed.
+    void VerifyDataNotConsumed() {
+      for (DataVector::iterator it = data_vector_.begin();
+          it != data_vector_.end(); ++it) {
+        EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: "
+                                           << (*it)->read_count()
+                                           << " Read index: "
+                                           << (*it)->read_index();
+        EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: "
+                                            << (*it)->write_count()
+                                            << " Write index: "
+                                            << (*it)->write_index();
+      }
+    }
+
+    void RunToCompletion(StaticSocketDataProvider* data) {
+      RunPreTestSetup();
+      AddData(data);
+      RunDefaultTest();
+      VerifyDataConsumed();
+    }
+
+    void AddData(StaticSocketDataProvider* data) {
+      DCHECK(!deterministic_);
+      data_vector_.push_back(data);
+      SSLSocketDataProvider* ssl_provider =
+          new SSLSocketDataProvider(ASYNC, OK);
+      if (test_type_ == SPDYNPN)
+        ssl_provider->SetNextProto(kProtoSPDY3);
+
+      ssl_vector_.push_back(ssl_provider);
+      if (test_type_ == SPDYNPN || test_type_ == SPDYSSL)
+        session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_provider);
+
+      session_deps_->socket_factory->AddSocketDataProvider(data);
+      if (test_type_ == SPDYNPN) {
+        MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
+        StaticSocketDataProvider* hanging_non_alternate_protocol_socket =
+                new StaticSocketDataProvider(NULL, 0, NULL, 0);
+        hanging_non_alternate_protocol_socket->set_connect_data(
+            never_finishing_connect);
+        session_deps_->socket_factory->AddSocketDataProvider(
+            hanging_non_alternate_protocol_socket);
+        alternate_vector_.push_back(hanging_non_alternate_protocol_socket);
+      }
+    }
+
+    void AddDeterministicData(DeterministicSocketData* data) {
+      DCHECK(deterministic_);
+      data_vector_.push_back(data);
+      SSLSocketDataProvider* ssl_provider =
+          new SSLSocketDataProvider(ASYNC, OK);
+      if (test_type_ == SPDYNPN)
+        ssl_provider->SetNextProto(kProtoSPDY3);
+
+      ssl_vector_.push_back(ssl_provider);
+      if (test_type_ == SPDYNPN || test_type_ == SPDYSSL) {
+        session_deps_->deterministic_socket_factory->
+            AddSSLSocketDataProvider(ssl_provider);
+      }
+      session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
+      if (test_type_ == SPDYNPN) {
+        MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
+        DeterministicSocketData* hanging_non_alternate_protocol_socket =
+            new DeterministicSocketData(NULL, 0, NULL, 0);
+        hanging_non_alternate_protocol_socket->set_connect_data(
+            never_finishing_connect);
+        session_deps_->deterministic_socket_factory->AddSocketDataProvider(
+            hanging_non_alternate_protocol_socket);
+        alternate_deterministic_vector_.push_back(
+            hanging_non_alternate_protocol_socket);
+      }
+    }
+
+    void SetSession(const scoped_refptr<HttpNetworkSession>& session) {
+      session_ = session;
+    }
+    HttpNetworkTransaction* trans() { return trans_.get(); }
+    void ResetTrans() { trans_.reset(); }
+    TransactionHelperResult& output() { return output_; }
+    const HttpRequestInfo& request() const { return request_; }
+    const scoped_refptr<HttpNetworkSession>& session() const {
+      return session_;
+    }
+    scoped_ptr<SpdySessionDependencies>& session_deps() {
+      return session_deps_;
+    }
+    int port() const { return port_; }
+    SpdyNetworkTransactionSpdy3TestTypes test_type() const {
+      return test_type_;
+    }
+
+   private:
+    typedef std::vector<StaticSocketDataProvider*> DataVector;
+    typedef ScopedVector<SSLSocketDataProvider> SSLVector;
+    typedef ScopedVector<StaticSocketDataProvider> AlternateVector;
+    typedef ScopedVector<DeterministicSocketData> AlternateDeterministicVector;
+    HttpRequestInfo request_;
+    scoped_ptr<SpdySessionDependencies> session_deps_;
+    scoped_refptr<HttpNetworkSession> session_;
+    TransactionHelperResult output_;
+    scoped_ptr<StaticSocketDataProvider> first_transaction_;
+    SSLVector ssl_vector_;
+    TestCompletionCallback callback;
+    scoped_ptr<HttpNetworkTransaction> trans_;
+    scoped_ptr<HttpNetworkTransaction> trans_http_;
+    DataVector data_vector_;
+    AlternateVector alternate_vector_;
+    AlternateDeterministicVector alternate_deterministic_vector_;
+    const BoundNetLog& log_;
+    SpdyNetworkTransactionSpdy3TestTypes test_type_;
+    int port_;
+    bool deterministic_;
+    bool spdy_enabled_;
+  };
+
+  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
+                                             int expected_status);
+
+  void ConnectStatusHelper(const MockRead& status);
+
+  const HttpRequestInfo& CreateGetPushRequest() {
+    google_get_push_request_.method = "GET";
+    google_get_push_request_.url = GURL("http://www.google.com/foo.dat");
+    google_get_push_request_.load_flags = 0;
+    return google_get_push_request_;
+  }
+
+  const HttpRequestInfo& CreateGetRequest() {
+    if (!google_get_request_initialized_) {
+      google_get_request_.method = "GET";
+      google_get_request_.url = GURL(kDefaultURL);
+      google_get_request_.load_flags = 0;
+      google_get_request_initialized_ = true;
+    }
+    return google_get_request_;
+  }
+
+  const HttpRequestInfo& CreateGetRequestWithUserAgent() {
+    if (!google_get_request_initialized_) {
+      google_get_request_.method = "GET";
+      google_get_request_.url = GURL(kDefaultURL);
+      google_get_request_.load_flags = 0;
+      google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
+      google_get_request_initialized_ = true;
+    }
+    return google_get_request_;
+  }
+
+  const HttpRequestInfo& CreatePostRequest() {
+    if (!google_post_request_initialized_) {
+      ScopedVector<UploadElementReader> element_readers;
+      element_readers.push_back(
+          new UploadBytesElementReader(kUploadData, kUploadDataSize));
+      upload_data_stream_.reset(new UploadDataStream(&element_readers, 0));
+
+      google_post_request_.method = "POST";
+      google_post_request_.url = GURL(kDefaultURL);
+      google_post_request_.upload_data_stream = upload_data_stream_.get();
+      google_post_request_initialized_ = true;
+    }
+    return google_post_request_;
+  }
+
+  const HttpRequestInfo& CreateFilePostRequest() {
+    if (!google_post_request_initialized_) {
+      FilePath file_path;
+      CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
+      CHECK_EQ(static_cast<int>(kUploadDataSize),
+               file_util::WriteFile(file_path, kUploadData, kUploadDataSize));
+
+      ScopedVector<UploadElementReader> element_readers;
+      element_readers.push_back(new UploadFileElementReader(
+          file_path, 0, kUploadDataSize, base::Time()));
+      upload_data_stream_.reset(new UploadDataStream(&element_readers, 0));
+
+      google_post_request_.method = "POST";
+      google_post_request_.url = GURL(kDefaultURL);
+      google_post_request_.upload_data_stream = upload_data_stream_.get();
+      google_post_request_initialized_ = true;
+    }
+    return google_post_request_;
+  }
+
+  const HttpRequestInfo& CreateComplexPostRequest() {
+    if (!google_post_request_initialized_) {
+      const int kFileRangeOffset = 1;
+      const int kFileRangeLength = 3;
+      CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
+
+      FilePath file_path;
+      CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
+      CHECK_EQ(static_cast<int>(kUploadDataSize),
+               file_util::WriteFile(file_path, kUploadData, kUploadDataSize));
+
+      ScopedVector<UploadElementReader> element_readers;
+      element_readers.push_back(
+          new UploadBytesElementReader(kUploadData, kFileRangeOffset));
+      element_readers.push_back(new UploadFileElementReader(
+          file_path, kFileRangeOffset, kFileRangeLength, base::Time()));
+      element_readers.push_back(new UploadBytesElementReader(
+          kUploadData + kFileRangeOffset + kFileRangeLength,
+          kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
+      upload_data_stream_.reset(new UploadDataStream(&element_readers, 0));
+
+      google_post_request_.method = "POST";
+      google_post_request_.url = GURL(kDefaultURL);
+      google_post_request_.upload_data_stream = upload_data_stream_.get();
+      google_post_request_initialized_ = true;
+    }
+    return google_post_request_;
+  }
+
+  const HttpRequestInfo& CreateChunkedPostRequest() {
+    if (!google_chunked_post_request_initialized_) {
+      upload_data_stream_.reset(
+          new UploadDataStream(UploadDataStream::CHUNKED, 0));
+      upload_data_stream_->AppendChunk(kUploadData, kUploadDataSize, false);
+      upload_data_stream_->AppendChunk(kUploadData, kUploadDataSize, true);
+
+      google_chunked_post_request_.method = "POST";
+      google_chunked_post_request_.url = GURL(kDefaultURL);
+      google_chunked_post_request_.upload_data_stream =
+          upload_data_stream_.get();
+      google_chunked_post_request_initialized_ = true;
+    }
+    return google_chunked_post_request_;
+  }
+
+  // Read the result of a particular transaction, knowing that we've got
+  // multiple transactions in the read pipeline; so as we read, we may have
+  // to skip over data destined for other transactions while we consume
+  // the data for |trans|.
+  int ReadResult(HttpNetworkTransaction* trans,
+                 StaticSocketDataProvider* data,
+                 std::string* result) {
+    const int kSize = 3000;
+
+    int bytes_read = 0;
+    scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize));
+    TestCompletionCallback callback;
+    while (true) {
+      int rv = trans->Read(buf, kSize, callback.callback());
+      if (rv == ERR_IO_PENDING) {
+        // Multiple transactions may be in the data set.  Keep pulling off
+        // reads until we complete our callback.
+        while (!callback.have_result()) {
+          data->CompleteRead();
+          MessageLoop::current()->RunUntilIdle();
+        }
+        rv = callback.WaitForResult();
+      } else if (rv <= 0) {
+        break;
+      }
+      result->append(buf->data(), rv);
+      bytes_read += rv;
+    }
+    return bytes_read;
+  }
+
+  void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
+    // This lengthy block is reaching into the pool to dig out the active
+    // session.  Once we have the session, we verify that the streams are
+    // all closed and not leaked at this point.
+    const GURL& url = helper.request().url;
+    int port = helper.test_type() == SPDYNPN ? 443 : 80;
+    HostPortPair host_port_pair(url.host(), port);
+    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+    BoundNetLog log;
+    const scoped_refptr<HttpNetworkSession>& session = helper.session();
+    SpdySessionPool* pool(session->spdy_session_pool());
+    EXPECT_TRUE(pool->HasSession(pair));
+    scoped_refptr<SpdySession> spdy_session(pool->Get(pair, log));
+    ASSERT_TRUE(spdy_session.get() != NULL);
+    EXPECT_EQ(0u, spdy_session->num_active_streams());
+    EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
+  }
+
+  void RunServerPushTest(OrderedSocketData* data,
+                         HttpResponseInfo* response,
+                         HttpResponseInfo* push_response,
+                         std::string& expected) {
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunPreTestSetup();
+    helper.AddData(data);
+
+    HttpNetworkTransaction* trans = helper.trans();
+
+    // Start the transaction with basic parameters.
+    TestCompletionCallback callback;
+    int rv = trans->Start(
+        &CreateGetRequest(), callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    rv = callback.WaitForResult();
+
+    // Request the pushed path.
+    scoped_ptr<HttpNetworkTransaction> trans2(
+        new HttpNetworkTransaction(helper.session()));
+    rv = trans2->Start(
+        &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    MessageLoop::current()->RunUntilIdle();
+
+    // The data for the pushed path may be coming in more than 1 packet. Compile
+    // the results into a single string.
+
+    // Read the server push body.
+    std::string result2;
+    ReadResult(trans2.get(), data, &result2);
+    // Read the response body.
+    std::string result;
+    ReadResult(trans, data, &result);
+
+    // Verify that we consumed all test data.
+    EXPECT_TRUE(data->at_read_eof());
+    EXPECT_TRUE(data->at_write_eof());
+
+    // Verify that the received push data is same as the expected push data.
+    EXPECT_EQ(result2.compare(expected), 0) << "Received data: "
+                                            << result2
+                                            << "||||| Expected data: "
+                                            << expected;
+
+    // Verify the SYN_REPLY.
+    // Copy the response info, because trans goes away.
+    *response = *trans->GetResponseInfo();
+    *push_response = *trans2->GetResponseInfo();
+
+    VerifyStreamsClosed(helper);
+  }
+
+  static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper,
+                                    int result) {
+    helper->ResetTrans();
+  }
+
+  static void StartTransactionCallback(
+      const scoped_refptr<HttpNetworkSession>& session,
+      int result) {
+    scoped_ptr<HttpNetworkTransaction> trans(
+        new HttpNetworkTransaction(session));
+    TestCompletionCallback callback;
+    HttpRequestInfo request;
+    request.method = "GET";
+    request.url = GURL("http://www.google.com/");
+    request.load_flags = 0;
+    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    callback.WaitForResult();
+  }
+
+ private:
+  scoped_ptr<UploadDataStream> upload_data_stream_;
+  bool google_get_request_initialized_;
+  bool google_post_request_initialized_;
+  bool google_chunked_post_request_initialized_;
+  HttpRequestInfo google_get_request_;
+  HttpRequestInfo google_post_request_;
+  HttpRequestInfo google_chunked_post_request_;
+  HttpRequestInfo google_get_push_request_;
+  base::ScopedTempDir temp_dir_;
+};
+
+//-----------------------------------------------------------------------------
+// All tests are run with three different connection types: SPDY after NPN
+// negotiation, SPDY without SSL, and SPDY with SSL.
+INSTANTIATE_TEST_CASE_P(Spdy,
+                        SpdyNetworkTransactionSpdy3Test,
+                        ::testing::Values(SPDYNOSSL, SPDYSSL, SPDYNPN));
+
+
+// Verify HttpNetworkTransaction constructor.
+TEST_P(SpdyNetworkTransactionSpdy3Test, Constructor) {
+  SpdySessionDependencies session_deps;
+  scoped_refptr<HttpNetworkSession> session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+  scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, Get) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, GetAtEachPriority) {
+  for (RequestPriority p = MINIMUM_PRIORITY; p < NUM_PRIORITIES;
+       p = RequestPriority(p + 1)) {
+    // Construct the request.
+    scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, p));
+    MockWrite writes[] = { CreateMockWrite(*req) };
+
+    const int spdy_prio = reinterpret_cast<SpdySynStreamControlFrame*>(
+        req.get())->priority();
+    // this repeats the RequestPriority-->SpdyPriority mapping from
+    // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
+    // sure it's being done right.
+    switch(p) {
+      case HIGHEST:
+        EXPECT_EQ(0, spdy_prio);
+        break;
+      case MEDIUM:
+        EXPECT_EQ(1, spdy_prio);
+        break;
+      case LOW:
+        EXPECT_EQ(2, spdy_prio);
+        break;
+      case LOWEST:
+        EXPECT_EQ(3, spdy_prio);
+        break;
+      case IDLE:
+        EXPECT_EQ(4, spdy_prio);
+        break;
+      default:
+        FAIL();
+    }
+
+    scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*resp),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                              writes, arraysize(writes));
+    HttpRequestInfo http_req = CreateGetRequest();
+    http_req.priority = p;
+
+    NormalSpdyTransactionHelper helper(http_req, BoundNetLog(),
+                                       GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!", out.response_data);
+  }
+}
+
+// Start three gets simultaniously; making sure that multiplexed
+// streams work properly.
+
+// This can't use the TransactionHelper method, since it only
+// handles a single transaction, and finishes them as soon
+// as it launches them.
+
+// TODO(gavinp): create a working generalized TransactionHelper that
+// can allow multiple streams in flight.
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ThreeGets) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
+  scoped_ptr<SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+    CreateMockWrite(*req3),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body),
+    CreateMockRead(*resp2, 4),
+    CreateMockRead(*body2),
+    CreateMockRead(*resp3, 7),
+    CreateMockRead(*body3),
+
+    CreateMockRead(*fbody),
+    CreateMockRead(*fbody2),
+    CreateMockRead(*fbody3),
+
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because three get requests are sent out, so
+  // there needs to be three sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  TestCompletionCallback callback3;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  out.rv = callback3.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+
+  trans2->GetResponseInfo();
+
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  helper.VerifyDataConsumed();
+  EXPECT_EQ(OK, out.rv);
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, TwoGetsLateBinding) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body),
+    CreateMockRead(*resp2, 4),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody),
+    CreateMockRead(*fbody2),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
+
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+  data_placeholder.set_connect_data(never_finishing_connect);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because two get requests are sent out, so
+  // there needs to be two sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  EXPECT_TRUE(response2->headers != NULL);
+  EXPECT_TRUE(response2->was_fetched_via_spdy);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, TwoGetsLateBindingFromPreconnect) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body),
+    CreateMockRead(*resp2, 4),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody),
+    CreateMockRead(*fbody2),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  OrderedSocketData preconnect_data(reads, arraysize(reads),
+                                    writes, arraysize(writes));
+
+  MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING);
+
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+  data_placeholder.set_connect_data(never_finishing_connect);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&preconnect_data);
+  // We require placeholder data because 3 connections are attempted (first is
+  // the preconnect, 2nd and 3rd are the never finished connections.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+
+  HttpRequestInfo httpreq = CreateGetRequest();
+
+  // Preconnect the first.
+  SSLConfig preconnect_ssl_config;
+  helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
+  HttpStreamFactory* http_stream_factory =
+      helper.session()->http_stream_factory();
+  if (http_stream_factory->has_next_protos()) {
+    preconnect_ssl_config.next_protos = http_stream_factory->next_protos();
+  }
+
+  http_stream_factory->PreconnectStreams(
+      1, httpreq, preconnect_ssl_config, preconnect_ssl_config);
+
+  out.rv = trans1->Start(&httpreq, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans2->Start(&httpreq, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  EXPECT_TRUE(response2->headers != NULL);
+  EXPECT_TRUE(response2->was_fetched_via_spdy);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  helper.VerifyDataConsumed();
+}
+
+// Similar to ThreeGets above, however this test adds a SETTINGS
+// frame.  The SETTINGS frame is read during the IO loop waiting on
+// the first transaction completion, and sets a maximum concurrent
+// stream limit of 1.  This means that our IO loop exists after the
+// second transaction completes, so we can assert on read_index().
+TEST_P(SpdyNetworkTransactionSpdy3Test, ThreeGetsWithMaxConcurrent) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
+  scoped_ptr<SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+    CreateMockWrite(*req3),
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fbody),
+    CreateMockRead(*resp2, 7),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody2),
+    CreateMockRead(*resp3, 12),
+    CreateMockRead(*body3),
+    CreateMockRead(*fbody3),
+
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  {
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunPreTestSetup();
+    helper.AddData(&data);
+    // We require placeholder data because three get requests are sent out, so
+    // there needs to be three sets of SSL connection data.
+    helper.AddData(&data_placeholder);
+    helper.AddData(&data_placeholder);
+    scoped_ptr<HttpNetworkTransaction> trans1(
+        new HttpNetworkTransaction(helper.session()));
+    scoped_ptr<HttpNetworkTransaction> trans2(
+        new HttpNetworkTransaction(helper.session()));
+    scoped_ptr<HttpNetworkTransaction> trans3(
+        new HttpNetworkTransaction(helper.session()));
+
+    TestCompletionCallback callback1;
+    TestCompletionCallback callback2;
+    TestCompletionCallback callback3;
+
+    HttpRequestInfo httpreq1 = CreateGetRequest();
+    HttpRequestInfo httpreq2 = CreateGetRequest();
+    HttpRequestInfo httpreq3 = CreateGetRequest();
+
+    out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+    ASSERT_EQ(out.rv, ERR_IO_PENDING);
+    // run transaction 1 through quickly to force a read of our SETTINGS
+    // frame
+    out.rv = callback1.WaitForResult();
+    ASSERT_EQ(OK, out.rv);
+
+    out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+    ASSERT_EQ(out.rv, ERR_IO_PENDING);
+    out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+    ASSERT_EQ(out.rv, ERR_IO_PENDING);
+    out.rv = callback2.WaitForResult();
+    ASSERT_EQ(OK, out.rv);
+    EXPECT_EQ(7U, data.read_index());  // i.e. the third trans was queued
+
+    out.rv = callback3.WaitForResult();
+    ASSERT_EQ(OK, out.rv);
+
+    const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+    ASSERT_TRUE(response1 != NULL);
+    EXPECT_TRUE(response1->headers != NULL);
+    EXPECT_TRUE(response1->was_fetched_via_spdy);
+    out.status_line = response1->headers->GetStatusLine();
+    out.response_info = *response1;
+    out.rv = ReadTransaction(trans1.get(), &out.response_data);
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!hello!", out.response_data);
+
+    const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+    out.status_line = response2->headers->GetStatusLine();
+    out.response_info = *response2;
+    out.rv = ReadTransaction(trans2.get(), &out.response_data);
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!hello!", out.response_data);
+
+    const HttpResponseInfo* response3 = trans3->GetResponseInfo();
+    out.status_line = response3->headers->GetStatusLine();
+    out.response_info = *response3;
+    out.rv = ReadTransaction(trans3.get(), &out.response_data);
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!hello!", out.response_data);
+
+    helper.VerifyDataConsumed();
+  }
+  EXPECT_EQ(OK, out.rv);
+}
+
+// Similar to ThreeGetsWithMaxConcurrent above, however this test adds
+// a fourth transaction.  The third and fourth transactions have
+// different data ("hello!" vs "hello!hello!") and because of the
+// user specified priority, we expect to see them inverted in
+// the response from the server.
+TEST_P(SpdyNetworkTransactionSpdy3Test, FourGetsWithMaxConcurrentPriority) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> req4(
+      ConstructSpdyGet(NULL, 0, false, 5, HIGHEST));
+  scoped_ptr<SpdyFrame> resp4(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> fbody4(ConstructSpdyBodyFrame(5, true));
+
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 7, LOWEST));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 7));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(7, false));
+  scoped_ptr<SpdyFrame> fbody3(ConstructSpdyBodyFrame(7, true));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = { CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+    CreateMockWrite(*req4),
+    CreateMockWrite(*req3),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fbody),
+    CreateMockRead(*resp2, 7),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody2),
+    CreateMockRead(*resp4, 13),
+    CreateMockRead(*fbody4),
+    CreateMockRead(*resp3, 16),
+    CreateMockRead(*body3),
+    CreateMockRead(*fbody3),
+
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+      BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because four get requests are sent out, so
+  // there needs to be four sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans4(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  TestCompletionCallback callback3;
+  TestCompletionCallback callback4;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+  HttpRequestInfo httpreq4 = CreateGetRequest();
+  httpreq4.priority = HIGHEST;
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+  out.rv = trans4->Start(&httpreq4, callback4.callback(), log);
+  ASSERT_EQ(ERR_IO_PENDING, out.rv);
+
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+  EXPECT_EQ(data.read_index(), 7U);  // i.e. the third & fourth trans queued
+
+  out.rv = callback3.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  // notice: response3 gets two hellos, response4 gets one
+  // hello, so we know dequeuing priority was respected.
+  const HttpResponseInfo* response3 = trans3->GetResponseInfo();
+  out.status_line = response3->headers->GetStatusLine();
+  out.response_info = *response3;
+  out.rv = ReadTransaction(trans3.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  out.rv = callback4.WaitForResult();
+  EXPECT_EQ(OK, out.rv);
+  const HttpResponseInfo* response4 = trans4->GetResponseInfo();
+  out.status_line = response4->headers->GetStatusLine();
+  out.response_info = *response4;
+  out.rv = ReadTransaction(trans4.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+  helper.VerifyDataConsumed();
+  EXPECT_EQ(OK, out.rv);
+}
+
+// Similar to ThreeGetsMaxConcurrrent above, however, this test
+// deletes a session in the middle of the transaction to insure
+// that we properly remove pendingcreatestream objects from
+// the spdy_session
+TEST_P(SpdyNetworkTransactionSpdy3Test, ThreeGetsWithMaxConcurrentDelete) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = { CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fbody),
+    CreateMockRead(*resp2, 7),
+    CreateMockRead(*body2),
+    CreateMockRead(*fbody2),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+      BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because three get requests are sent out, so
+  // there needs to be three sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  scoped_ptr<HttpNetworkTransaction> trans1(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  TestCompletionCallback callback3;
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+
+  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  delete trans3.release();
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback2.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  EXPECT_EQ(8U, data.read_index());
+
+  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
+  ASSERT_TRUE(response1 != NULL);
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(trans1.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+
+  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
+  ASSERT_TRUE(response2 != NULL);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(trans2.get(), &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+  helper.VerifyDataConsumed();
+  EXPECT_EQ(OK, out.rv);
+}
+
+namespace {
+
+// The KillerCallback will delete the transaction on error as part of the
+// callback.
+class KillerCallback : public TestCompletionCallbackBase {
+ public:
+  explicit KillerCallback(HttpNetworkTransaction* transaction)
+      : transaction_(transaction),
+        ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+            base::Bind(&KillerCallback::OnComplete, base::Unretained(this)))) {
+  }
+
+  virtual ~KillerCallback() {}
+
+  const CompletionCallback& callback() const { return callback_; }
+
+ private:
+  void OnComplete(int result) {
+    if (result < 0)
+      delete transaction_;
+
+    SetResult(result);
+  }
+
+  HttpNetworkTransaction* transaction_;
+  CompletionCallback callback_;
+};
+
+}  // namespace
+
+// Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
+// closes the socket while we have a pending transaction waiting for
+// a pending stream creation.  http://crbug.com/52901
+TEST_P(SpdyNetworkTransactionSpdy3Test, ThreeGetsWithMaxConcurrentSocketClose) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> fin_body(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+
+  SettingsMap settings;
+  const size_t max_concurrent_streams = 1;
+  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  MockWrite writes[] = { CreateMockWrite(*req),
+    CreateMockWrite(*req2),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 1),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    CreateMockRead(*fin_body),
+    CreateMockRead(*resp2, 7),
+    MockRead(ASYNC, ERR_CONNECTION_RESET, 0),  // Abort!
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
+
+  BoundNetLog log;
+  TransactionHelperResult out;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+      BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  // We require placeholder data because three get requests are sent out, so
+  // there needs to be three sets of SSL connection data.
+  helper.AddData(&data_placeholder);
+  helper.AddData(&data_placeholder);
+  HttpNetworkTransaction trans1(helper.session());
+  HttpNetworkTransaction trans2(helper.session());
+  HttpNetworkTransaction* trans3(new HttpNetworkTransaction(helper.session()));
+
+  TestCompletionCallback callback1;
+  TestCompletionCallback callback2;
+  KillerCallback callback3(trans3);
+
+  HttpRequestInfo httpreq1 = CreateGetRequest();
+  HttpRequestInfo httpreq2 = CreateGetRequest();
+  HttpRequestInfo httpreq3 = CreateGetRequest();
+
+  out.rv = trans1.Start(&httpreq1, callback1.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
+  out.rv = callback1.WaitForResult();
+  ASSERT_EQ(OK, out.rv);
+
+  out.rv = trans2.Start(&httpreq2, callback2.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
+  ASSERT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback3.WaitForResult();
+  ASSERT_EQ(ERR_ABORTED, out.rv);
+
+  EXPECT_EQ(6U, data.read_index());
+
+  const HttpResponseInfo* response1 = trans1.GetResponseInfo();
+  ASSERT_TRUE(response1 != NULL);
+  EXPECT_TRUE(response1->headers != NULL);
+  EXPECT_TRUE(response1->was_fetched_via_spdy);
+  out.status_line = response1->headers->GetStatusLine();
+  out.response_info = *response1;
+  out.rv = ReadTransaction(&trans1, &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+
+  const HttpResponseInfo* response2 = trans2.GetResponseInfo();
+  ASSERT_TRUE(response2 != NULL);
+  out.status_line = response2->headers->GetStatusLine();
+  out.response_info = *response2;
+  out.rv = ReadTransaction(&trans2, &out.response_data);
+  EXPECT_EQ(ERR_CONNECTION_RESET, out.rv);
+
+  helper.VerifyDataConsumed();
+}
+
+// Test that a simple PUT request works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, Put) {
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "PUT";
+  request.url = GURL("http://www.google.com/");
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,             // Kind = Syn
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                      // Credential Slot
+    CONTROL_FLAG_FIN,       // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  const char* const kPutHeaders[] = {
+    ":method", "PUT",
+    ":path", "/",
+    ":host", "www.google.com",
+    ":scheme", "http",
+    ":version", "HTTP/1.1",
+    "content-length", "0"
+  };
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0,
+    kPutHeaders, arraysize(kPutHeaders) / 2));
+  MockWrite writes[] = {
+    CreateMockWrite(*req)
+  };
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  const SpdyHeaderInfo kSynReplyHeader = {
+    SYN_REPLY,              // Kind = SynReply
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                      // Credential Slot
+    CONTROL_FLAG_NONE,      // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  static const char* const kStandardRespHeaders[] = {
+    ":status", "200",
+    ":version", "HTTP/1.1"
+    "content-length", "1234"
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader,
+      NULL, 0, kStandardRespHeaders, arraysize(kStandardRespHeaders) / 2));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+}
+
+// Test that a simple HEAD request works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, Head) {
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "HEAD";
+  request.url = GURL("http://www.google.com/");
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,             // Kind = Syn
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                      // Credential Slot
+    CONTROL_FLAG_FIN,       // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  const char* const kHeadHeaders[] = {
+    ":method", "HEAD",
+    ":path", "/",
+    ":host", "www.google.com",
+    ":scheme", "http",
+    ":version", "HTTP/1.1",
+    "content-length", "0"
+  };
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0,
+    kHeadHeaders, arraysize(kHeadHeaders) / 2));
+  MockWrite writes[] = {
+    CreateMockWrite(*req)
+  };
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  const SpdyHeaderInfo kSynReplyHeader = {
+    SYN_REPLY,              // Kind = SynReply
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                      // Credential Slot
+    CONTROL_FLAG_NONE,      // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  static const char* const kStandardRespHeaders[] = {
+    ":status", "200",
+    ":version", "HTTP/1.1"
+    "content-length", "1234"
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader,
+      NULL, 0, kStandardRespHeaders, arraysize(kStandardRespHeaders) / 2));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+}
+
+// Test that a simple POST works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, Post) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),  // POST upload frame
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreatePostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a POST with a file works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, FilePost) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),  // POST upload frame
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateFilePostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a complex POST works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, ComplexPost) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),  // POST upload frame
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateComplexPostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a chunked POST works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, ChunkedPost) {
+  set_merge_chunks(false);
+
+  scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*chunk1),
+    CreateMockWrite(*chunk2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*chunk1),
+    CreateMockRead(*chunk2),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+}
+
+// Test that a POST without any post data works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, NullPost) {
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  // Create an empty UploadData.
+  request.upload_data_stream = NULL;
+
+  // When request.upload_data_stream is NULL for post, content-length is
+  // expected to be 0.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(0, NULL, 0));
+  // Set the FIN bit since there will be no body.
+  req->set_flags(CONTROL_FLAG_FIN);
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// Test that a simple POST works.
+TEST_P(SpdyNetworkTransactionSpdy3Test, EmptyPost) {
+  // Create an empty UploadDataStream.
+  ScopedVector<UploadElementReader> element_readers;
+  UploadDataStream stream(&element_readers, 0);
+
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &stream;
+
+  const uint64 kContentLength = 0;
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kContentLength, NULL, 0));
+  // Set the FIN bit since there will be no body.
+  req->set_flags(CONTROL_FLAG_FIN);
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads), writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// While we're doing a post, the server sends back a SYN_REPLY.
+TEST_P(SpdyNetworkTransactionSpdy3Test, PostWithEarlySynReply) {
+  static const char upload[] = { "hello!" };
+  ScopedVector<UploadElementReader> element_readers;
+  element_readers.push_back(
+      new UploadBytesElementReader(upload, sizeof(upload)));
+  UploadDataStream stream(&element_readers, 0);
+
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &stream;
+
+  scoped_ptr<SpdyFrame> stream_reply(ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdyFrame> stream_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream_reply, 1),
+    MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 0),
+    CreateMockWrite(*body, 2),
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreatePostRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreatePostRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  data.RunFor(2);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
+  data.RunFor(1);
+}
+
+// The client upon cancellation tries to send a RST_STREAM frame. The mock
+// socket causes the TCP write to return zero. This test checks that the client
+// tries to queue up the RST_STREAM frame again.
+TEST_P(SpdyNetworkTransactionSpdy3Test, SocketWriteReturnsZero) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, CANCEL));
+  MockWrite writes[] = {
+    CreateMockWrite(*req.get(), 0, SYNCHRONOUS),
+    MockWrite(SYNCHRONOUS, 0, 0, 2),
+    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp.get(), 1, ASYNC),
+    MockRead(ASYNC, 0, 0, 4)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  data.SetStop(2);
+  data.Run();
+  helper.ResetTrans();
+  data.SetStop(20);
+  data.Run();
+
+  helper.VerifyDataConsumed();
+}
+
+// Test that the transaction doesn't crash when we don't have a reply.
+TEST_P(SpdyNetworkTransactionSpdy3Test, ResponseWithoutSynReply) {
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads), NULL, 0);
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv);
+}
+
+// Test that the transaction doesn't crash when we get two replies on the same
+// stream ID. See http://crbug.com/45639.
+TEST_P(SpdyNetworkTransactionSpdy3Test, ResponseWithTwoSynReplies) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  std::string response_data;
+  rv = ReadTransaction(trans, &response_data);
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
+
+  helper.VerifyDataConsumed();
+}
+
+// Test that sent data frames and received WINDOW_UPDATE frames change
+// the send_window_size_ correctly.
+
+// WINDOW_UPDATE is different than most other frames in that it can arrive
+// while the client is still sending the request body.  In order to enforce
+// this scenario, we feed a couple of dummy frames and give a delay of 0 to
+// socket data provider, so that initial read that is done as soon as the
+// stream is created, succeeds and schedules another read.  This way reads
+// and writes are interleaved; after doing a full frame write, SpdyStream
+// will break out of DoLoop and will read and process a WINDOW_UPDATE.
+// Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away
+// since request has not been completely written, therefore we feed
+// enough number of WINDOW_UPDATEs to finish the first read and cause a
+// write, leading to a complete write of request body; after that we send
+// a reply with a body, to cause a graceful shutdown.
+
+// TODO(agayev): develop a socket data provider where both, reads and
+// writes are ordered so that writing tests like these are easy and rewrite
+// all these tests using it.  Right now we are working around the
+// limitations as described above and it's not deterministic, tests may
+// fail under specific circumstances.
+TEST_P(SpdyNetworkTransactionSpdy3Test, WindowUpdateReceived) {
+  static int kFrameCount = 2;
+  scoped_ptr<std::string> content(
+      new std::string(kMaxSpdyFrameChunkSize, 'a'));
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(
+      kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0));
+  scoped_ptr<SpdyFrame> body(
+      ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false));
+  scoped_ptr<SpdyFrame> body_end(
+      ConstructSpdyBodyFrame(1, content->c_str(), content->size(), true));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*body),
+    CreateMockWrite(*body_end),
+  };
+
+  static const int32 kDeltaWindowSize = 0xff;
+  static const int kDeltaCount = 4;
+  scoped_ptr<SpdyFrame> window_update(
+      ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
+  scoped_ptr<SpdyFrame> window_update_dummy(
+      ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*window_update_dummy),
+    CreateMockRead(*window_update_dummy),
+    CreateMockRead(*window_update_dummy),
+    CreateMockRead(*window_update),     // Four updates, therefore window
+    CreateMockRead(*window_update),     // size should increase by
+    CreateMockRead(*window_update),     // kDeltaWindowSize * 4
+    CreateMockRead(*window_update),
+    CreateMockRead(*resp),
+    CreateMockRead(*body_end),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(0, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  ScopedVector<UploadElementReader> element_readers;
+  for (int i = 0; i < kFrameCount; ++i) {
+    element_readers.push_back(
+        new UploadBytesElementReader(content->c_str(), content->size()));
+  }
+  UploadDataStream upload_data_stream(&element_readers, 0);
+
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL(kDefaultURL);
+  request.upload_data_stream = &upload_data_stream;
+
+  NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
+  ASSERT_TRUE(stream != NULL);
+  ASSERT_TRUE(stream->stream() != NULL);
+  EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize) +
+            kDeltaWindowSize * kDeltaCount -
+            kMaxSpdyFrameChunkSize * kFrameCount,
+            stream->stream()->send_window_size());
+  helper.VerifyDataConsumed();
+}
+
+// Test that received data frames and sent WINDOW_UPDATE frames change
+// the recv_window_size_ correctly.
+TEST_P(SpdyNetworkTransactionSpdy3Test, WindowUpdateSent) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> window_update(
+      ConstructSpdyWindowUpdate(1, kUploadDataSize));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*window_update),
+  };
+
+  scoped_ptr<SpdyFrame> resp(
+      ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body_no_fin(
+      ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> body_fin(
+      ConstructSpdyBodyFrame(1, NULL, 0, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body_no_fin),
+    MockRead(ASYNC, ERR_IO_PENDING, 0),  // Force a pause
+    CreateMockRead(*body_fin),
+    MockRead(ASYNC, ERR_IO_PENDING, 0),  // Force a pause
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunPreTestSetup();
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  SpdyHttpStream* stream =
+      static_cast<SpdyHttpStream*>(trans->stream_.get());
+  ASSERT_TRUE(stream != NULL);
+  ASSERT_TRUE(stream->stream() != NULL);
+
+  EXPECT_EQ(
+      static_cast<int>(kSpdyStreamInitialWindowSize) - kUploadDataSize,
+      stream->stream()->recv_window_size());
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  ASSERT_TRUE(response->headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+
+  // Force sending of WINDOW_UPDATE by setting initial_recv_window_size to a
+  // small value.
+  stream->stream()->set_initial_recv_window_size(kUploadDataSize / 2);
+
+  // Issue a read which will cause a WINDOW_UPDATE to be sent and window
+  // size increased to default.
+  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kUploadDataSize));
+  rv = trans->Read(buf, kUploadDataSize, CompletionCallback());
+  EXPECT_EQ(kUploadDataSize, rv);
+  std::string content(buf->data(), buf->data()+kUploadDataSize);
+  EXPECT_STREQ(kUploadData, content.c_str());
+
+  // Schedule the reading of empty data frame with FIN
+  data.CompleteRead();
+
+  // Force write of WINDOW_UPDATE which was scheduled during the above
+  // read.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read EOF.
+  data.CompleteRead();
+
+  helper.VerifyDataConsumed();
+}
+
+// Test that WINDOW_UPDATE frame causing overflow is handled correctly.
+TEST_P(SpdyNetworkTransactionSpdy3Test, WindowUpdateOverflow) {
+  // Number of full frames we hope to write (but will not, used to
+  // set content-length header correctly)
+  static int kFrameCount = 3;
+
+  scoped_ptr<std::string> content(
+      new std::string(kMaxSpdyFrameChunkSize, 'a'));
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(
+      kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0));
+  scoped_ptr<SpdyFrame> body(
+      ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, FLOW_CONTROL_ERROR));
+
+  // We're not going to write a data frame with FIN, we'll receive a bad
+  // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 0),
+    CreateMockWrite(*body, 2),
+    CreateMockWrite(*rst, 3),
+  };
+
+  static const int32 kDeltaWindowSize = 0x7fffffff;  // cause an overflow
+  scoped_ptr<SpdyFrame> window_update(
+      ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
+  MockRead reads[] = {
+    CreateMockRead(*window_update, 1),
+    MockRead(ASYNC, 0, 4)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  ScopedVector<UploadElementReader> element_readers;
+  for (int i = 0; i < kFrameCount; ++i) {
+    element_readers.push_back(
+        new UploadBytesElementReader(content->c_str(), content->size()));
+  }
+  UploadDataStream upload_data_stream(&element_readers, 0);
+
+  // Setup the request
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_data_stream;
+
+  NormalSpdyTransactionHelper helper(request,
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  ASSERT_EQ(ERR_IO_PENDING, rv);
+
+  data.RunFor(5);
+  ASSERT_TRUE(callback.have_result());
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult());
+  helper.VerifyDataConsumed();
+}
+
+// Test that after hitting a send window size of 0, the write process
+// stalls and upon receiving WINDOW_UPDATE frame write resumes.
+
+// This test constructs a POST request followed by enough data frames
+// containing 'a' that would make the window size 0, followed by another
+// data frame containing default content (which is "hello!") and this frame
+// also contains a FIN flag.  DelayedSocketData is used to enforce all
+// writes go through before a read could happen.  However, the last frame
+// ("hello!")  is not supposed to go through since by the time its turn
+// arrives, window size is 0.  At this point MessageLoop::Run() called via
+// callback would block.  Therefore we call MessageLoop::RunUntilIdle()
+// which returns after performing all possible writes.  We use DCHECKS to
+// ensure that last data frame is still there and stream has stalled.
+// After that, next read is artifically enforced, which causes a
+// WINDOW_UPDATE to be read and I/O process resumes.
+TEST_P(SpdyNetworkTransactionSpdy3Test, FlowControlStallResume) {
+  // Number of frames we need to send to zero out the window size: data
+  // frames plus SYN_STREAM plus the last data frame; also we need another
+  // data frame that we will send once the WINDOW_UPDATE is received,
+  // therefore +3.
+  size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
+
+  // Calculate last frame's size; 0 size data frame is legal.
+  size_t last_frame_size =
+      kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
+
+  // Construct content for a data frame of maximum size.
+  std::string content(kMaxSpdyFrameChunkSize, 'a');
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(
+      kSpdyStreamInitialWindowSize + kUploadDataSize, NULL, 0));
+
+  // Full frames.
+  scoped_ptr<SpdyFrame> body1(
+      ConstructSpdyBodyFrame(1, content.c_str(), content.size(), false));
+
+  // Last frame to zero out the window size.
+  scoped_ptr<SpdyFrame> body2(
+      ConstructSpdyBodyFrame(1, content.c_str(), last_frame_size, false));
+
+  // Data frame to be sent once WINDOW_UPDATE frame is received.
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(1, true));
+
+  // Fill in mock writes.
+  scoped_array<MockWrite> writes(new MockWrite[num_writes]);
+  size_t i = 0;
+  writes[i] = CreateMockWrite(*req);
+  for (i = 1; i < num_writes - 2; i++)
+    writes[i] = CreateMockWrite(*body1);
+  writes[i++] = CreateMockWrite(*body2);
+  writes[i] = CreateMockWrite(*body3);
+
+  // Construct read frame, give enough space to upload the rest of the
+  // data.
+  scoped_ptr<SpdyFrame> window_update(
+      ConstructSpdyWindowUpdate(1, kUploadDataSize));
+  scoped_ptr<SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*window_update),
+    CreateMockRead(*window_update),
+    CreateMockRead(*reply),
+    CreateMockRead(*body2),
+    CreateMockRead(*body3),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  // Force all writes to happen before any read, last write will not
+  // actually queue a frame, due to window size being 0.
+  DelayedSocketData data(num_writes, reads, arraysize(reads),
+                         writes.get(), num_writes);
+
+  ScopedVector<UploadElementReader> element_readers;
+  std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
+  upload_data_string.append(kUploadData, kUploadDataSize);
+  element_readers.push_back(new UploadBytesElementReader(
+      upload_data_string.c_str(), upload_data_string.size()));
+  UploadDataStream upload_data_stream(&element_readers, 0);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_data_stream;
+  NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  MessageLoop::current()->RunUntilIdle();  // Write as much as we can.
+
+  SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
+  ASSERT_TRUE(stream != NULL);
+  ASSERT_TRUE(stream->stream() != NULL);
+  EXPECT_EQ(0, stream->stream()->send_window_size());
+  // All the body data should have been read.
+  // TODO(satorux): This is because of the weirdness in reading the request
+  // body in OnSendBodyComplete(). See crbug.com/113107.
+  EXPECT_TRUE(upload_data_stream.IsEOF());
+  // But the body is not yet fully sent (kUploadData is not yet sent).
+  EXPECT_FALSE(stream->stream()->body_sent());
+
+  data.ForceNextRead();   // Read in WINDOW_UPDATE frame.
+  rv = callback.WaitForResult();
+  helper.VerifyDataConsumed();
+}
+
+// Test we correctly handle the case where the SETTINGS frame results in
+// unstalling the send window.
+TEST_P(SpdyNetworkTransactionSpdy3Test, FlowControlStallResumeAfterSettings) {
+  // Number of frames we need to send to zero out the window size: data
+  // frames plus SYN_STREAM plus the last data frame; also we need another
+  // data frame that we will send once the SETTING is received, therefore +3.
+  size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
+
+  // Calculate last frame's size; 0 size data frame is legal.
+  size_t last_frame_size =
+      kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
+
+  // Construct content for a data frame of maximum size.
+  std::string content(kMaxSpdyFrameChunkSize, 'a');
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(
+      kSpdyStreamInitialWindowSize + kUploadDataSize, NULL, 0));
+
+  // Full frames.
+  scoped_ptr<SpdyFrame> body1(
+      ConstructSpdyBodyFrame(1, content.c_str(), content.size(), false));
+
+  // Last frame to zero out the window size.
+  scoped_ptr<SpdyFrame> body2(
+      ConstructSpdyBodyFrame(1, content.c_str(), last_frame_size, false));
+
+  // Data frame to be sent once SETTINGS frame is received.
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(1, true));
+
+  // Fill in mock writes.
+  scoped_array<MockWrite> writes(new MockWrite[num_writes]);
+  size_t i = 0;
+  writes[i] = CreateMockWrite(*req);
+  for (i = 1; i < num_writes - 2; i++)
+    writes[i] = CreateMockWrite(*body1);
+  writes[i++] = CreateMockWrite(*body2);
+  writes[i] = CreateMockWrite(*body3);
+
+  // Construct read frame for SETTINGS that gives enough space to upload the
+  // rest of the data.
+  SettingsMap settings;
+  settings[SETTINGS_INITIAL_WINDOW_SIZE] =
+      SettingsFlagsAndValue(
+          SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize * 2);
+  scoped_ptr<SpdyFrame> settings_frame_large(ConstructSpdySettings(settings));
+  scoped_ptr<SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame_large),
+    CreateMockRead(*reply),
+    CreateMockRead(*body2),
+    CreateMockRead(*body3),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  // Force all writes to happen before any read, last write will not
+  // actually queue a frame, due to window size being 0.
+  DelayedSocketData data(num_writes, reads, arraysize(reads),
+                         writes.get(), num_writes);
+
+  ScopedVector<UploadElementReader> element_readers;
+  std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
+  upload_data_string.append(kUploadData, kUploadDataSize);
+  element_readers.push_back(new UploadBytesElementReader(
+      upload_data_string.c_str(), upload_data_string.size()));
+  UploadDataStream upload_data_stream(&element_readers, 0);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_data_stream;
+  NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  MessageLoop::current()->RunUntilIdle();  // Write as much as we can.
+
+  SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
+  ASSERT_TRUE(stream != NULL);
+  ASSERT_TRUE(stream->stream() != NULL);
+  EXPECT_EQ(0, stream->stream()->send_window_size());
+
+  // All the body data should have been read.
+  // TODO(satorux): This is because of the weirdness in reading the request
+  // body in OnSendBodyComplete(). See crbug.com/113107.
+  EXPECT_TRUE(upload_data_stream.IsEOF());
+  // But the body is not yet fully sent (kUploadData is not yet sent).
+  EXPECT_FALSE(stream->stream()->body_sent());
+  EXPECT_TRUE(stream->stream()->stalled_by_flow_control());
+
+  data.ForceNextRead();   // Read in SETTINGS frame to unstall.
+  rv = callback.WaitForResult();
+  helper.VerifyDataConsumed();
+  EXPECT_FALSE(stream->stream()->stalled_by_flow_control());
+}
+
+// Test we correctly handle the case where the SETTINGS frame results in a
+// negative send window size.
+TEST_P(SpdyNetworkTransactionSpdy3Test, FlowControlNegativeSendWindowSize) {
+  // Number of frames we need to send to zero out the window size: data
+  // frames plus SYN_STREAM plus the last data frame; also we need another
+  // data frame that we will send once the SETTING is received, therefore +3.
+  size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
+
+  // Calculate last frame's size; 0 size data frame is legal.
+  size_t last_frame_size =
+      kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
+
+  // Construct content for a data frame of maximum size.
+  std::string content(kMaxSpdyFrameChunkSize, 'a');
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPost(
+      kSpdyStreamInitialWindowSize + kUploadDataSize, NULL, 0));
+
+  // Full frames.
+  scoped_ptr<SpdyFrame> body1(
+      ConstructSpdyBodyFrame(1, content.c_str(), content.size(), false));
+
+  // Last frame to zero out the window size.
+  scoped_ptr<SpdyFrame> body2(
+      ConstructSpdyBodyFrame(1, content.c_str(), last_frame_size, false));
+
+  // Data frame to be sent once SETTINGS frame is received.
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(1, true));
+
+  // Fill in mock writes.
+  scoped_array<MockWrite> writes(new MockWrite[num_writes]);
+  size_t i = 0;
+  writes[i] = CreateMockWrite(*req);
+  for (i = 1; i < num_writes - 2; i++)
+    writes[i] = CreateMockWrite(*body1);
+  writes[i++] = CreateMockWrite(*body2);
+  writes[i] = CreateMockWrite(*body3);
+
+  // Construct read frame for SETTINGS that makes the send_window_size
+  // negative.
+  SettingsMap new_settings;
+  new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
+      SettingsFlagsAndValue(
+          SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize / 2);
+  scoped_ptr<SpdyFrame> settings_frame_small(
+      ConstructSpdySettings(new_settings));
+  // Construct read frame for WINDOW_UPDATE that makes the send_window_size
+  // postive.
+  scoped_ptr<SpdyFrame> window_update_init_size(
+      ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize));
+  scoped_ptr<SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0));
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame_small),
+    CreateMockRead(*window_update_init_size),
+    CreateMockRead(*reply),
+    CreateMockRead(*body2),
+    CreateMockRead(*body3),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  // Force all writes to happen before any read, last write will not actually
+  // queue a frame, due to window size being 0.
+  DelayedSocketData data(num_writes, reads, arraysize(reads),
+                         writes.get(), num_writes);
+
+  ScopedVector<UploadElementReader> element_readers;
+  std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
+  upload_data_string.append(kUploadData, kUploadDataSize);
+  element_readers.push_back(new UploadBytesElementReader(
+      upload_data_string.c_str(), upload_data_string.size()));
+  UploadDataStream upload_data_stream(&element_readers, 0);
+
+  HttpRequestInfo request;
+  request.method = "POST";
+  request.url = GURL("http://www.google.com/");
+  request.upload_data_stream = &upload_data_stream;
+  NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  MessageLoop::current()->RunUntilIdle();  // Write as much as we can.
+
+  SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
+  ASSERT_TRUE(stream != NULL);
+  ASSERT_TRUE(stream->stream() != NULL);
+  EXPECT_EQ(0, stream->stream()->send_window_size());
+
+  // All the body data should have been read.
+  // TODO(satorux): This is because of the weirdness in reading the request
+  // body in OnSendBodyComplete(). See crbug.com/113107.
+  EXPECT_TRUE(upload_data_stream.IsEOF());
+  // But the body is not yet fully sent (kUploadData is not yet sent).
+  EXPECT_FALSE(stream->stream()->body_sent());
+
+  data.ForceNextRead();   // Read in WINDOW_UPDATE or SETTINGS frame.
+  rv = callback.WaitForResult();
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ResetReplyWithTransferEncoding) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*rst),
+  };
+
+  const char* const headers[] = {
+    "transfer-encoding", "chuncked"
+  };
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(headers, 1, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+
+  helper.session()->spdy_session_pool()->CloseAllSessions();
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ResetPushWithTransferEncoding) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*rst),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  const char* const headers[] = {":scheme", "http",
+                                 ":host", "www.google.com",
+                                 ":path", "/1",
+                                 "transfer-encoding", "chunked"};
+  scoped_ptr<SpdyFrame> push(ConstructSpdyPush(headers, arraysize(headers) / 2,
+                                               2, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*push),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  helper.session()->spdy_session_pool()->CloseAllSessions();
+  helper.VerifyDataConsumed();
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, CancelledTransaction) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    // This following read isn't used by the test, except during the
+    // RunUntilIdle() call at the end since the SpdySession survives the
+    // HttpNetworkTransaction and still tries to continue Read()'ing.  Any
+    // MockRead will do here.
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  helper.ResetTrans();  // Cancel the transaction.
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+  helper.VerifyDataNotConsumed();
+}
+
+// Verify that the client sends a Rst Frame upon cancelling the stream.
+TEST_P(SpdyNetworkTransactionSpdy3Test, CancelledTransactionSendRst) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, CANCEL));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 0, SYNCHRONOUS),
+    CreateMockWrite(*rst, 2, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 0, 3)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(),
+                                     GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  data.SetStop(2);
+  data.Run();
+  helper.ResetTrans();
+  data.SetStop(20);
+  data.Run();
+
+  helper.VerifyDataConsumed();
+}
+
+// Verify that the client can correctly deal with the user callback attempting
+// to start another transaction on a session that is closing down. See
+// http://crbug.com/47455
+TEST_P(SpdyNetworkTransactionSpdy3Test, StartTransactionOnReadCallback) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+  MockWrite writes2[] = { CreateMockWrite(*req) };
+
+  // The indicated length of this packet is longer than its actual length. When
+  // the session receives an empty packet after this one, it shuts down the
+  // session, and calls the read callback with the incomplete data.
+  const uint8 kGetBodyFrame2[] = {
+    0x00, 0x00, 0x00, 0x01,
+    0x01, 0x00, 0x00, 0x07,
+    'h', 'e', 'l', 'l', 'o', '!',
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+    MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2),
+             arraysize(kGetBodyFrame2), 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
+    MockRead(ASYNC, 0, 0, 6),  // EOF
+  };
+  MockRead reads2[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(ASYNC, 0, 0, 3),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  DelayedSocketData data2(1, reads2, arraysize(reads2),
+                          writes2, arraysize(writes2));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  helper.AddData(&data2);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+
+  const int kSize = 3000;
+  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
+  rv = trans->Read(
+      buf, kSize,
+      base::Bind(&SpdyNetworkTransactionSpdy3Test::StartTransactionCallback,
+                 helper.session()));
+  // This forces an err_IO_pending, which sets the callback.
+  data.CompleteRead();
+  // This finishes the read.
+  data.CompleteRead();
+  helper.VerifyDataConsumed();
+}
+
+// Verify that the client can correctly deal with the user callback deleting the
+// transaction. Failures will usually be valgrind errors. See
+// http://crbug.com/46925
+TEST_P(SpdyNetworkTransactionSpdy3Test, DeleteSessionOnReadCallback) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp.get(), 2),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+    CreateMockRead(*body.get(), 4),
+    MockRead(ASYNC, 0, 0, 5),  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+
+  // Setup a user callback which will delete the session, and clear out the
+  // memory holding the stream object. Note that the callback deletes trans.
+  const int kSize = 3000;
+  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
+  rv = trans->Read(
+      buf, kSize,
+      base::Bind(&SpdyNetworkTransactionSpdy3Test::DeleteSessionCallback,
+                 base::Unretained(&helper)));
+  ASSERT_EQ(ERR_IO_PENDING, rv);
+  data.CompleteRead();
+
+  // Finish running rest of tasks.
+  MessageLoop::current()->RunUntilIdle();
+  helper.VerifyDataConsumed();
+}
+
+// Send a spdy request to www.google.com that gets redirected to www.foo.com.
+TEST_P(SpdyNetworkTransactionSpdy3Test, RedirectGetRequest) {
+  // These are headers which the net::URLRequest tacks on.
+  const char* const kExtraHeaders[] = {
+    "accept-encoding",
+    "gzip,deflate",
+  };
+  const SpdyHeaderInfo kSynStartHeader = MakeSpdyHeader(SYN_STREAM);
+  const char* const kStandardGetHeaders[] = {
+    ":host",
+    "www.google.com",
+    ":method",
+    "GET",
+    ":scheme",
+    "http",
+    ":path",
+    "/",
+    "user-agent",
+    "",
+    ":version",
+    "HTTP/1.1"
+  };
+  const char* const kStandardGetHeaders2[] = {
+    ":host",
+    "www.foo.com",
+    ":method",
+    "GET",
+    ":scheme",
+    "http",
+    ":path",
+    "/index.php",
+    "user-agent",
+    "",
+    ":version",
+    "HTTP/1.1"
+  };
+
+  // Setup writes/reads to www.google.com
+  scoped_ptr<SpdyFrame> req(ConstructSpdyPacket(
+      kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2,
+      kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyPacket(
+      kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2,
+      kStandardGetHeaders2, arraysize(kStandardGetHeaders2) / 2));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReplyRedirect(1));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    MockRead(ASYNC, 0, 0, 3)  // EOF
+  };
+
+  // Setup writes/reads to www.foo.com
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes2[] = {
+    CreateMockWrite(*req2, 1),
+  };
+  MockRead reads2[] = {
+    CreateMockRead(*resp2, 2),
+    CreateMockRead(*body2, 3),
+    MockRead(ASYNC, 0, 0, 4)  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data2(reads2, arraysize(reads2),
+                          writes2, arraysize(writes2));
+
+  // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
+  HttpStreamFactory::set_force_spdy_over_ssl(false);
+  HttpStreamFactory::set_force_spdy_always(true);
+  TestDelegate d;
+  {
+    SpdyURLRequestContext spdy_url_request_context;
+    net::URLRequest r(
+        GURL("http://www.google.com/"), &d, &spdy_url_request_context);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data2);
+
+    d.set_quit_on_redirect(true);
+    r.Start();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d.received_redirect_count());
+
+    r.FollowDeferredRedirect();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d.response_started_count());
+    EXPECT_FALSE(d.received_data_before_response());
+    EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status());
+    std::string contents("hello!");
+    EXPECT_EQ(contents, d.data_received());
+  }
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+  EXPECT_TRUE(data2.at_read_eof());
+  EXPECT_TRUE(data2.at_write_eof());
+}
+
+// Detect response with upper case headers and reset the stream.
+TEST_P(SpdyNetworkTransactionSpdy3Test, UpperCaseHeaders) {
+  scoped_ptr<SpdyFrame>
+      syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      rst(ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*syn, 0),
+    CreateMockWrite(*rst, 2),
+  };
+
+  const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
+  scoped_ptr<SpdyFrame>
+      reply(ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
+  MockRead reads[] = {
+    CreateMockRead(*reply, 1),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+}
+
+// Detect response with upper case headers in a HEADERS frame and reset the
+// stream.
+TEST_P(SpdyNetworkTransactionSpdy3Test, UpperCaseHeadersInHeadersFrame) {
+  scoped_ptr<SpdyFrame>
+      syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      rst(ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*syn, 0),
+    CreateMockWrite(*rst, 2),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    ":status", "200 OK",
+    ":version", "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "X-UpperCase", "yes",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+}
+
+// Detect push stream with upper case headers and reset the stream.
+TEST_P(SpdyNetworkTransactionSpdy3Test, UpperCaseHeadersOnPush) {
+  scoped_ptr<SpdyFrame>
+      syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*syn, 0),
+    CreateMockWrite(*rst, 2),
+  };
+
+  scoped_ptr<SpdyFrame>
+      reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  const char* const extra_headers[] = {
+    "X-UpperCase", "yes"
+  };
+  scoped_ptr<SpdyFrame>
+      push(ConstructSpdyPush(extra_headers, arraysize(extra_headers) / 2,
+                             2, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*reply, 1),
+    CreateMockRead(*push, 1),
+    CreateMockRead(*body, 1),
+    MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+}
+
+// Send a spdy request to www.google.com. Get a pushed stream that redirects to
+// www.foo.com.
+TEST_P(SpdyNetworkTransactionSpdy3Test, RedirectServerPush) {
+  // These are headers which the net::URLRequest tacks on.
+  const char* const kExtraHeaders[] = {
+    "accept-encoding",
+    "gzip,deflate",
+  };
+  const SpdyHeaderInfo kSynStartHeader = MakeSpdyHeader(SYN_STREAM);
+  const char* const kStandardGetHeaders[] = {
+    ":host",
+    "www.google.com",
+    ":method",
+    "GET",
+    ":scheme",
+    "http",
+    ":path",
+    "/",
+    "user-agent",
+    "",
+    ":version",
+    "HTTP/1.1"
+  };
+
+  // Setup writes/reads to www.google.com
+  scoped_ptr<SpdyFrame> req(
+      ConstructSpdyPacket(kSynStartHeader,
+                          kExtraHeaders,
+                          arraysize(kExtraHeaders) / 2,
+                          kStandardGetHeaders,
+                          arraysize(kStandardGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> rep(
+      ConstructSpdyPush(NULL,
+                        0,
+                        2,
+                        1,
+                        "http://www.google.com/foo.dat",
+                        "301 Moved Permanently",
+                        "http://www.foo.com/index.php"));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(2, CANCEL));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+    CreateMockWrite(*rst, 6),
+  };
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    CreateMockRead(*rep, 3),
+    CreateMockRead(*body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
+    MockRead(ASYNC, 0, 0, 7)  // EOF
+  };
+
+  // Setup writes/reads to www.foo.com
+  const char* const kStandardGetHeaders2[] = {
+    ":host",
+    "www.foo.com",
+    ":method",
+    "GET",
+    ":scheme",
+    "http",
+    ":path",
+    "/index.php",
+    "user-agent",
+    "",
+    ":version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame> req2(
+      ConstructSpdyPacket(kSynStartHeader,
+                          kExtraHeaders,
+                          arraysize(kExtraHeaders) / 2,
+                          kStandardGetHeaders2,
+                          arraysize(kStandardGetHeaders2) / 2));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes2[] = {
+    CreateMockWrite(*req2, 1),
+  };
+  MockRead reads2[] = {
+    CreateMockRead(*resp2, 2),
+    CreateMockRead(*body2, 3),
+    MockRead(ASYNC, 0, 0, 5)  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  OrderedSocketData data2(reads2, arraysize(reads2),
+                          writes2, arraysize(writes2));
+
+  // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
+  HttpStreamFactory::set_force_spdy_over_ssl(false);
+  HttpStreamFactory::set_force_spdy_always(true);
+  TestDelegate d;
+  TestDelegate d2;
+  SpdyURLRequestContext spdy_url_request_context;
+  {
+    net::URLRequest r(
+        GURL("http://www.google.com/"), &d, &spdy_url_request_context);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data);
+
+    r.Start();
+    MessageLoop::current()->Run();
+
+    EXPECT_EQ(0, d.received_redirect_count());
+    std::string contents("hello!");
+    EXPECT_EQ(contents, d.data_received());
+
+    net::URLRequest r2(
+        GURL("http://www.google.com/foo.dat"), &d2, &spdy_url_request_context);
+    spdy_url_request_context.socket_factory().
+        AddSocketDataProvider(&data2);
+
+    d2.set_quit_on_redirect(true);
+    r2.Start();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d2.received_redirect_count());
+
+    r2.FollowDeferredRedirect();
+    MessageLoop::current()->Run();
+    EXPECT_EQ(1, d2.response_started_count());
+    EXPECT_FALSE(d2.received_data_before_response());
+    EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status());
+    std::string contents2("hello!");
+    EXPECT_EQ(contents2, d2.data_received());
+  }
+  data.CompleteRead();
+  data2.CompleteRead();
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+  EXPECT_TRUE(data2.at_read_eof());
+  EXPECT_TRUE(data2.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushSingleDataFrame) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushBeforeSynReply) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_reply, 3),
+    CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushSingleDataFrame2) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushServerAborted) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  scoped_ptr<SpdyFrame>
+    stream2_rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream2_rst, 4),
+    CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushDuplicate) {
+  // Verify that we don't leak streams and that we properly send a reset
+  // if the server pushes the same stream twice.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream3_rst(ConstructSpdyRstStream(4, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream3_rst, 5),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  scoped_ptr<SpdyFrame>
+      stream3_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    4,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream3_syn, 4),
+    CreateMockRead(*stream1_body, 6, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 7),
+    MockRead(ASYNC, ERR_IO_PENDING, 8),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushMultipleDataFrame) {
+  static const unsigned char kPushBodyFrame1[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x1F,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  static const char kPushBodyFrame2[] = " my darling";
+  static const char kPushBodyFrame3[] = " hello";
+  static const char kPushBodyFrame4[] = " my baby";
+
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame1),
+             arraysize(kPushBodyFrame1), 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame2),
+             arraysize(kPushBodyFrame2) - 1, 5),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame3),
+             arraysize(kPushBodyFrame3) - 1, 6),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame4),
+             arraysize(kPushBodyFrame4) - 1, 7),
+    CreateMockRead(*stream1_body, 8, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 9),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed my darling hello my baby");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test,
+       ServerPushMultipleDataFrameInterrupted) {
+  static const unsigned char kPushBodyFrame1[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x1F,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  static const char kPushBodyFrame2[] = " my darling";
+  static const char kPushBodyFrame3[] = " hello";
+  static const char kPushBodyFrame4[] = " my baby";
+
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    1,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame1),
+             arraysize(kPushBodyFrame1), 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame2),
+             arraysize(kPushBodyFrame2) - 1, 5),
+    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame3),
+             arraysize(kPushBodyFrame3) - 1, 7),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame4),
+             arraysize(kPushBodyFrame4) - 1, 8),
+    CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS),
+    MockRead(ASYNC, ERR_IO_PENDING, 10)  // Force a pause.
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed my darling hello my baby");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushInvalidAssociatedStreamID0) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream2_rst(ConstructSpdyRstStream(2, REFUSED_STREAM));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream2_rst, 4),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    0,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushInvalidAssociatedStreamID9) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream2_rst(ConstructSpdyRstStream(2, INVALID_STREAM));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream2_rst, 4),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL,
+                                    0,
+                                    2,
+                                    9,
+                                    "http://www.google.com/foo.dat"));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushNoURL) {
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame>
+      stream2_rst(ConstructSpdyRstStream(2, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+    CreateMockWrite(*stream2_rst, 4),
+  };
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyPush(NULL, 0, 2, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream1_body, 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+// Verify that various SynReply headers parse correctly through the
+// HTTP layer.
+TEST_P(SpdyNetworkTransactionSpdy3Test, SynReplyHeaders) {
+  struct SynReplyHeadersTests {
+    int num_headers;
+    const char* extra_headers[5];
+    const char* expected_headers;
+  } test_cases[] = {
+    // This uses a multi-valued cookie header.
+    { 2,
+      { "cookie", "val1",
+        "cookie", "val2",  // will get appended separated by NULL
+        NULL
+      },
+      "status: 200\n"
+      "version: HTTP/1.1\n"
+      "cookie: val1\n"
+      "cookie: val2\n"
+      "hello: bye\n"
+    },
+    // This is the minimalist set of headers.
+    { 0,
+      { NULL },
+      "status: 200\n"
+      "version: HTTP/1.1\n"
+      "hello: bye\n"
+    },
+    // Headers with a comma separated list.
+    { 1,
+      { "cookie", "val1,val2",
+        NULL
+      },
+      "status: 200\n"
+      "version: HTTP/1.1\n"
+      "cookie: val1,val2\n"
+      "hello: bye\n"
+    }
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    scoped_ptr<SpdyFrame> req(
+        ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+    MockWrite writes[] = { CreateMockWrite(*req) };
+
+    scoped_ptr<SpdyFrame> resp(
+        ConstructSpdyGetSynReply(test_cases[i].extra_headers,
+                                 test_cases[i].num_headers,
+                                 1));
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*resp),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+
+    EXPECT_EQ(OK, out.rv);
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+    EXPECT_EQ("hello!", out.response_data);
+
+    scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
+    EXPECT_TRUE(headers.get() != NULL);
+    void* iter = NULL;
+    std::string name, value, lines;
+    while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+      lines.append(name);
+      lines.append(": ");
+      lines.append(value);
+      lines.append("\n");
+    }
+    EXPECT_EQ(std::string(test_cases[i].expected_headers), lines);
+  }
+}
+
+// Verify that various SynReply headers parse vary fields correctly
+// through the HTTP layer, and the response matches the request.
+TEST_P(SpdyNetworkTransactionSpdy3Test, SynReplyHeadersVary) {
+  static const SpdyHeaderInfo syn_reply_info = {
+    SYN_REPLY,                              // Syn Reply
+    1,                                      // Stream ID
+    0,                                      // Associated Stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                                      // Credential Slot
+    CONTROL_FLAG_NONE,                      // Control Flags
+    false,                                  // Compressed
+    INVALID,                                // Status
+    NULL,                                   // Data
+    0,                                      // Data Length
+    DATA_FLAG_NONE                          // Data Flags
+  };
+  // Modify the following data to change/add test cases:
+  struct SynReplyTests {
+    const SpdyHeaderInfo* syn_reply;
+    bool vary_matches;
+    int num_headers[2];
+    const char* extra_headers[2][16];
+  } test_cases[] = {
+    // Test the case of a multi-valued cookie.  When the value is delimited
+    // with NUL characters, it needs to be unfolded into multiple headers.
+    {
+      &syn_reply_info,
+      true,
+      { 1, 4 },
+      { { "cookie",   "val1,val2",
+          NULL
+        },
+        { ":status",   "200",
+          ":version",  "HTTP/1.1",
+          "vary",     "cookie",
+          "url",      "/index.php",
+          NULL
+        }
+      }
+    }, {    // Multiple vary fields.
+      &syn_reply_info,
+      true,
+      { 2, 5 },
+      { { "friend",   "barney",
+          "enemy",    "snaggletooth",
+          NULL
+        },
+        { ":status",   "200",
+          ":version",  "HTTP/1.1",
+          "vary",     "friend",
+          "vary",     "enemy",
+          "url",      "/index.php",
+          NULL
+        }
+      }
+    }, {    // Test a '*' vary field.
+      &syn_reply_info,
+      false,
+      { 1, 4 },
+      { { "cookie",   "val1,val2",
+          NULL
+        },
+        { ":status",   "200",
+          ":version",  "HTTP/1.1",
+          "vary",     "*",
+          "url",      "/index.php",
+          NULL
+        }
+      }
+    }, {    // Multiple comma-separated vary fields.
+      &syn_reply_info,
+      true,
+      { 2, 4 },
+      { { "friend",   "barney",
+          "enemy",    "snaggletooth",
+          NULL
+        },
+        { ":status",   "200",
+          ":version",  "HTTP/1.1",
+          "vary",     "friend,enemy",
+          "url",      "/index.php",
+          NULL
+        }
+      }
+    }
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    // Construct the request.
+    scoped_ptr<SpdyFrame> frame_req(
+      ConstructSpdyGet(test_cases[i].extra_headers[0],
+                       test_cases[i].num_headers[0],
+                       false, 1, LOWEST));
+
+    MockWrite writes[] = {
+      CreateMockWrite(*frame_req),
+    };
+
+    // Construct the reply.
+    scoped_ptr<SpdyFrame> frame_reply(
+      ConstructSpdyPacket(*test_cases[i].syn_reply,
+                          test_cases[i].extra_headers[1],
+                          test_cases[i].num_headers[1],
+                          NULL,
+                          0));
+
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*frame_reply),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    // Attach the headers to the request.
+    int header_count = test_cases[i].num_headers[0];
+
+    HttpRequestInfo request = CreateGetRequest();
+    for (int ct = 0; ct < header_count; ct++) {
+      const char* header_key = test_cases[i].extra_headers[0][ct * 2];
+      const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1];
+      request.extra_headers.SetHeader(header_key, header_value);
+    }
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(request,
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+
+    EXPECT_EQ(OK, out.rv) << i;
+    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i;
+    EXPECT_EQ("hello!", out.response_data) << i;
+
+    // Test the response information.
+    EXPECT_TRUE(out.response_info.response_time >
+                out.response_info.request_time) << i;
+    base::TimeDelta test_delay = out.response_info.response_time -
+                                 out.response_info.request_time;
+    base::TimeDelta min_expected_delay;
+    min_expected_delay.FromMilliseconds(10);
+    EXPECT_GT(test_delay.InMillisecondsF(),
+              min_expected_delay.InMillisecondsF()) << i;
+    EXPECT_EQ(out.response_info.vary_data.is_valid(),
+              test_cases[i].vary_matches) << i;
+
+    // Check the headers.
+    scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
+    ASSERT_TRUE(headers.get() != NULL) << i;
+    void* iter = NULL;
+    std::string name, value, lines;
+    while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+      lines.append(name);
+      lines.append(": ");
+      lines.append(value);
+      lines.append("\n");
+    }
+
+    // Construct the expected header reply string.
+    char reply_buffer[256] = "";
+    ConstructSpdyReplyString(test_cases[i].extra_headers[1],
+                             test_cases[i].num_headers[1],
+                             reply_buffer,
+                             256);
+
+    EXPECT_EQ(std::string(reply_buffer), lines) << i;
+  }
+}
+
+// Verify that we don't crash on invalid SynReply responses.
+TEST_P(SpdyNetworkTransactionSpdy3Test, InvalidSynReply) {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_REPLY,              // Kind = SynReply
+    1,                      // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                      // Credential Slot
+    CONTROL_FLAG_NONE,      // Control Flags
+    false,                  // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+
+  struct InvalidSynReplyTests {
+    int num_headers;
+    const char* headers[10];
+  } test_cases[] = {
+    // SYN_REPLY missing status header
+    { 4,
+      { "cookie", "val1",
+        "cookie", "val2",
+        "url", "/index.php",
+        "version", "HTTP/1.1",
+        NULL
+      },
+    },
+    // SYN_REPLY missing version header
+    { 2,
+      { ":status", "200",
+        "url", "/index.php",
+        NULL
+      },
+    },
+    // SYN_REPLY with no headers
+    { 0, { NULL }, },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    scoped_ptr<SpdyFrame> req(
+        ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+    MockWrite writes[] = {
+      CreateMockWrite(*req),
+    };
+
+    scoped_ptr<SpdyFrame> resp(
+        ConstructSpdyPacket(kSynStartHeader,
+                            NULL, 0,
+                            test_cases[i].headers,
+                            test_cases[i].num_headers));
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*resp),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+    EXPECT_EQ(ERR_INCOMPLETE_SPDY_HEADERS, out.rv);
+  }
+}
+
+// Verify that we don't crash on some corrupt frames.
+TEST_P(SpdyNetworkTransactionSpdy3Test, CorruptFrameSessionError) {
+  // This is the length field that's too short.
+  scoped_ptr<SpdyFrame> syn_reply_wrong_length(
+      ConstructSpdyGetSynReply(NULL, 0, 1));
+  syn_reply_wrong_length->set_length(syn_reply_wrong_length->length() - 4);
+
+  struct SynReplyTests {
+    const SpdyFrame* syn_reply;
+  } test_cases[] = {
+    { syn_reply_wrong_length.get(), },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    scoped_ptr<SpdyFrame> req(
+        ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+    MockWrite writes[] = {
+      CreateMockWrite(*req),
+      MockWrite(ASYNC, 0, 0)  // EOF
+    };
+
+    scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+    MockRead reads[] = {
+      CreateMockRead(*test_cases[i].syn_reply),
+      CreateMockRead(*body),
+      MockRead(ASYNC, 0, 0)  // EOF
+    };
+
+    DelayedSocketData data(1, reads, arraysize(reads),
+                           writes, arraysize(writes));
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.RunToCompletion(&data);
+    TransactionHelperResult out = helper.output();
+    EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+  }
+}
+
+// Test that we shutdown correctly on write errors.
+TEST_P(SpdyNetworkTransactionSpdy3Test, WriteError) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    // We'll write 10 bytes successfully
+    MockWrite(ASYNC, req->data(), 10),
+    // Followed by ERROR!
+    MockWrite(ASYNC, ERR_FAILED),
+  };
+
+  DelayedSocketData data(2, NULL, 0,
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_FAILED, out.rv);
+  data.Reset();
+}
+
+// Test that partial writes work.
+TEST_P(SpdyNetworkTransactionSpdy3Test, PartialWrite) {
+  // Chop the SYN_STREAM frame into 5 chunks.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  const int kChunks = 5;
+  scoped_array<MockWrite> writes(ChopWriteFrame(*req.get(), kChunks));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(kChunks, reads, arraysize(reads),
+                         writes.get(), kChunks);
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+// In this test, we enable compression, but get a uncompressed SynReply from
+// the server.  Verify that teardown is all clean.
+TEST_P(SpdyNetworkTransactionSpdy3Test, DecompressFailureOnSynReply) {
+  scoped_ptr<SpdyFrame> compressed(
+      ConstructSpdyGet(NULL, 0, true, 1, LOWEST));
+  scoped_ptr<SpdyFrame> rst(
+      ConstructSpdyRstStream(1, PROTOCOL_ERROR));
+  MockWrite writes[] = {
+    CreateMockWrite(*compressed),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  SpdySessionDependencies* session_deps = new SpdySessionDependencies();
+  session_deps->enable_compression = true;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), session_deps);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+  data.Reset();
+}
+
+// Test that the NetLog contains good data for a simple GET request.
+TEST_P(SpdyNetworkTransactionSpdy3Test, NetLog) {
+  static const char* const kExtraHeaders[] = {
+    "user-agent",   "Chrome",
+  };
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(kExtraHeaders, 1, false, 1,
+                                                   LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  CapturingBoundNetLog log;
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(),
+                                     log.bound(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  // Check that the NetLog was filled reasonably.
+  // This test is intentionally non-specific about the exact ordering of the
+  // log; instead we just check to make sure that certain events exist, and that
+  // they are in the right order.
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_LT(0u, entries.size());
+  int pos = 0;
+  pos = net::ExpectLogContainsSomewhere(entries, 0,
+      net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
+      net::NetLog::PHASE_BEGIN);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
+      net::NetLog::PHASE_END);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
+      net::NetLog::PHASE_BEGIN);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
+      net::NetLog::PHASE_END);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
+      net::NetLog::PHASE_BEGIN);
+  pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
+      net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
+      net::NetLog::PHASE_END);
+
+  // Check that we logged all the headers correctly
+  pos = net::ExpectLogContainsSomewhere(
+      entries, 0,
+      net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
+      net::NetLog::PHASE_NONE);
+
+  ListValue* header_list;
+  ASSERT_TRUE(entries[pos].params.get());
+  ASSERT_TRUE(entries[pos].params->GetList("headers", &header_list));
+
+  std::vector<std::string> expected;
+  expected.push_back(":host: www.google.com");
+  expected.push_back(":path: /");
+  expected.push_back(":scheme: http");
+  expected.push_back(":version: HTTP/1.1");
+  expected.push_back(":method: GET");
+  expected.push_back("user-agent: Chrome");
+  EXPECT_EQ(expected.size(), header_list->GetSize());
+  for (std::vector<std::string>::const_iterator it = expected.begin();
+       it != expected.end();
+       ++it) {
+    base::StringValue header(*it);
+    EXPECT_NE(header_list->end(), header_list->Find(header)) <<
+        "Header not found: " << *it;
+  }
+}
+
+// Since we buffer the IO from the stream to the renderer, this test verifies
+// that when we read out the maximum amount of data (e.g. we received 50 bytes
+// on the network, but issued a Read for only 5 of those bytes) that the data
+// flow still works correctly.
+TEST_P(SpdyNetworkTransactionSpdy3Test, BufferFull) {
+  BufferedSpdyFramer framer(3, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // 2 data frames in a single read.
+  scoped_ptr<SpdyFrame> data_frame_1(
+      framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE));
+  scoped_ptr<SpdyFrame> data_frame_2(
+      framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE));
+  const SpdyFrame* data_frames[2] = {
+    data_frame_1.get(),
+    data_frame_2.get(),
+  };
+  char combined_data_frames[100];
+  int combined_data_frames_len =
+      CombineFrames(data_frames, arraysize(data_frames),
+                    combined_data_frames, arraysize(combined_data_frames));
+  scoped_ptr<SpdyFrame> last_frame(
+      framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
+    MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
+    CreateMockRead(*last_frame),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  TestCompletionCallback callback;
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 3;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      data.CompleteRead();
+      rv = read_callback.WaitForResult();
+    }
+    if (rv > 0) {
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      NOTREACHED();
+    }
+  } while (rv > 0);
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("goodbye world", out.response_data);
+}
+
+// Verify that basic buffering works; when multiple data frames arrive
+// at the same time, ensure that we don't notify a read completion for
+// each data frame individually.
+TEST_P(SpdyNetworkTransactionSpdy3Test, Buffering) {
+  BufferedSpdyFramer framer(3, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // 4 data frames in a single read.
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+  scoped_ptr<SpdyFrame> data_frame_fin(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
+  const SpdyFrame* data_frames[4] = {
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame_fin.get()
+  };
+  char combined_data_frames[100];
+  int combined_data_frames_len =
+      CombineFrames(data_frames, arraysize(data_frames),
+                    combined_data_frames, arraysize(combined_data_frames));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
+    MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  int reads_completed = 0;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 14;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      data.CompleteRead();
+      rv = read_callback.WaitForResult();
+    }
+    if (rv > 0) {
+      EXPECT_EQ(kSmallReadSize, rv);
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      FAIL() << "Unexpected read error: " << rv;
+    }
+    reads_completed++;
+  } while (rv > 0);
+
+  EXPECT_EQ(3, reads_completed);  // Reads are: 14 bytes, 14 bytes, 0 bytes.
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("messagemessagemessagemessage", out.response_data);
+}
+
+// Verify the case where we buffer data but read it after it has been buffered.
+TEST_P(SpdyNetworkTransactionSpdy3Test, BufferedAll) {
+  BufferedSpdyFramer framer(3, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // 5 data frames in a single read.
+  scoped_ptr<SpdyFrame> syn_reply(
+      ConstructSpdyGetSynReply(NULL, 0, 1));
+  syn_reply->set_flags(CONTROL_FLAG_NONE);  // turn off FIN bit
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+  scoped_ptr<SpdyFrame> data_frame_fin(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
+  const SpdyFrame* frames[5] = {
+    syn_reply.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame_fin.get()
+  };
+  char combined_frames[200];
+  int combined_frames_len =
+      CombineFrames(frames, arraysize(frames),
+                    combined_frames, arraysize(combined_frames));
+
+  MockRead reads[] = {
+    MockRead(ASYNC, combined_frames, combined_frames_len),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  int reads_completed = 0;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 14;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv > 0) {
+      EXPECT_EQ(kSmallReadSize, rv);
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      FAIL() << "Unexpected read error: " << rv;
+    }
+    reads_completed++;
+  } while (rv > 0);
+
+  EXPECT_EQ(3, reads_completed);
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("messagemessagemessagemessage", out.response_data);
+}
+
+// Verify the case where we buffer data and close the connection.
+TEST_P(SpdyNetworkTransactionSpdy3Test, BufferedClosed) {
+  BufferedSpdyFramer framer(3, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // All data frames in a single read.
+  // NOTE: We don't FIN the stream.
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+  const SpdyFrame* data_frames[4] = {
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get(),
+    data_frame.get()
+  };
+  char combined_data_frames[100];
+  int combined_data_frames_len =
+      CombineFrames(data_frames, arraysize(data_frames),
+                    combined_data_frames, arraysize(combined_data_frames));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
+    MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  std::string content;
+  int reads_completed = 0;
+  do {
+    // Read small chunks at a time.
+    const int kSmallReadSize = 14;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
+    rv = trans->Read(buf, kSmallReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      data.CompleteRead();
+      rv = read_callback.WaitForResult();
+    }
+    if (rv > 0) {
+      content.append(buf->data(), rv);
+    } else if (rv < 0) {
+      // This test intentionally closes the connection, and will get an error.
+      EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
+      break;
+    }
+    reads_completed++;
+  } while (rv > 0);
+
+  EXPECT_EQ(0, reads_completed);
+
+  out.response_data.swap(content);
+
+  // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
+  // MockClientSocketFactory) are still alive.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+}
+
+// Verify the case where we buffer data and cancel the transaction.
+TEST_P(SpdyNetworkTransactionSpdy3Test, BufferedCancelled) {
+  BufferedSpdyFramer framer(3, false);
+
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // NOTE: We don't FIN the stream.
+  scoped_ptr<SpdyFrame> data_frame(
+      framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
+    CreateMockRead(*data_frame),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TransactionHelperResult out = helper.output();
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.status_line = response->headers->GetStatusLine();
+  out.response_info = *response;  // Make a copy so we can verify.
+
+  // Read Data
+  TestCompletionCallback read_callback;
+
+  do {
+    const int kReadSize = 256;
+    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize));
+    rv = trans->Read(buf, kReadSize, read_callback.callback());
+    if (rv == net::ERR_IO_PENDING) {
+      // Complete the read now, which causes buffering to start.
+      data.CompleteRead();
+      // Destroy the transaction, causing the stream to get cancelled
+      // and orphaning the buffered IO task.
+      helper.ResetTrans();
+      break;
+    }
+    // We shouldn't get here in this test.
+    FAIL() << "Unexpected read: " << rv;
+  } while (rv > 0);
+
+  // Flush the MessageLoop; this will cause the buffered IO task
+  // to run for the final time.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+}
+
+// Test that if the server requests persistence of settings, that we save
+// the settings in the HttpServerProperties.
+TEST_P(SpdyNetworkTransactionSpdy3Test, SettingsSaved) {
+  static const SpdyHeaderInfo kSynReplyInfo = {
+    SYN_REPLY,                              // Syn Reply
+    1,                                      // Stream ID
+    0,                                      // Associated Stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                                      // Credential Slot
+    CONTROL_FLAG_NONE,                      // Control Flags
+    false,                                  // Compressed
+    INVALID,                                // Status
+    NULL,                                   // Data
+    0,                                      // Data Length
+    DATA_FLAG_NONE                          // Data Flags
+  };
+  static const char* const kExtraHeaders[] = {
+    ":status",   "200",
+    ":version",  "HTTP/1.1"
+  };
+
+  BoundNetLog net_log;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(), net_log,
+                                     GetParam(), NULL);
+  helper.RunPreTestSetup();
+
+  // Verify that no settings exist initially.
+  HostPortPair host_port_pair("www.google.com", helper.port());
+  SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+  EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
+      host_port_pair).empty());
+
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  // Construct the reply.
+  scoped_ptr<SpdyFrame> reply(
+    ConstructSpdyPacket(kSynReplyInfo,
+                        kExtraHeaders,
+                        arraysize(kExtraHeaders) / 2,
+                        NULL,
+                        0));
+
+  const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
+  unsigned int kSampleValue1 = 0x0a0a0a0a;
+  const SpdySettingsIds kSampleId2 = SETTINGS_DOWNLOAD_BANDWIDTH;
+  unsigned int kSampleValue2 = 0x0b0b0b0b;
+  const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME;
+  unsigned int kSampleValue3 = 0x0c0c0c0c;
+  scoped_ptr<SpdyFrame> settings_frame;
+  {
+    // Construct the SETTINGS frame.
+    SettingsMap settings;
+    // First add a persisted setting.
+    settings[kSampleId1] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue1);
+    // Next add a non-persisted setting.
+    settings[kSampleId2] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kSampleValue2);
+    // Next add another persisted setting.
+    settings[kSampleId3] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue3);
+    settings_frame.reset(ConstructSpdySettings(settings));
+  }
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*reply),
+    CreateMockRead(*body),
+    CreateMockRead(*settings_frame),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  helper.AddData(&data);
+  helper.RunDefaultTest();
+  helper.VerifyDataConsumed();
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  {
+    // Verify we had two persisted settings.
+    const SettingsMap& settings_map =
+        spdy_session_pool->http_server_properties()->GetSpdySettings(
+            host_port_pair);
+    ASSERT_EQ(2u, settings_map.size());
+
+    // Verify the first persisted setting.
+    SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
+    EXPECT_TRUE(it1 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value1 = it1->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
+    EXPECT_EQ(kSampleValue1, flags_and_value1.second);
+
+    // Verify the second persisted setting.
+    SettingsMap::const_iterator it3 = settings_map.find(kSampleId3);
+    EXPECT_TRUE(it3 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value3 = it3->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first);
+    EXPECT_EQ(kSampleValue3, flags_and_value3.second);
+  }
+}
+
+// Test that when there are settings saved that they are sent back to the
+// server upon session establishment.
+TEST_P(SpdyNetworkTransactionSpdy3Test, SettingsPlayback) {
+  static const SpdyHeaderInfo kSynReplyInfo = {
+    SYN_REPLY,                              // Syn Reply
+    1,                                      // Stream ID
+    0,                                      // Associated Stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                                      // Credential Slot
+    CONTROL_FLAG_NONE,                      // Control Flags
+    false,                                  // Compressed
+    INVALID,                                // Status
+    NULL,                                   // Data
+    0,                                      // Data Length
+    DATA_FLAG_NONE                          // Data Flags
+  };
+  static const char* kExtraHeaders[] = {
+    ":status",   "200",
+    ":version",  "HTTP/1.1"
+  };
+
+  BoundNetLog net_log;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(), net_log,
+                                     GetParam(), NULL);
+  helper.RunPreTestSetup();
+
+  // Verify that no settings exist initially.
+  HostPortPair host_port_pair("www.google.com", helper.port());
+  SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+  EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
+      host_port_pair).empty());
+
+  const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
+  unsigned int kSampleValue1 = 0x0a0a0a0a;
+  const SpdySettingsIds kSampleId2 = SETTINGS_ROUND_TRIP_TIME;
+  unsigned int kSampleValue2 = 0x0c0c0c0c;
+
+  // First add a persisted setting.
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      host_port_pair,
+      kSampleId1,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      kSampleValue1);
+
+  // Next add another persisted setting.
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      host_port_pair,
+      kSampleId2,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      kSampleValue2);
+
+  EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings(
+      host_port_pair).size());
+
+  // Construct the SETTINGS frame.
+  const SettingsMap& settings =
+      spdy_session_pool->http_server_properties()->GetSpdySettings(
+          host_port_pair);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+    CreateMockWrite(*req),
+  };
+
+  // Construct the reply.
+  scoped_ptr<SpdyFrame> reply(
+    ConstructSpdyPacket(kSynReplyInfo,
+                        kExtraHeaders,
+                        arraysize(kExtraHeaders) / 2,
+                        NULL,
+                        0));
+
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*reply),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(2, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  helper.AddData(&data);
+  helper.RunDefaultTest();
+  helper.VerifyDataConsumed();
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  {
+    // Verify we had two persisted settings.
+    const SettingsMap& settings_map =
+        spdy_session_pool->http_server_properties()->GetSpdySettings(
+            host_port_pair);
+    ASSERT_EQ(2u, settings_map.size());
+
+    // Verify the first persisted setting.
+    SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
+    EXPECT_TRUE(it1 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value1 = it1->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
+    EXPECT_EQ(kSampleValue1, flags_and_value1.second);
+
+    // Verify the second persisted setting.
+    SettingsMap::const_iterator it2 = settings_map.find(kSampleId2);
+    EXPECT_TRUE(it2 != settings_map.end());
+    SettingsFlagsAndValue flags_and_value2 = it2->second;
+    EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first);
+    EXPECT_EQ(kSampleValue2, flags_and_value2.second);
+  }
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, GoAwayWithActiveStream) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> go_away(ConstructSpdyGoAway());
+  MockRead reads[] = {
+    CreateMockRead(*go_away),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.AddData(&data);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_ABORTED, out.rv);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, CloseWithActiveStream) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  BoundNetLog log;
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     log, GetParam(), NULL);
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  TransactionHelperResult out;
+  out.rv = trans->Start(&CreateGetRequest(), callback.callback(), log);
+
+  EXPECT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.rv = ReadTransaction(trans, &out.response_data);
+  EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv);
+
+  // Verify that we consumed all test data.
+  helper.VerifyDataConsumed();
+}
+
+// Test to make sure we can correctly connect through a proxy.
+TEST_P(SpdyNetworkTransactionSpdy3Test, ProxyConnect) {
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.session_deps().reset(new SpdySessionDependencies(
+      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")));
+  helper.SetSession(make_scoped_refptr(
+      SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
+  helper.RunPreTestSetup();
+  HttpNetworkTransaction* trans = helper.trans();
+
+  const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+
+  MockWrite writes_SPDYNPN[] = {
+    MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
+    CreateMockWrite(*req, 2),
+  };
+  MockRead reads_SPDYNPN[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*body.get(), 4),
+    MockRead(ASYNC, 0, 0, 5),
+  };
+
+  MockWrite writes_SPDYSSL[] = {
+    MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
+    CreateMockWrite(*req, 2),
+  };
+  MockRead reads_SPDYSSL[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp, 3),
+    CreateMockRead(*body.get(), 4),
+    MockRead(ASYNC, 0, 0, 5),
+  };
+
+  MockWrite writes_SPDYNOSSL[] = {
+    CreateMockWrite(*req, 0),
+  };
+
+  MockRead reads_SPDYNOSSL[] = {
+    CreateMockRead(*resp, 1),
+    CreateMockRead(*body.get(), 2),
+    MockRead(ASYNC, 0, 0, 3),
+  };
+
+  scoped_ptr<OrderedSocketData> data;
+  switch(GetParam()) {
+    case SPDYNOSSL:
+      data.reset(new OrderedSocketData(reads_SPDYNOSSL,
+                                       arraysize(reads_SPDYNOSSL),
+                                       writes_SPDYNOSSL,
+                                       arraysize(writes_SPDYNOSSL)));
+      break;
+    case SPDYSSL:
+      data.reset(new OrderedSocketData(reads_SPDYSSL,
+                                       arraysize(reads_SPDYSSL),
+                                       writes_SPDYSSL,
+                                       arraysize(writes_SPDYSSL)));
+      break;
+    case SPDYNPN:
+      data.reset(new OrderedSocketData(reads_SPDYNPN,
+                                       arraysize(reads_SPDYNPN),
+                                       writes_SPDYNPN,
+                                       arraysize(writes_SPDYNPN)));
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  helper.AddData(data.get());
+  TestCompletionCallback callback;
+
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  std::string response_data;
+  ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
+  EXPECT_EQ("hello!", response_data);
+  helper.VerifyDataConsumed();
+}
+
+// Test to make sure we can correctly connect through a proxy to www.google.com,
+// if there already exists a direct spdy connection to www.google.com. See
+// http://crbug.com/49874
+TEST_P(SpdyNetworkTransactionSpdy3Test, DirectConnectProxyReconnect) {
+  // When setting up the first transaction, we store the SpdySessionPool so that
+  // we can use the same pool in the second transaction.
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  // Use a proxy service which returns a proxy fallback list from DIRECT to
+  // myproxy:70. For this test there will be no fallback, so it is equivalent
+  // to simply DIRECT. The reason for appending the second proxy is to verify
+  // that the session pool key used does is just "DIRECT".
+  helper.session_deps().reset(new SpdySessionDependencies(
+      ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70")));
+  helper.SetSession(make_scoped_refptr(
+      SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
+
+  SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+  helper.RunPreTestSetup();
+
+  // Construct and send a simple GET request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 2),
+    CreateMockRead(*body, 3),
+    MockRead(ASYNC, ERR_IO_PENDING, 4),  // Force a pause
+    MockRead(ASYNC, 0, 5)  // EOF
+  };
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+
+  TestCompletionCallback callback;
+  TransactionHelperResult out;
+  out.rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+
+  EXPECT_EQ(out.rv, ERR_IO_PENDING);
+  out.rv = callback.WaitForResult();
+  EXPECT_EQ(out.rv, OK);
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  EXPECT_TRUE(response->headers != NULL);
+  EXPECT_TRUE(response->was_fetched_via_spdy);
+  out.rv = ReadTransaction(trans, &out.response_data);
+  EXPECT_EQ(OK, out.rv);
+  out.status_line = response->headers->GetStatusLine();
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  // Check that the SpdySession is still in the SpdySessionPool.
+  HostPortPair host_port_pair("www.google.com", helper.port());
+  HostPortProxyPair session_pool_key_direct(
+      host_port_pair, ProxyServer::Direct());
+  EXPECT_TRUE(spdy_session_pool->HasSession(session_pool_key_direct));
+  HostPortProxyPair session_pool_key_proxy(
+      host_port_pair,
+      ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP));
+  EXPECT_FALSE(spdy_session_pool->HasSession(session_pool_key_proxy));
+
+  // Set up data for the proxy connection.
+  const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
+                           "Host: www.google.com\r\n"
+                           "Proxy-Connection: keep-alive\r\n\r\n"};
+  const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(
+      "http://www.google.com/foo.dat", false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+
+  MockWrite writes_SPDYNPN[] = {
+    MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
+    CreateMockWrite(*req2, 2),
+  };
+  MockRead reads_SPDYNPN[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp2, 3),
+    CreateMockRead(*body2, 4),
+    MockRead(ASYNC, 0, 5)  // EOF
+  };
+
+  MockWrite writes_SPDYNOSSL[] = {
+    CreateMockWrite(*req2, 0),
+  };
+  MockRead reads_SPDYNOSSL[] = {
+    CreateMockRead(*resp2, 1),
+    CreateMockRead(*body2, 2),
+    MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  MockWrite writes_SPDYSSL[] = {
+    MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
+    CreateMockWrite(*req2, 2),
+  };
+  MockRead reads_SPDYSSL[] = {
+    MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
+    CreateMockRead(*resp2, 3),
+    CreateMockRead(*body2, 4),
+    MockRead(ASYNC, 0, 0, 5),
+  };
+
+  scoped_ptr<OrderedSocketData> data_proxy;
+  switch(GetParam()) {
+    case SPDYNPN:
+      data_proxy.reset(new OrderedSocketData(reads_SPDYNPN,
+                                             arraysize(reads_SPDYNPN),
+                                             writes_SPDYNPN,
+                                             arraysize(writes_SPDYNPN)));
+      break;
+    case SPDYNOSSL:
+      data_proxy.reset(new OrderedSocketData(reads_SPDYNOSSL,
+                                             arraysize(reads_SPDYNOSSL),
+                                             writes_SPDYNOSSL,
+                                             arraysize(writes_SPDYNOSSL)));
+      break;
+    case SPDYSSL:
+      data_proxy.reset(new OrderedSocketData(reads_SPDYSSL,
+                                             arraysize(reads_SPDYSSL),
+                                             writes_SPDYSSL,
+                                             arraysize(writes_SPDYSSL)));
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  // Create another request to www.google.com, but this time through a proxy.
+  HttpRequestInfo request_proxy;
+  request_proxy.method = "GET";
+  request_proxy.url = GURL("http://www.google.com/foo.dat");
+  request_proxy.load_flags = 0;
+  scoped_ptr<SpdySessionDependencies> ssd_proxy(new SpdySessionDependencies());
+  // Ensure that this transaction uses the same SpdySessionPool.
+  scoped_refptr<HttpNetworkSession> session_proxy(
+      SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get()));
+  NormalSpdyTransactionHelper helper_proxy(request_proxy,
+                                           BoundNetLog(), GetParam(), NULL);
+  HttpNetworkSessionPeer session_peer(session_proxy);
+  scoped_ptr<net::ProxyService> proxy_service(
+          ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+  session_peer.SetProxyService(proxy_service.get());
+  helper_proxy.session_deps().swap(ssd_proxy);
+  helper_proxy.SetSession(session_proxy);
+  helper_proxy.RunPreTestSetup();
+  helper_proxy.AddData(data_proxy.get());
+
+  HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
+  TestCompletionCallback callback_proxy;
+  int rv = trans_proxy->Start(
+      &request_proxy, callback_proxy.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback_proxy.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
+  EXPECT_TRUE(response_proxy.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine());
+
+  std::string response_data;
+  ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data));
+  EXPECT_EQ("hello!", response_data);
+
+  data.CompleteRead();
+  helper_proxy.VerifyDataConsumed();
+}
+
+// When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
+// on a new connection, if the connection was previously known to be good.
+// This can happen when a server reboots without saying goodbye, or when
+// we're behind a NAT that masked the RST.
+TEST_P(SpdyNetworkTransactionSpdy3Test, VerifyRetryOnConnectionReset) {
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, ERR_IO_PENDING),
+    MockRead(ASYNC, ERR_CONNECTION_RESET),
+  };
+
+  MockRead reads2[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  // This test has a couple of variants.
+  enum {
+    // Induce the RST while waiting for our transaction to send.
+    VARIANT_RST_DURING_SEND_COMPLETION,
+    // Induce the RST while waiting for our transaction to read.
+    // In this case, the send completed - everything copied into the SNDBUF.
+    VARIANT_RST_DURING_READ_COMPLETION
+  };
+
+  for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
+       variant <= VARIANT_RST_DURING_READ_COMPLETION;
+       ++variant) {
+    DelayedSocketData data1(1, reads, arraysize(reads), NULL, 0);
+
+    DelayedSocketData data2(1, reads2, arraysize(reads2), NULL, 0);
+
+    NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                       BoundNetLog(), GetParam(), NULL);
+    helper.AddData(&data1);
+    helper.AddData(&data2);
+    helper.RunPreTestSetup();
+
+    for (int i = 0; i < 2; ++i) {
+      scoped_ptr<HttpNetworkTransaction> trans(
+          new HttpNetworkTransaction(helper.session()));
+
+      TestCompletionCallback callback;
+      int rv = trans->Start(
+          &helper.request(), callback.callback(), BoundNetLog());
+      EXPECT_EQ(ERR_IO_PENDING, rv);
+      // On the second transaction, we trigger the RST.
+      if (i == 1) {
+        if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
+          // Writes to the socket complete asynchronously on SPDY by running
+          // through the message loop.  Complete the write here.
+          MessageLoop::current()->RunUntilIdle();
+        }
+
+        // Now schedule the ERR_CONNECTION_RESET.
+        EXPECT_EQ(3u, data1.read_index());
+        data1.CompleteRead();
+        EXPECT_EQ(4u, data1.read_index());
+      }
+      rv = callback.WaitForResult();
+      EXPECT_EQ(OK, rv);
+
+      const HttpResponseInfo* response = trans->GetResponseInfo();
+      ASSERT_TRUE(response != NULL);
+      EXPECT_TRUE(response->headers != NULL);
+      EXPECT_TRUE(response->was_fetched_via_spdy);
+      std::string response_data;
+      rv = ReadTransaction(trans.get(), &response_data);
+      EXPECT_EQ(OK, rv);
+      EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+      EXPECT_EQ("hello!", response_data);
+    }
+
+    helper.VerifyDataConsumed();
+  }
+}
+
+// Test that turning SPDY on and off works properly.
+TEST_P(SpdyNetworkTransactionSpdy3Test, SpdyOnOffToggle) {
+  net::HttpStreamFactory::set_spdy_enabled(true);
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+  MockRead spdy_reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, spdy_reads, arraysize(spdy_reads),
+                         spdy_writes, arraysize(spdy_writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+
+  net::HttpStreamFactory::set_spdy_enabled(false);
+  MockRead http_reads[] = {
+    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+    MockRead("hello from http"),
+    MockRead(SYNCHRONOUS, OK),
+  };
+  DelayedSocketData data2(1, http_reads, arraysize(http_reads), NULL, 0);
+  NormalSpdyTransactionHelper helper2(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper2.SetSpdyDisabled();
+  helper2.RunToCompletion(&data2);
+  TransactionHelperResult out2 = helper2.output();
+  EXPECT_EQ(OK, out2.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line);
+  EXPECT_EQ("hello from http", out2.response_data);
+
+  net::HttpStreamFactory::set_spdy_enabled(true);
+}
+
+// Tests that Basic authentication works over SPDY
+TEST_P(SpdyNetworkTransactionSpdy3Test, SpdyBasicAuth) {
+  net::HttpStreamFactory::set_spdy_enabled(true);
+
+  // The first request will be a bare GET, the second request will be a
+  // GET with an Authorization header.
+  scoped_ptr<SpdyFrame> req_get(
+      ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  const char* const kExtraAuthorizationHeaders[] = {
+    "authorization",
+    "Basic Zm9vOmJhcg==",
+  };
+  scoped_ptr<SpdyFrame> req_get_authorization(
+      ConstructSpdyGet(
+          kExtraAuthorizationHeaders,
+          arraysize(kExtraAuthorizationHeaders) / 2,
+          false, 3, LOWEST));
+  MockWrite spdy_writes[] = {
+    CreateMockWrite(*req_get, 1),
+    CreateMockWrite(*req_get_authorization, 4),
+  };
+
+  // The first response is a 401 authentication challenge, and the second
+  // response will be a 200 response since the second request includes a valid
+  // Authorization header.
+  const char* const kExtraAuthenticationHeaders[] = {
+    "www-authenticate",
+    "Basic realm=\"MyRealm\""
+  };
+  scoped_ptr<SpdyFrame> resp_authentication(
+      ConstructSpdySynReplyError(
+          "401 Authentication Required",
+          kExtraAuthenticationHeaders,
+          arraysize(kExtraAuthenticationHeaders) / 2,
+          1));
+  scoped_ptr<SpdyFrame> body_authentication(
+      ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true));
+  MockRead spdy_reads[] = {
+    CreateMockRead(*resp_authentication, 2),
+    CreateMockRead(*body_authentication, 3),
+    CreateMockRead(*resp_data, 5),
+    CreateMockRead(*body_data, 6),
+    MockRead(ASYNC, 0, 7),
+  };
+
+  OrderedSocketData data(spdy_reads, arraysize(spdy_reads),
+                         spdy_writes, arraysize(spdy_writes));
+  HttpRequestInfo request(CreateGetRequest());
+  BoundNetLog net_log;
+  NormalSpdyTransactionHelper helper(request, net_log, GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+  HttpNetworkTransaction* trans = helper.trans();
+  TestCompletionCallback callback;
+  const int rv_start = trans->Start(&request, callback.callback(), net_log);
+  EXPECT_EQ(ERR_IO_PENDING, rv_start);
+  const int rv_start_complete = callback.WaitForResult();
+  EXPECT_EQ(OK, rv_start_complete);
+
+  // Make sure the response has an auth challenge.
+  const HttpResponseInfo* const response_start = trans->GetResponseInfo();
+  ASSERT_TRUE(response_start != NULL);
+  ASSERT_TRUE(response_start->headers != NULL);
+  EXPECT_EQ(401, response_start->headers->response_code());
+  EXPECT_TRUE(response_start->was_fetched_via_spdy);
+  AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get();
+  ASSERT_TRUE(auth_challenge != NULL);
+  EXPECT_FALSE(auth_challenge->is_proxy);
+  EXPECT_EQ("basic", auth_challenge->scheme);
+  EXPECT_EQ("MyRealm", auth_challenge->realm);
+
+  // Restart with a username/password.
+  AuthCredentials credentials(ASCIIToUTF16("foo"), ASCIIToUTF16("bar"));
+  TestCompletionCallback callback_restart;
+  const int rv_restart = trans->RestartWithAuth(
+      credentials, callback_restart.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv_restart);
+  const int rv_restart_complete = callback_restart.WaitForResult();
+  EXPECT_EQ(OK, rv_restart_complete);
+  // TODO(cbentzel): This is actually the same response object as before, but
+  // data has changed.
+  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
+  ASSERT_TRUE(response_restart != NULL);
+  ASSERT_TRUE(response_restart->headers != NULL);
+  EXPECT_EQ(200, response_restart->headers->response_code());
+  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushWithHeaders) {
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 1),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    ":scheme", "http",
+    ":host", "www.google.com",
+    ":path", "/foo.dat",
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+    ":status",
+    "200",
+    ":version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame>
+    stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                          arraysize(kInitialHeaders) / 2,
+                                          false,
+                                          2,
+                                          LOWEST,
+                                          SYN_STREAM,
+                                          CONTROL_FLAG_NONE,
+                                          NULL,
+                                          0,
+                                          1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                2,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 2),
+    CreateMockRead(*stream2_syn, 3),
+    CreateMockRead(*stream2_headers, 4),
+    CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 6),
+    MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  RunServerPushTest(&data,
+                    &response,
+                    &response2,
+                    expected_push_result);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushClaimBeforeHeaders) {
+  // We push a stream and attempt to claim it before the headers come down.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    ":scheme", "http",
+    ":host", "www.google.com",
+    ":path", "/foo.dat"
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+    ":status",
+    "200",
+    ":version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                            arraysize(kInitialHeaders) / 2,
+                                            false,
+                                            2,
+                                            LOWEST,
+                                            SYN_STREAM,
+                                            CONTROL_FLAG_NONE,
+                                            NULL,
+                                            0,
+                                            1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                2,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 1),
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_body, 3),
+    CreateMockRead(*stream2_headers, 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, 0, 6),  // EOF
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.AddDeterministicData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+  // and the body of the primary stream, but before we've received the HEADERS
+  // for the pushed stream.
+  data.SetStop(3);
+
+  // Start the transaction.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.Run();
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Request the pushed path.  At this point, we've received the push, but the
+  // headers are not yet complete.
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(
+      &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.RunFor(3);
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read the server push body.
+  std::string result2;
+  ReadResult(trans2.get(), &data, &result2);
+  // Read the response body.
+  std::string result;
+  ReadResult(trans, &data, &result);
+
+  // Verify that the received push data is same as the expected push data.
+  EXPECT_EQ(result2.compare(expected_push_result), 0)
+      << "Received data: "
+      << result2
+      << "||||| Expected data: "
+      << expected_push_result;
+
+  // Verify the SYN_REPLY.
+  // Copy the response info, because trans goes away.
+  response = *trans->GetResponseInfo();
+  response2 = *trans2->GetResponseInfo();
+
+  VerifyStreamsClosed(helper);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+
+  // Read the final EOF (which will close the session)
+  data.RunFor(1);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushWithTwoHeaderFrames) {
+  // We push a stream and attempt to claim it before the headers come down.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    ":scheme", "http",
+    ":host", "www.google.com",
+    ":path", "/foo.dat"
+  };
+  static const char* const kMiddleHeaders[] = {
+    "hello",
+    "bye",
+  };
+  static const char* const kLateHeaders[] = {
+    ":status",
+    "200",
+    ":version",
+    "HTTP/1.1"
+  };
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                            arraysize(kInitialHeaders) / 2,
+                                            false,
+                                            2,
+                                            LOWEST,
+                                            SYN_STREAM,
+                                            CONTROL_FLAG_NONE,
+                                            NULL,
+                                            0,
+                                            1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders,
+                                                 arraysize(kMiddleHeaders) / 2,
+                                                 false,
+                                                 2,
+                                                 LOWEST,
+                                                 HEADERS,
+                                                 CONTROL_FLAG_NONE,
+                                                 NULL,
+                                                 0,
+                                                 0));
+  scoped_ptr<SpdyFrame>
+      stream2_headers2(ConstructSpdyControlFrame(kLateHeaders,
+                                                 arraysize(kLateHeaders) / 2,
+                                                 false,
+                                                 2,
+                                                 LOWEST,
+                                                 HEADERS,
+                                                 CONTROL_FLAG_NONE,
+                                                 NULL,
+                                                 0,
+                                                 0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 1),
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_body, 3),
+    CreateMockRead(*stream2_headers1, 4),
+    CreateMockRead(*stream2_headers2, 5),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 6),
+    MockRead(ASYNC, 0, 7),  // EOF
+  };
+
+  HttpResponseInfo response;
+  HttpResponseInfo response2;
+  std::string expected_push_result("pushed");
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.AddDeterministicData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+  // the first HEADERS frame, and the body of the primary stream, but before
+  // we've received the final HEADERS for the pushed stream.
+  data.SetStop(4);
+
+  // Start the transaction.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.Run();
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Request the pushed path.  At this point, we've received the push, but the
+  // headers are not yet complete.
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(
+      &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.RunFor(3);
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read the server push body.
+  std::string result2;
+  ReadResult(trans2.get(), &data, &result2);
+  // Read the response body.
+  std::string result;
+  ReadResult(trans, &data, &result);
+
+  // Verify that the received push data is same as the expected push data.
+  EXPECT_EQ(result2.compare(expected_push_result), 0)
+      << "Received data: "
+      << result2
+      << "||||| Expected data: "
+      << expected_push_result;
+
+  // Verify the SYN_REPLY.
+  // Copy the response info, because trans goes away.
+  response = *trans->GetResponseInfo();
+  response2 = *trans2->GetResponseInfo();
+
+  VerifyStreamsClosed(helper);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Verify the pushed stream.
+  EXPECT_TRUE(response2.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+
+  // Verify we got all the headers
+  EXPECT_TRUE(response2.headers->HasHeaderValue(
+      "scheme", "http"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue(
+      "host", "www.google.com"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue(
+      "path", "/foo.dat"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
+  EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
+
+  // Read the final EOF (which will close the session)
+  data.RunFor(1);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushWithNoStatusHeaderFrames) {
+  // We push a stream and attempt to claim it before the headers come down.
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame>
+      stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockWrite writes[] = {
+    CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
+  };
+
+  static const char* const kInitialHeaders[] = {
+    ":scheme", "http",
+    ":host", "www.google.com",
+    ":path", "/foo.dat"
+  };
+  static const char* const kMiddleHeaders[] = {
+    "hello",
+    "bye",
+  };
+  scoped_ptr<SpdyFrame>
+      stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
+                                            arraysize(kInitialHeaders) / 2,
+                                            false,
+                                            2,
+                                            LOWEST,
+                                            SYN_STREAM,
+                                            CONTROL_FLAG_NONE,
+                                            NULL,
+                                            0,
+                                            1));
+  scoped_ptr<SpdyFrame>
+      stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders,
+                                                 arraysize(kMiddleHeaders) / 2,
+                                                 false,
+                                                 2,
+                                                 LOWEST,
+                                                 HEADERS,
+                                                 CONTROL_FLAG_NONE,
+                                                 NULL,
+                                                 0,
+                                                 0));
+
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply, 1),
+    CreateMockRead(*stream2_syn, 2),
+    CreateMockRead(*stream1_body, 3),
+    CreateMockRead(*stream2_headers1, 4),
+    MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+             arraysize(kPushBodyFrame), 5),
+    MockRead(ASYNC, 0, 6),  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.AddDeterministicData(&data);
+  helper.RunPreTestSetup();
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+  // the first HEADERS frame, and the body of the primary stream, but before
+  // we've received the final HEADERS for the pushed stream.
+  data.SetStop(4);
+
+  // Start the transaction.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.Run();
+  rv = callback.WaitForResult();
+  EXPECT_EQ(0, rv);
+
+  // Request the pushed path.  At this point, we've received the push, but the
+  // headers are not yet complete.
+  scoped_ptr<HttpNetworkTransaction> trans2(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(
+      &CreateGetPushRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  data.RunFor(2);
+  MessageLoop::current()->RunUntilIdle();
+
+  // Read the server push body.
+  std::string result2;
+  ReadResult(trans2.get(), &data, &result2);
+  // Read the response body.
+  std::string result;
+  ReadResult(trans, &data, &result);
+  EXPECT_EQ("hello!", result);
+
+  // Verify that we haven't received any push data.
+  EXPECT_EQ("", result2);
+
+  // Verify the SYN_REPLY.
+  // Copy the response info, because trans goes away.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  ASSERT_TRUE(trans2->GetResponseInfo() == NULL);
+
+  VerifyStreamsClosed(helper);
+
+  // Verify the SYN_REPLY.
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+
+  // Read the final EOF (which will close the session).
+  data.RunFor(1);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof());
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, SynReplyWithHeaders) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  static const char* const kInitialHeaders[] = {
+    ":status",
+    "200 OK",
+    ":version",
+    "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, SynReplyWithLateHeaders) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  static const char* const kInitialHeaders[] = {
+    ":status",
+    "200 OK",
+    ":version",
+    "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    "hello",
+    "bye",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_body),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body2),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(OK, out.rv);
+  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+  EXPECT_EQ("hello!hello!", out.response_data);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, SynReplyWithDuplicateLateHeaders) {
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = { CreateMockWrite(*req) };
+
+  static const char* const kInitialHeaders[] = {
+    ":status",
+    "200 OK",
+    ":version",
+    "HTTP/1.1"
+  };
+  static const char* const kLateHeaders[] = {
+    ":status",
+    "500 Server Error",
+  };
+  scoped_ptr<SpdyFrame>
+      stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
+                                              arraysize(kInitialHeaders) / 2,
+                                              false,
+                                              1,
+                                              LOWEST,
+                                              SYN_REPLY,
+                                              CONTROL_FLAG_NONE,
+                                              NULL,
+                                              0,
+                                              0));
+  scoped_ptr<SpdyFrame>
+      stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
+                                                arraysize(kLateHeaders) / 2,
+                                                false,
+                                                1,
+                                                LOWEST,
+                                                HEADERS,
+                                                CONTROL_FLAG_NONE,
+                                                NULL,
+                                                0,
+                                                0));
+  scoped_ptr<SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*stream1_reply),
+    CreateMockRead(*stream1_body),
+    CreateMockRead(*stream1_headers),
+    CreateMockRead(*stream1_body2),
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+
+  DelayedSocketData data(1, reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushCrossOriginCorrectness) {
+  // In this test we want to verify that we can't accidentally push content
+  // which can't be pushed by this content server.
+  // This test assumes that:
+  //   - if we're requesting http://www.foo.com/barbaz
+  //   - the browser has made a connection to "www.foo.com".
+
+  // A list of the URL to fetch, followed by the URL being pushed.
+  static const char* const kTestCases[] = {
+    "http://www.google.com/foo.html",
+    "http://www.google.com:81/foo.js",     // Bad port
+
+    "http://www.google.com/foo.html",
+    "https://www.google.com/foo.js",       // Bad protocol
+
+    "http://www.google.com/foo.html",
+    "ftp://www.google.com/foo.js",         // Invalid Protocol
+
+    "http://www.google.com/foo.html",
+    "http://blat.www.google.com/foo.js",   // Cross subdomain
+
+    "http://www.google.com/foo.html",
+    "http://www.foo.com/foo.js",           // Cross domain
+  };
+
+
+  static const unsigned char kPushBodyFrame[] = {
+    0x00, 0x00, 0x00, 0x02,                                      // header, ID
+    0x01, 0x00, 0x00, 0x06,                                      // FIN, length
+    'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
+  };
+
+  for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
+    const char* url_to_fetch = kTestCases[index];
+    const char* url_to_push = kTestCases[index + 1];
+
+    scoped_ptr<SpdyFrame>
+        stream1_syn(ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
+    scoped_ptr<SpdyFrame>
+        stream1_body(ConstructSpdyBodyFrame(1, true));
+    scoped_ptr<SpdyFrame> push_rst(
+        ConstructSpdyRstStream(2, REFUSED_STREAM));
+    MockWrite writes[] = {
+      CreateMockWrite(*stream1_syn, 1),
+      CreateMockWrite(*push_rst, 4),
+    };
+
+    scoped_ptr<SpdyFrame>
+        stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+    scoped_ptr<SpdyFrame>
+        stream2_syn(ConstructSpdyPush(NULL,
+                                      0,
+                                      2,
+                                      1,
+                                      url_to_push));
+    scoped_ptr<SpdyFrame> rst(
+        ConstructSpdyRstStream(2, CANCEL));
+
+    MockRead reads[] = {
+      CreateMockRead(*stream1_reply, 2),
+      CreateMockRead(*stream2_syn, 3),
+      CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
+      MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+               arraysize(kPushBodyFrame), 6),
+      MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
+    };
+
+    HttpResponseInfo response;
+    OrderedSocketData data(reads, arraysize(reads),
+                           writes, arraysize(writes));
+
+    HttpRequestInfo request;
+    request.method = "GET";
+    request.url = GURL(url_to_fetch);
+    request.load_flags = 0;
+
+    // Enable cross-origin push. Since we are not using a proxy, this should
+    // not actually enable cross-origin SPDY push.
+    scoped_ptr<SpdySessionDependencies> session_deps(
+        new SpdySessionDependencies());
+    session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
+    NormalSpdyTransactionHelper helper(request,
+                                       BoundNetLog(), GetParam(),
+                                       session_deps.release());
+    helper.RunPreTestSetup();
+    helper.AddData(&data);
+
+    HttpNetworkTransaction* trans = helper.trans();
+
+    // Start the transaction with basic parameters.
+    TestCompletionCallback callback;
+
+    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+    rv = callback.WaitForResult();
+
+    // Read the response body.
+    std::string result;
+    ReadResult(trans, &data, &result);
+
+    // Verify that we consumed all test data.
+    EXPECT_TRUE(data.at_read_eof());
+    EXPECT_TRUE(data.at_write_eof());
+
+    // Verify the SYN_REPLY.
+    // Copy the response info, because trans goes away.
+    response = *trans->GetResponseInfo();
+
+    VerifyStreamsClosed(helper);
+
+    // Verify the SYN_REPLY.
+    EXPECT_TRUE(response.headers != NULL);
+    EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+  }
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, RetryAfterRefused) {
+  // Construct the request.
+  scoped_ptr<SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req, 1),
+    CreateMockWrite(*req2, 3),
+  };
+
+  scoped_ptr<SpdyFrame> refused(
+      ConstructSpdyRstStream(1, REFUSED_STREAM));
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(3, true));
+  MockRead reads[] = {
+    CreateMockRead(*refused, 2),
+    CreateMockRead(*resp, 4),
+    CreateMockRead(*body, 5),
+    MockRead(ASYNC, 0, 6)  // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+
+  helper.RunPreTestSetup();
+  helper.AddData(&data);
+
+  HttpNetworkTransaction* trans = helper.trans();
+
+  // Start the transaction with basic parameters.
+  TestCompletionCallback callback;
+  int rv = trans->Start(
+      &CreateGetRequest(), callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  rv = callback.WaitForResult();
+  EXPECT_EQ(OK, rv);
+
+  // Verify that we consumed all test data.
+  EXPECT_TRUE(data.at_read_eof()) << "Read count: "
+                                   << data.read_count()
+                                   << " Read index: "
+                                   << data.read_index();
+  EXPECT_TRUE(data.at_write_eof()) << "Write count: "
+                                    << data.write_count()
+                                    << " Write index: "
+                                    << data.write_index();
+
+  // Verify the SYN_REPLY.
+  HttpResponseInfo response = *trans->GetResponseInfo();
+  EXPECT_TRUE(response.headers != NULL);
+  EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+}
+
+TEST_P(SpdyNetworkTransactionSpdy3Test, OutOfOrderSynStream) {
+  // This first request will start to establish the SpdySession.
+  // Then we will start the second (MEDIUM priority) and then third
+  // (HIGHEST priority) request in such a way that the third will actually
+  // start before the second, causing the second to be numbered differently
+  // than they order they were created.
+  scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, HIGHEST));
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, MEDIUM));
+  MockWrite writes[] = {
+    CreateMockWrite(*req1, 0),
+    CreateMockWrite(*req2, 3),
+    CreateMockWrite(*req3, 4),
+  };
+
+  scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp1, 1),
+    CreateMockRead(*body1, 2),
+    CreateMockRead(*resp2, 5),
+    CreateMockRead(*body2, 6),
+    CreateMockRead(*resp3, 7),
+    CreateMockRead(*body3, 8),
+    MockRead(ASYNC, 0, 9)  // EOF
+  };
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+  NormalSpdyTransactionHelper helper(CreateGetRequest(),
+                                     BoundNetLog(), GetParam(), NULL);
+  helper.SetDeterministic();
+  helper.RunPreTestSetup();
+  helper.AddDeterministicData(&data);
+
+  // Start the first transaction to set up the SpdySession
+  HttpNetworkTransaction* trans = helper.trans();
+  TestCompletionCallback callback;
+  HttpRequestInfo info1 = CreateGetRequest();
+  info1.priority = LOWEST;
+  int rv = trans->Start(&info1, callback.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Run the message loop, but do not allow the write to complete.
+  // This leaves the SpdySession with a write pending, which prevents
+  // SpdySession from attempting subsequent writes until this write completes.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Now, start both new transactions
+  HttpRequestInfo info2 = CreateGetRequest();
+  info2.priority = MEDIUM;
+  TestCompletionCallback callback2;
+    scoped_ptr<HttpNetworkTransaction> trans2(
+        new HttpNetworkTransaction(helper.session()));
+  rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  MessageLoop::current()->RunUntilIdle();
+
+  HttpRequestInfo info3 = CreateGetRequest();
+  info3.priority = HIGHEST;
+  TestCompletionCallback callback3;
+  scoped_ptr<HttpNetworkTransaction> trans3(
+      new HttpNetworkTransaction(helper.session()));
+  rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  MessageLoop::current()->RunUntilIdle();
+
+  // We now have two SYN_STREAM frames queued up which will be
+  // dequeued only once the first write completes, which we
+  // now allow to happen.
+  data.RunFor(2);
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  // And now we can allow everything else to run to completion.
+  data.SetStop(10);
+  data.Run();
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ(OK, callback3.WaitForResult());
+
+  helper.VerifyDataConsumed();
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_protocol.h b/src/net/spdy/spdy_protocol.h
new file mode 100644
index 0000000..30daee3
--- /dev/null
+++ b/src/net/spdy/spdy_protocol.h
@@ -0,0 +1,1065 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains some protocol structures for use with Spdy.
+
+#ifndef NET_SPDY_SPDY_PROTOCOL_H_
+#define NET_SPDY_SPDY_PROTOCOL_H_
+
+#include <limits>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/sys_byteorder.h"
+#include "net/spdy/spdy_bitmasks.h"
+
+//  Data Frame Format
+//  +----------------------------------+
+//  |0|       Stream-ID (31bits)       |
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   |
+//  +----------------------------------+
+//  |               Data               |
+//  +----------------------------------+
+//
+//  Control Frame Format
+//  +----------------------------------+
+//  |1| Version(15bits) | Type(16bits) |
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   |
+//  +----------------------------------+
+//  |               Data               |
+//  +----------------------------------+
+//
+//  Control Frame: SYN_STREAM
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000001|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   |  >= 12
+//  +----------------------------------+
+//  |X|       Stream-ID(31bits)        |
+//  +----------------------------------+
+//  |X|Associated-To-Stream-ID (31bits)|
+//  +----------------------------------+
+//  |Pri| unused      | Length (16bits)|
+//  +----------------------------------+
+//
+//  Control Frame: SYN_REPLY
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000010|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   |  >= 8
+//  +----------------------------------+
+//  |X|       Stream-ID(31bits)        |
+//  +----------------------------------+
+//  | unused (16 bits)| Length (16bits)|
+//  +----------------------------------+
+//
+//  Control Frame: RST_STREAM
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000011|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   |  >= 4
+//  +----------------------------------+
+//  |X|       Stream-ID(31bits)        |
+//  +----------------------------------+
+//  |        Status code (32 bits)     |
+//  +----------------------------------+
+//
+//  Control Frame: SETTINGS
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000100|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   |
+//  +----------------------------------+
+//  |        # of entries (32)         |
+//  +----------------------------------+
+//
+//  Control Frame: NOOP
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000101|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   | = 0
+//  +----------------------------------+
+//
+//  Control Frame: PING
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000110|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   | = 4
+//  +----------------------------------+
+//  |        Unique id (32 bits)       |
+//  +----------------------------------+
+//
+//  Control Frame: GOAWAY
+//  +----------------------------------+
+//  |1|000000000000001|0000000000000111|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   | = 4
+//  +----------------------------------+
+//  |X|  Last-accepted-stream-id       |
+//  +----------------------------------+
+//
+//  Control Frame: HEADERS
+//  +----------------------------------+
+//  |1|000000000000001|0000000000001000|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   | >= 8
+//  +----------------------------------+
+//  |X|      Stream-ID (31 bits)       |
+//  +----------------------------------+
+//  | unused (16 bits)| Length (16bits)|
+//  +----------------------------------+
+//
+//  Control Frame: WINDOW_UPDATE
+//  +----------------------------------+
+//  |1|000000000000001|0000000000001001|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   | = 8
+//  +----------------------------------+
+//  |X|      Stream-ID (31 bits)       |
+//  +----------------------------------+
+//  |   Delta-Window-Size (32 bits)    |
+//  +----------------------------------+
+//
+//  Control Frame: CREDENTIAL
+//  +----------------------------------+
+//  |1|000000000000001|0000000000001010|
+//  +----------------------------------+
+//  | flags (8)  |  Length (24 bits)   | >= 12
+//  +----------------------------------+
+//  |  Slot (16 bits) |                |
+//  +-----------------+                |
+//  |      Proof Length (32 bits)      |
+//  +----------------------------------+
+//  |               Proof              |
+//  +----------------------------------+ <+
+//  |   Certificate Length (32 bits)   |  |
+//  +----------------------------------+  | Repeated until end of frame
+//  |            Certificate           |  |
+//  +----------------------------------+ <+
+//
+
+namespace net {
+
+// Initial window size for a Spdy stream
+const int32 kSpdyStreamInitialWindowSize = 64 * 1024;  // 64 KBytes
+
+// Maximum window size for a Spdy stream
+const int32 kSpdyStreamMaximumWindowSize = 0x7FFFFFFF;  // Max signed 32bit int
+
+// SPDY 2 dictionary.
+// This is just a hacked dictionary to use for shrinking HTTP-like headers.
+const char kV2Dictionary[] =
+  "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
+  "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
+  "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
+  "-agent10010120020120220320420520630030130230330430530630740040140240340440"
+  "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
+  "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
+  "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
+  "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
+  "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
+  "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
+  "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
+  "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
+  ".1statusversionurl";
+const int kV2DictionarySize = arraysize(kV2Dictionary);
+
+// SPDY 3 dictionary.
+const char kV3Dictionary[] = {
+  0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69,  // ....opti
+  0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68,  // ons....h
+  0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70,  // ead....p
+  0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70,  // ost....p
+  0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65,  // ut....de
+  0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05,  // lete....
+  0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00,  // trace...
+  0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00,  // .accept.
+  0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70,  // ...accep
+  0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,  // t-charse
+  0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63,  // t....acc
+  0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,  // ept-enco
+  0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f,  // ding....
+  0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c,  // accept-l
+  0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00,  // anguage.
+  0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70,  // ...accep
+  0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73,  // t-ranges
+  0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00,  // ....age.
+  0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77,  // ...allow
+  0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68,  // ....auth
+  0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,  // orizatio
+  0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63,  // n....cac
+  0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72,  // he-contr
+  0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f,  // ol....co
+  0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,  // nnection
+  0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
+  0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65,  // ent-base
+  0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
+  0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,  // ent-enco
+  0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10,  // ding....
+  0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,  // content-
+  0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,  // language
+  0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
+  0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67,  // ent-leng
+  0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f,  // th....co
+  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f,  // ntent-lo
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,  // cation..
+  0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,  // ..conten
+  0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00,  // t-md5...
+  0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,  // .content
+  0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00,  // -range..
+  0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,  // ..conten
+  0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00,  // t-type..
+  0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00,  // ..date..
+  0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00,  // ..etag..
+  0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,  // ..expect
+  0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69,  // ....expi
+  0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66,  // res....f
+  0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68,  // rom....h
+  0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69,  // ost....i
+  0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00,  // f-match.
+  0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f,  // ...if-mo
+  0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73,  // dified-s
+  0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d,  // ince....
+  0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d,  // if-none-
+  0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00,  // match...
+  0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67,  // .if-rang
+  0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d,  // e....if-
+  0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,  // unmodifi
+  0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65,  // ed-since
+  0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74,  // ....last
+  0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,  // -modifie
+  0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63,  // d....loc
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,  // ation...
+  0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72,  // .max-for
+  0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00,  // wards...
+  0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00,  // .pragma.
+  0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79,  // ...proxy
+  0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,  // -authent
+  0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,  // icate...
+  0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61,  // .proxy-a
+  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,  // uthoriza
+  0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05,  // tion....
+  0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00,  // range...
+  0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72,  // .referer
+  0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72,  // ....retr
+  0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00,  // y-after.
+  0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,  // ...serve
+  0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00,  // r....te.
+  0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c,  // ...trail
+  0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72,  // er....tr
+  0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65,  // ansfer-e
+  0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00,  // ncoding.
+  0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61,  // ...upgra
+  0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73,  // de....us
+  0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,  // er-agent
+  0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79,  // ....vary
+  0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00,  // ....via.
+  0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69,  // ...warni
+  0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77,  // ng....ww
+  0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,  // w-authen
+  0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00,  // ticate..
+  0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,  // ..method
+  0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00,  // ....get.
+  0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,  // ...statu
+  0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30,  // s....200
+  0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76,  // .OK....v
+  0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00,  // ersion..
+  0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31,  // ..HTTP.1
+  0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72,  // .1....ur
+  0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62,  // l....pub
+  0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73,  // lic....s
+  0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69,  // et-cooki
+  0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65,  // e....kee
+  0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00,  // p-alive.
+  0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69,  // ...origi
+  0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32,  // n1001012
+  0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35,  // 01202205
+  0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30,  // 20630030
+  0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33,  // 23033043
+  0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37,  // 05306307
+  0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30,  // 40240540
+  0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34,  // 64074084
+  0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31,  // 09410411
+  0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31,  // 41241341
+  0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34,  // 44154164
+  0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34,  // 17502504
+  0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e,  // 505203.N
+  0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f,  // on-Autho
+  0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65,  // ritative
+  0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,  // .Informa
+  0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20,  // tion204.
+  0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65,  // No.Conte
+  0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f,  // nt301.Mo
+  0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d,  // ved.Perm
+  0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34,  // anently4
+  0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52,  // 00.Bad.R
+  0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30,  // equest40
+  0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68,  // 1.Unauth
+  0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30,  // orized40
+  0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64,  // 3.Forbid
+  0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e,  // den404.N
+  0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64,  // ot.Found
+  0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65,  // 500.Inte
+  0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,  // rnal.Ser
+  0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f,  // ver.Erro
+  0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74,  // r501.Not
+  0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65,  // .Impleme
+  0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20,  // nted503.
+  0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20,  // Service.
+  0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,  // Unavaila
+  0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46,  // bleJan.F
+  0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41,  // eb.Mar.A
+  0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a,  // pr.May.J
+  0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41,  // un.Jul.A
+  0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20,  // ug.Sept.
+  0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20,  // Oct.Nov.
+  0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30,  // Dec.00.0
+  0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e,  // 0.00.Mon
+  0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57,  // ..Tue..W
+  0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c,  // ed..Thu.
+  0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61,  // .Fri..Sa
+  0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20,  // t..Sun..
+  0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b,  // GMTchunk
+  0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f,  // ed.text.
+  0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61,  // html.ima
+  0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69,  // ge.png.i
+  0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67,  // mage.jpg
+  0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67,  // .image.g
+  0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,  // if.appli
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,  // cation.x
+  0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,  // ml.appli
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,  // cation.x
+  0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c,  // html.xml
+  0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c,  // .text.pl
+  0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74,  // ain.text
+  0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72,  // .javascr
+  0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c,  // ipt.publ
+  0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,  // icprivat
+  0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65,  // emax-age
+  0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65,  // .gzip.de
+  0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64,  // flate.sd
+  0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,  // chcharse
+  0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63,  // t.utf-8c
+  0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69,  // harset.i
+  0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d,  // so-8859-
+  0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a,  // 1.utf-..
+  0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e         // .enq.0.
+};
+const int kV3DictionarySize = arraysize(kV3Dictionary);
+
+// Note: all protocol data structures are on-the-wire format.  That means that
+//       data is stored in network-normalized order.  Readers must use the
+//       accessors provided or call ntohX() functions.
+
+// Types of Spdy Control Frames.
+enum SpdyControlType {
+  SYN_STREAM = 1,
+  SYN_REPLY,
+  RST_STREAM,
+  SETTINGS,
+  NOOP,  // Because it is valid in SPDY/2, kept for identifiability/enum order.
+  PING,
+  GOAWAY,
+  HEADERS,
+  WINDOW_UPDATE,
+  CREDENTIAL,
+  NUM_CONTROL_FRAME_TYPES
+};
+
+// Flags on data packets.
+enum SpdyDataFlags {
+  DATA_FLAG_NONE = 0,
+  DATA_FLAG_FIN = 1,
+};
+
+// Flags on control packets
+enum SpdyControlFlags {
+  CONTROL_FLAG_NONE = 0,
+  CONTROL_FLAG_FIN = 1,
+  CONTROL_FLAG_UNIDIRECTIONAL = 2
+};
+
+// Flags on the SETTINGS control frame.
+enum SpdySettingsControlFlags {
+  SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1
+};
+
+// Flags for settings within a SETTINGS frame.
+enum SpdySettingsFlags {
+  SETTINGS_FLAG_NONE = 0x0,
+  SETTINGS_FLAG_PLEASE_PERSIST = 0x1,
+  SETTINGS_FLAG_PERSISTED = 0x2
+};
+
+// List of known settings.
+enum SpdySettingsIds {
+  SETTINGS_UPLOAD_BANDWIDTH = 0x1,
+  SETTINGS_DOWNLOAD_BANDWIDTH = 0x2,
+  // Network round trip time in milliseconds.
+  SETTINGS_ROUND_TRIP_TIME = 0x3,
+  SETTINGS_MAX_CONCURRENT_STREAMS = 0x4,
+  // TCP congestion window in packets.
+  SETTINGS_CURRENT_CWND = 0x5,
+  // Downstream byte retransmission rate in percentage.
+  SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6,
+  // Initial window size in bytes
+  SETTINGS_INITIAL_WINDOW_SIZE = 0x7
+};
+
+// Status codes, as used in control frames (primarily RST_STREAM).
+// TODO(hkhalil): Rename to SpdyRstStreamStatus
+enum SpdyStatusCodes {
+  INVALID = 0,
+  PROTOCOL_ERROR = 1,
+  INVALID_STREAM = 2,
+  REFUSED_STREAM = 3,
+  UNSUPPORTED_VERSION = 4,
+  CANCEL = 5,
+  INTERNAL_ERROR = 6,
+  FLOW_CONTROL_ERROR = 7,
+  STREAM_IN_USE = 8,
+  STREAM_ALREADY_CLOSED = 9,
+  INVALID_CREDENTIALS = 10,
+  FRAME_TOO_LARGE = 11,
+  NUM_STATUS_CODES = 12
+};
+
+enum SpdyGoAwayStatus {
+  GOAWAY_INVALID = -1,
+  GOAWAY_OK = 0,
+  GOAWAY_PROTOCOL_ERROR = 1,
+  GOAWAY_INTERNAL_ERROR = 2,
+  GOAWAY_NUM_STATUS_CODES = 3
+};
+
+// A SPDY stream id is a 31 bit entity.
+typedef uint32 SpdyStreamId;
+
+// A SPDY priority is a number between 0 and 7 (inclusive).
+// SPDY priority range is version-dependant. For SPDY 2 and below, priority is a
+// number between 0 and 3.
+typedef uint8 SpdyPriority;
+
+// -------------------------------------------------------------------------
+// These structures mirror the protocol structure definitions.
+
+// For the control data structures, we pack so that sizes match the
+// protocol over-the-wire sizes.
+#pragma pack(push)
+#pragma pack(1)
+
+// A special structure for the 8 bit flags and 24 bit length fields.
+union FlagsAndLength {
+  uint8 flags_[4];  // 8 bits
+  uint32 length_;   // 24 bits
+};
+
+// The basic SPDY Frame structure.
+struct SpdyFrameBlock {
+  union {
+    struct {
+      uint16 version_;
+      uint16 type_;
+    } control_;
+    struct {
+      SpdyStreamId stream_id_;
+    } data_;
+  };
+  FlagsAndLength flags_length_;
+};
+
+// A SYN_STREAM Control Frame structure.
+struct SpdySynStreamControlFrameBlock : SpdyFrameBlock {
+  SpdyStreamId stream_id_;
+  SpdyStreamId associated_stream_id_;
+  SpdyPriority priority_;
+  uint8 credential_slot_;
+};
+
+// A SYN_REPLY Control Frame structure.
+struct SpdySynReplyControlFrameBlock : SpdyFrameBlock {
+  SpdyStreamId stream_id_;
+};
+
+// A RST_STREAM Control Frame structure.
+struct SpdyRstStreamControlFrameBlock : SpdyFrameBlock {
+  SpdyStreamId stream_id_;
+  uint32 status_;
+};
+
+// A SETTINGS Control Frame structure.
+struct SpdySettingsControlFrameBlock : SpdyFrameBlock {
+  uint32 num_entries_;
+  // Variable data here.
+};
+
+// A PING Control Frame structure.
+struct SpdyPingControlFrameBlock : SpdyFrameBlock {
+  uint32 unique_id_;
+};
+
+// TODO(avd): remove this struct
+// A CREDENTIAL Control Frame structure.
+struct SpdyCredentialControlFrameBlock : SpdyFrameBlock {
+  uint16 slot_;
+  uint32 proof_len_;
+  // Variable data here.
+  // proof data
+  // for each certificate: unit32 certificate_len + certificate_data[i]
+};
+
+// A GOAWAY Control Frame structure.
+struct SpdyGoAwayControlFrameBlock : SpdyFrameBlock {
+  SpdyStreamId last_accepted_stream_id_;
+  SpdyGoAwayStatus status_;
+};
+
+// A HEADERS Control Frame structure.
+struct SpdyHeadersControlFrameBlock : SpdyFrameBlock {
+  SpdyStreamId stream_id_;
+};
+
+// A WINDOW_UPDATE Control Frame structure
+struct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock {
+  SpdyStreamId stream_id_;
+  uint32 delta_window_size_;
+};
+
+#pragma pack(pop)
+
+// -------------------------------------------------------------------------
+// Wrapper classes for various SPDY frames.
+
+// All Spdy Frame types derive from this SpdyFrame class.
+class SpdyFrame {
+ public:
+  // Create a SpdyFrame for a given sized buffer.
+  explicit SpdyFrame(size_t size) : frame_(NULL), owns_buffer_(true) {
+    DCHECK_GE(size, sizeof(struct SpdyFrameBlock));
+    char* buffer = new char[size];
+    memset(buffer, 0, size);
+    frame_ = reinterpret_cast<struct SpdyFrameBlock*>(buffer);
+  }
+
+  // Create a SpdyFrame using a pre-created buffer.
+  // If |owns_buffer| is true, this class takes ownership of the buffer
+  // and will delete it on cleanup.  The buffer must have been created using
+  // new char[].
+  // If |owns_buffer| is false, the caller retains ownership of the buffer and
+  // is responsible for making sure the buffer outlives this frame.  In other
+  // words, this class does NOT create a copy of the buffer.
+  SpdyFrame(char* data, bool owns_buffer)
+      : frame_(reinterpret_cast<struct SpdyFrameBlock*>(data)),
+        owns_buffer_(owns_buffer) {
+    DCHECK(frame_);
+  }
+
+  ~SpdyFrame() {
+    if (owns_buffer_) {
+      char* buffer = reinterpret_cast<char*>(frame_);
+      delete [] buffer;
+    }
+    frame_ = NULL;
+  }
+
+  // Provides access to the frame bytes, which is a buffer containing
+  // the frame packed as expected for sending over the wire.
+  char* data() const { return reinterpret_cast<char*>(frame_); }
+
+  uint8 flags() const { return frame_->flags_length_.flags_[0]; }
+  void set_flags(uint8 flags) { frame_->flags_length_.flags_[0] = flags; }
+
+  uint32 length() const {
+    return ntohl(frame_->flags_length_.length_) & kLengthMask;
+  }
+
+  void set_length(uint32 length) {
+    DCHECK_EQ(0u, (length & ~kLengthMask));
+    /*
+    +----------------------------------+
+    | Flags (8)  |  Length (24 bits)   |
+    +----------------------------------+
+    */
+    frame_->flags_length_.length_ = htonl((length & kLengthMask)
+                                          | (flags() << 24));
+  }
+
+  bool is_control_frame() const {
+    return (ntohs(frame_->control_.version_) & kControlFlagMask) ==
+        kControlFlagMask;
+  }
+
+  // The size of the SpdyFrameBlock structure.
+  // Every SpdyFrame* class has a static size() method for accessing
+  // the size of the data structure which will be sent over the wire.
+  // Note:  this is not the same as sizeof(SpdyFrame).
+  enum { kHeaderSize = sizeof(struct SpdyFrameBlock) };
+
+ protected:
+  SpdyFrameBlock* frame_;
+
+ private:
+  bool owns_buffer_;
+  DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
+};
+
+// A Data Frame.
+class SpdyDataFrame : public SpdyFrame {
+ public:
+  SpdyDataFrame() : SpdyFrame(size()) {}
+  SpdyDataFrame(char* data, bool owns_buffer)
+      : SpdyFrame(data, owns_buffer) {}
+
+  SpdyStreamId stream_id() const {
+    return ntohl(frame_->data_.stream_id_) & kStreamIdMask;
+  }
+
+  // Note that setting the stream id sets the control bit to false.
+  // As stream id should always be set, this means the control bit
+  // should always be set correctly.
+  void set_stream_id(SpdyStreamId id) {
+    DCHECK_EQ(0u, (id & ~kStreamIdMask));
+    frame_->data_.stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  // Returns the size of the SpdyFrameBlock structure.
+  // Note: this is not the size of the SpdyDataFrame class.
+  static size_t size() { return SpdyFrame::kHeaderSize; }
+
+  const char* payload() const {
+    return reinterpret_cast<const char*>(frame_) + size();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SpdyDataFrame);
+};
+
+// A Control Frame.
+class SpdyControlFrame : public SpdyFrame {
+ public:
+  explicit SpdyControlFrame(size_t size) : SpdyFrame(size) {}
+  SpdyControlFrame(char* data, bool owns_buffer)
+      : SpdyFrame(data, owns_buffer) {}
+
+  // Callers can use this method to check if the frame appears to be a valid
+  // frame.  Does not guarantee that there are no errors.
+  bool AppearsToBeAValidControlFrame() const {
+    // Right now we only check if the frame has an out-of-bounds type.
+    uint16 type = ntohs(block()->control_.type_);
+    // NOOP is not a 'valid' control frame in SPDY/3 and beyond.
+    return type >= SYN_STREAM &&
+        type < NUM_CONTROL_FRAME_TYPES &&
+        (version() == 2 || type != NOOP);
+  }
+
+  uint16 version() const {
+    const int kVersionMask = 0x7fff;
+    return static_cast<uint16>(
+        ntohs((block()->control_.version_)) & kVersionMask);
+  }
+
+  void set_version(uint16 version) {
+    /*
+    +----------------------------------+
+    |C| Version(15bits) | Type(16bits) |
+    +----------------------------------+
+    */
+    DCHECK_EQ(0U, version & kControlFlagMask);
+    mutable_block()->control_.version_ = htons(kControlFlagMask | version);
+  }
+
+  SpdyControlType type() const {
+    uint16 type = ntohs(block()->control_.type_);
+    LOG_IF(DFATAL, type < SYN_STREAM || type >= NUM_CONTROL_FRAME_TYPES)
+        << "Invalid control frame type " << type;
+    return static_cast<SpdyControlType>(type);
+  }
+
+  void set_type(SpdyControlType type) {
+    DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES);
+    mutable_block()->control_.type_ = htons(static_cast<uint16>(type));
+  }
+
+  // Returns true if this control frame is of a type that has a header block,
+  // otherwise it returns false.
+  bool has_header_block() const {
+    return type() == SYN_STREAM || type() == SYN_REPLY || type() == HEADERS;
+  }
+
+ private:
+  const struct SpdyFrameBlock* block() const {
+    return frame_;
+  }
+  struct SpdyFrameBlock* mutable_block() {
+    return frame_;
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdyControlFrame);
+};
+
+// A SYN_STREAM frame.
+class SpdySynStreamControlFrame : public SpdyControlFrame {
+ public:
+  SpdySynStreamControlFrame() : SpdyControlFrame(size()) {}
+  SpdySynStreamControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  SpdyStreamId stream_id() const {
+    return ntohl(block()->stream_id_) & kStreamIdMask;
+  }
+
+  void set_stream_id(SpdyStreamId id) {
+    mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  SpdyStreamId associated_stream_id() const {
+    return ntohl(block()->associated_stream_id_) & kStreamIdMask;
+  }
+
+  void set_associated_stream_id(SpdyStreamId id) {
+    mutable_block()->associated_stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  SpdyPriority priority() const {
+    if (version() < 3) {
+      return (block()->priority_ & kSpdy2PriorityMask) >> 6;
+    } else {
+      return (block()->priority_ & kSpdy3PriorityMask) >> 5;
+    }
+  }
+
+  uint8 credential_slot() const {
+    if (version() < 3) {
+      return 0;
+    } else {
+      return block()->credential_slot_;
+    }
+  }
+
+  void set_credential_slot(uint8 credential_slot) {
+    DCHECK(version() >= 3);
+    mutable_block()->credential_slot_ = credential_slot;
+  }
+
+  // The number of bytes in the header block beyond the frame header length.
+  int header_block_len() const {
+    return static_cast<int>(length() - (size() - SpdyFrame::kHeaderSize));
+  }
+
+  const char* header_block() const {
+    return reinterpret_cast<const char*>(block()) + size();
+  }
+
+  // Returns the size of the SpdySynStreamControlFrameBlock structure.
+  // Note: this is not the size of the SpdySynStreamControlFrame class.
+  static size_t size() { return sizeof(SpdySynStreamControlFrameBlock); }
+
+ private:
+  const struct SpdySynStreamControlFrameBlock* block() const {
+    return static_cast<SpdySynStreamControlFrameBlock*>(frame_);
+  }
+  struct SpdySynStreamControlFrameBlock* mutable_block() {
+    return static_cast<SpdySynStreamControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdySynStreamControlFrame);
+};
+
+// A SYN_REPLY frame.
+class SpdySynReplyControlFrame : public SpdyControlFrame {
+ public:
+  SpdySynReplyControlFrame() : SpdyControlFrame(size()) {}
+  SpdySynReplyControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  SpdyStreamId stream_id() const {
+    return ntohl(block()->stream_id_) & kStreamIdMask;
+  }
+
+  void set_stream_id(SpdyStreamId id) {
+    mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  int header_block_len() const {
+    size_t header_block_len = length() - (size() - SpdyFrame::kHeaderSize);
+    // SPDY 2 had 2 bytes of unused space preceeding the header block.
+    if (version() < 3) {
+      header_block_len -= 2;
+    }
+    return static_cast<int>(header_block_len);
+  }
+
+  const char* header_block() const {
+    const char* header_block = reinterpret_cast<const char*>(block()) + size();
+    // SPDY 2 had 2 bytes of unused space preceeding the header block.
+    if (version() < 3) {
+      header_block += 2;
+    }
+    return header_block;
+  }
+
+  // Returns the size of the SpdySynReplyControlFrameBlock structure.
+  // Note: this is not the size of the SpdySynReplyControlFrame class.
+  static size_t size() { return sizeof(SpdySynReplyControlFrameBlock); }
+
+ private:
+  const struct SpdySynReplyControlFrameBlock* block() const {
+    return static_cast<SpdySynReplyControlFrameBlock*>(frame_);
+  }
+  struct SpdySynReplyControlFrameBlock* mutable_block() {
+    return static_cast<SpdySynReplyControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdySynReplyControlFrame);
+};
+
+// A RST_STREAM frame.
+class SpdyRstStreamControlFrame : public SpdyControlFrame {
+ public:
+  SpdyRstStreamControlFrame() : SpdyControlFrame(size()) {}
+  SpdyRstStreamControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  SpdyStreamId stream_id() const {
+    return ntohl(block()->stream_id_) & kStreamIdMask;
+  }
+
+  void set_stream_id(SpdyStreamId id) {
+    mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  SpdyStatusCodes status() const {
+    SpdyStatusCodes status =
+        static_cast<SpdyStatusCodes>(ntohl(block()->status_));
+    if (status < INVALID || status >= NUM_STATUS_CODES) {
+      status = INVALID;
+    }
+    return status;
+  }
+  void set_status(SpdyStatusCodes status) {
+    mutable_block()->status_ = htonl(static_cast<uint32>(status));
+  }
+
+  // Returns the size of the SpdyRstStreamControlFrameBlock structure.
+  // Note: this is not the size of the SpdyRstStreamControlFrame class.
+  static size_t size() { return sizeof(SpdyRstStreamControlFrameBlock); }
+
+ private:
+  const struct SpdyRstStreamControlFrameBlock* block() const {
+    return static_cast<SpdyRstStreamControlFrameBlock*>(frame_);
+  }
+  struct SpdyRstStreamControlFrameBlock* mutable_block() {
+    return static_cast<SpdyRstStreamControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamControlFrame);
+};
+
+class SpdySettingsControlFrame : public SpdyControlFrame {
+ public:
+  SpdySettingsControlFrame() : SpdyControlFrame(size()) {}
+  SpdySettingsControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  uint32 num_entries() const {
+    return ntohl(block()->num_entries_);
+  }
+
+  void set_num_entries(int val) {
+    mutable_block()->num_entries_ = htonl(static_cast<uint32>(val));
+  }
+
+  int header_block_len() const {
+    return static_cast<int>(length() - (size() - SpdyFrame::kHeaderSize));
+  }
+
+  const char* header_block() const {
+    return reinterpret_cast<const char*>(block()) + size();
+  }
+
+  // Returns the size of the SpdySettingsControlFrameBlock structure.
+  // Note: this is not the size of the SpdySettingsControlFrameBlock class.
+  static size_t size() { return sizeof(SpdySettingsControlFrameBlock); }
+
+ private:
+  const struct SpdySettingsControlFrameBlock* block() const {
+    return static_cast<SpdySettingsControlFrameBlock*>(frame_);
+  }
+  struct SpdySettingsControlFrameBlock* mutable_block() {
+    return static_cast<SpdySettingsControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame);
+};
+
+class SpdyPingControlFrame : public SpdyControlFrame {
+ public:
+  SpdyPingControlFrame() : SpdyControlFrame(size()) {}
+  SpdyPingControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  uint32 unique_id() const {
+    return ntohl(block()->unique_id_);
+  }
+
+  void set_unique_id(uint32 unique_id) {
+    mutable_block()->unique_id_ = htonl(unique_id);
+  }
+
+  static size_t size() { return sizeof(SpdyPingControlFrameBlock); }
+
+ private:
+  const struct SpdyPingControlFrameBlock* block() const {
+    return static_cast<SpdyPingControlFrameBlock*>(frame_);
+  }
+  struct SpdyPingControlFrameBlock* mutable_block() {
+    return static_cast<SpdyPingControlFrameBlock*>(frame_);
+  }
+};
+
+class SpdyCredentialControlFrame : public SpdyControlFrame {
+ public:
+  SpdyCredentialControlFrame() : SpdyControlFrame(size()) {}
+  SpdyCredentialControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  const char* payload() const {
+    return reinterpret_cast<const char*>(block()) + SpdyFrame::kHeaderSize;
+  }
+
+  static size_t size() { return sizeof(SpdyCredentialControlFrameBlock); }
+
+ private:
+  const struct SpdyCredentialControlFrameBlock* block() const {
+    return static_cast<SpdyCredentialControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdyCredentialControlFrame);
+};
+
+class SpdyGoAwayControlFrame : public SpdyControlFrame {
+ public:
+  SpdyGoAwayControlFrame() : SpdyControlFrame(size()) {}
+  SpdyGoAwayControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  SpdyStreamId last_accepted_stream_id() const {
+    return ntohl(block()->last_accepted_stream_id_) & kStreamIdMask;
+  }
+
+  SpdyGoAwayStatus status() const {
+    if (version() < 3) {
+      LOG(DFATAL) << "Attempted to access status of SPDY 2 GOAWAY.";
+      return GOAWAY_INVALID;
+    } else {
+      uint32 status = ntohl(block()->status_);
+      if (status >= GOAWAY_NUM_STATUS_CODES) {
+        return GOAWAY_INVALID;
+      } else {
+        return static_cast<SpdyGoAwayStatus>(status);
+      }
+    }
+  }
+
+  void set_last_accepted_stream_id(SpdyStreamId id) {
+    mutable_block()->last_accepted_stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  static size_t size() { return sizeof(SpdyGoAwayControlFrameBlock); }
+
+ private:
+  const struct SpdyGoAwayControlFrameBlock* block() const {
+    return static_cast<SpdyGoAwayControlFrameBlock*>(frame_);
+  }
+  struct SpdyGoAwayControlFrameBlock* mutable_block() {
+    return static_cast<SpdyGoAwayControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayControlFrame);
+};
+
+// A HEADERS frame.
+class SpdyHeadersControlFrame : public SpdyControlFrame {
+ public:
+  SpdyHeadersControlFrame() : SpdyControlFrame(size()) {}
+  SpdyHeadersControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  SpdyStreamId stream_id() const {
+    return ntohl(block()->stream_id_) & kStreamIdMask;
+  }
+
+  void set_stream_id(SpdyStreamId id) {
+    mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  // The number of bytes in the header block beyond the frame header length.
+  int header_block_len() const {
+    size_t header_block_len = length() - (size() - SpdyFrame::kHeaderSize);
+    // SPDY 2 had 2 bytes of unused space preceeding the header block.
+    if (version() < 3) {
+      header_block_len -= 2;
+    }
+    return static_cast<int>(header_block_len);
+  }
+
+  const char* header_block() const {
+    const char* header_block = reinterpret_cast<const char*>(block()) + size();
+    // SPDY 2 had 2 bytes of unused space preceeding the header block.
+    if (version() < 3) {
+      header_block += 2;
+    }
+    return header_block;
+  }
+
+  // Returns the size of the SpdyHeadersControlFrameBlock structure.
+  // Note: this is not the size of the SpdyHeadersControlFrame class.
+  static size_t size() { return sizeof(SpdyHeadersControlFrameBlock); }
+
+ private:
+  const struct SpdyHeadersControlFrameBlock* block() const {
+    return static_cast<SpdyHeadersControlFrameBlock*>(frame_);
+  }
+  struct SpdyHeadersControlFrameBlock* mutable_block() {
+    return static_cast<SpdyHeadersControlFrameBlock*>(frame_);
+  }
+  DISALLOW_COPY_AND_ASSIGN(SpdyHeadersControlFrame);
+};
+
+// A WINDOW_UPDATE frame.
+class SpdyWindowUpdateControlFrame : public SpdyControlFrame {
+ public:
+  SpdyWindowUpdateControlFrame() : SpdyControlFrame(size()) {}
+  SpdyWindowUpdateControlFrame(char* data, bool owns_buffer)
+      : SpdyControlFrame(data, owns_buffer) {}
+
+  SpdyStreamId stream_id() const {
+    return ntohl(block()->stream_id_) & kStreamIdMask;
+  }
+
+  void set_stream_id(SpdyStreamId id) {
+    mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
+  }
+
+  uint32 delta_window_size() const {
+    return ntohl(block()->delta_window_size_);
+  }
+
+  void set_delta_window_size(uint32 delta_window_size) {
+    mutable_block()->delta_window_size_ = htonl(delta_window_size);
+  }
+
+  // Returns the size of the SpdyWindowUpdateControlFrameBlock structure.
+  // Note: this is not the size of the SpdyWindowUpdateControlFrame class.
+  static size_t size() { return sizeof(SpdyWindowUpdateControlFrameBlock); }
+
+ private:
+  const struct SpdyWindowUpdateControlFrameBlock* block() const {
+    return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_);
+  }
+  struct SpdyWindowUpdateControlFrameBlock* mutable_block() {
+    return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_);
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_PROTOCOL_H_
diff --git a/src/net/spdy/spdy_protocol_test.cc b/src/net/spdy/spdy_protocol_test.cc
new file mode 100644
index 0000000..fba50d7
--- /dev/null
+++ b/src/net/spdy/spdy_protocol_test.cc
@@ -0,0 +1,403 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_protocol.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "net/spdy/spdy_bitmasks.h"
+#include "net/spdy/spdy_framer.h"
+#include "testing/platform_test.h"
+
+namespace {
+
+enum SpdyProtocolTestTypes {
+  SPDY2 = 2,
+  SPDY3 = 3,
+};
+
+} // namespace
+
+namespace net {
+
+class SpdyProtocolTest
+    : public ::testing::TestWithParam<SpdyProtocolTestTypes> {
+ protected:
+  virtual void SetUp() {
+    spdy_version_ = GetParam();
+  }
+
+  bool IsSpdy2() { return spdy_version_ == SPDY2; }
+
+  // Version of SPDY protocol to be used.
+  int spdy_version_;
+};
+
+// All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
+INSTANTIATE_TEST_CASE_P(SpdyProtocolTests,
+                        SpdyProtocolTest,
+                        ::testing::Values(SPDY2, SPDY3));
+
+// Test our protocol constants
+TEST_P(SpdyProtocolTest, ProtocolConstants) {
+#if defined(__LB_SHELL__) || defined(COBALT)
+  // Compiler quirk: <function> declared using a type with no linkage,
+  // must be defined in this translation unit
+  unsigned int spdy_frame_header_size = SpdyFrame::kHeaderSize;
+  EXPECT_EQ(8u, spdy_frame_header_size);
+#else
+  EXPECT_EQ(8u, SpdyFrame::kHeaderSize);
+#endif
+  EXPECT_EQ(8u, SpdyDataFrame::size());
+#if defined(__LB_SHELL__) || defined(COBALT)
+  // Compiler quirk: <function> declared using a type with no linkage,
+  // must be defined in this translation unit
+  unsigned int spdy_control_frame_header_size = SpdyFrame::kHeaderSize;
+  EXPECT_EQ(8u, spdy_control_frame_header_size);
+#else
+  EXPECT_EQ(8u, SpdyControlFrame::kHeaderSize);
+#endif
+  EXPECT_EQ(18u, SpdySynStreamControlFrame::size());
+  EXPECT_EQ(12u, SpdySynReplyControlFrame::size());
+  EXPECT_EQ(16u, SpdyRstStreamControlFrame::size());
+  EXPECT_EQ(12u, SpdySettingsControlFrame::size());
+  EXPECT_EQ(12u, SpdyPingControlFrame::size());
+  EXPECT_EQ(16u, SpdyGoAwayControlFrame::size());
+  EXPECT_EQ(12u, SpdyHeadersControlFrame::size());
+  EXPECT_EQ(16u, SpdyWindowUpdateControlFrame::size());
+  EXPECT_EQ(4u, sizeof(FlagsAndLength));
+  EXPECT_EQ(1, SYN_STREAM);
+  EXPECT_EQ(2, SYN_REPLY);
+  EXPECT_EQ(3, RST_STREAM);
+  EXPECT_EQ(4, SETTINGS);
+  EXPECT_EQ(5, NOOP);
+  EXPECT_EQ(6, PING);
+  EXPECT_EQ(7, GOAWAY);
+  EXPECT_EQ(8, HEADERS);
+  EXPECT_EQ(9, WINDOW_UPDATE);
+}
+
+// Test some of the protocol helper functions
+TEST_P(SpdyProtocolTest, FrameStructs) {
+  SpdyFrame frame(SpdyFrame::kHeaderSize);
+  frame.set_length(12345);
+  frame.set_flags(10);
+  EXPECT_EQ(12345u, frame.length());
+  EXPECT_EQ(10u, frame.flags());
+  EXPECT_FALSE(frame.is_control_frame());
+
+  frame.set_length(0);
+  frame.set_flags(10);
+  EXPECT_EQ(0u, frame.length());
+  EXPECT_EQ(10u, frame.flags());
+  EXPECT_FALSE(frame.is_control_frame());
+}
+
+TEST_P(SpdyProtocolTest, DataFrameStructs) {
+  SpdyDataFrame data_frame;
+  data_frame.set_stream_id(12345);
+  EXPECT_EQ(12345u, data_frame.stream_id());
+}
+
+TEST_P(SpdyProtocolTest, ControlFrameStructs) {
+  SpdyFramer framer(spdy_version_);
+  SpdyHeaderBlock headers;
+
+  const uint8 credential_slot = IsSpdy2() ? 0 : 5;
+
+  scoped_ptr<SpdySynStreamControlFrame> syn_frame(framer.CreateSynStream(
+      123, 456, 2, credential_slot, CONTROL_FLAG_FIN, false, &headers));
+  EXPECT_EQ(framer.protocol_version(), syn_frame->version());
+  EXPECT_TRUE(syn_frame->is_control_frame());
+  EXPECT_EQ(SYN_STREAM, syn_frame->type());
+  EXPECT_EQ(123u, syn_frame->stream_id());
+  EXPECT_EQ(456u, syn_frame->associated_stream_id());
+  EXPECT_EQ(2u, syn_frame->priority());
+  EXPECT_EQ(credential_slot, syn_frame->credential_slot());
+  EXPECT_EQ(IsSpdy2() ? 2 : 4, syn_frame->header_block_len());
+  EXPECT_EQ(1u, syn_frame->flags());
+  syn_frame->set_associated_stream_id(999u);
+  EXPECT_EQ(123u, syn_frame->stream_id());
+  EXPECT_EQ(999u, syn_frame->associated_stream_id());
+
+  scoped_ptr<SpdySynReplyControlFrame> syn_reply(
+      framer.CreateSynReply(123, CONTROL_FLAG_NONE, false, &headers));
+  EXPECT_EQ(framer.protocol_version(), syn_reply->version());
+  EXPECT_TRUE(syn_reply->is_control_frame());
+  EXPECT_EQ(SYN_REPLY, syn_reply->type());
+  EXPECT_EQ(123u, syn_reply->stream_id());
+  EXPECT_EQ(IsSpdy2() ? 2 : 4, syn_reply->header_block_len());
+  EXPECT_EQ(0, syn_reply->flags());
+
+  scoped_ptr<SpdyRstStreamControlFrame> rst_frame(
+      framer.CreateRstStream(123, PROTOCOL_ERROR));
+  EXPECT_EQ(framer.protocol_version(), rst_frame->version());
+  EXPECT_TRUE(rst_frame->is_control_frame());
+  EXPECT_EQ(RST_STREAM, rst_frame->type());
+  EXPECT_EQ(123u, rst_frame->stream_id());
+  EXPECT_EQ(PROTOCOL_ERROR, rst_frame->status());
+  rst_frame->set_status(INVALID_STREAM);
+  EXPECT_EQ(INVALID_STREAM, rst_frame->status());
+  EXPECT_EQ(0, rst_frame->flags());
+
+  const uint32 kUniqueId = 1234567u;
+  const uint32 kUniqueId2 = 31415926u;
+  scoped_ptr<SpdyPingControlFrame> ping_frame(
+      framer.CreatePingFrame(kUniqueId));
+  EXPECT_EQ(framer.protocol_version(), ping_frame->version());
+  EXPECT_TRUE(ping_frame->is_control_frame());
+  EXPECT_EQ(PING, ping_frame->type());
+  EXPECT_EQ(kUniqueId, ping_frame->unique_id());
+  ping_frame->set_unique_id(kUniqueId2);
+  EXPECT_EQ(kUniqueId2, ping_frame->unique_id());
+
+  scoped_ptr<SpdyGoAwayControlFrame> goaway_frame(
+      framer.CreateGoAway(123, GOAWAY_INTERNAL_ERROR));
+  EXPECT_EQ(framer.protocol_version(), goaway_frame->version());
+  EXPECT_TRUE(goaway_frame->is_control_frame());
+  EXPECT_EQ(GOAWAY, goaway_frame->type());
+  EXPECT_EQ(123u, goaway_frame->last_accepted_stream_id());
+  if (!IsSpdy2()) {
+    EXPECT_EQ(GOAWAY_INTERNAL_ERROR, goaway_frame->status());
+  }
+
+  scoped_ptr<SpdyHeadersControlFrame> headers_frame(
+      framer.CreateHeaders(123, CONTROL_FLAG_NONE, false, &headers));
+  EXPECT_EQ(framer.protocol_version(), headers_frame->version());
+  EXPECT_TRUE(headers_frame->is_control_frame());
+  EXPECT_EQ(HEADERS, headers_frame->type());
+  EXPECT_EQ(123u, headers_frame->stream_id());
+  EXPECT_EQ(IsSpdy2() ? 2 : 4, headers_frame->header_block_len());
+  EXPECT_EQ(0, headers_frame->flags());
+
+  scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
+      framer.CreateWindowUpdate(123, 456));
+  EXPECT_EQ(framer.protocol_version(), window_update_frame->version());
+  EXPECT_TRUE(window_update_frame->is_control_frame());
+  EXPECT_EQ(WINDOW_UPDATE, window_update_frame->type());
+  EXPECT_EQ(123u, window_update_frame->stream_id());
+  EXPECT_EQ(456u, window_update_frame->delta_window_size());
+}
+
+TEST_P(SpdyProtocolTest, TestDataFrame) {
+  SpdyDataFrame frame;
+
+  // Set the stream ID to various values.
+  frame.set_stream_id(0);
+  EXPECT_EQ(0u, frame.stream_id());
+  EXPECT_FALSE(frame.is_control_frame());
+  frame.set_stream_id(~0 & kStreamIdMask);
+  EXPECT_EQ(~0 & kStreamIdMask, frame.stream_id());
+  EXPECT_FALSE(frame.is_control_frame());
+
+  // Set length to various values.  Make sure that when you set_length(x),
+  // length() == x.  Also make sure the flags are unaltered.
+  memset(frame.data(), '1', SpdyDataFrame::size());
+  int8 flags = frame.flags();
+  frame.set_length(0);
+  EXPECT_EQ(0u, frame.length());
+  EXPECT_EQ(flags, frame.flags());
+  frame.set_length(kLengthMask);
+  EXPECT_EQ(kLengthMask, frame.length());
+  EXPECT_EQ(flags, frame.flags());
+  frame.set_length(5u);
+  EXPECT_EQ(5u, frame.length());
+  EXPECT_EQ(flags, frame.flags());
+
+  // Set flags to various values.  Make sure that when you set_flags(x),
+  // flags() == x.  Also make sure the length is unaltered.
+  memset(frame.data(), '1', SpdyDataFrame::size());
+  uint32 length = frame.length();
+  frame.set_flags(0u);
+  EXPECT_EQ(0u, frame.flags());
+  EXPECT_EQ(length, frame.length());
+  int8 all_flags = ~0;
+  frame.set_flags(all_flags);
+  flags = frame.flags();
+  EXPECT_EQ(all_flags, flags);
+  EXPECT_EQ(length, frame.length());
+  frame.set_flags(5u);
+  EXPECT_EQ(5u, frame.flags());
+  EXPECT_EQ(length, frame.length());
+}
+
+// Test various types of SETTINGS frames.
+TEST_P(SpdyProtocolTest, TestSpdySettingsFrame) {
+  SpdyFramer framer(spdy_version_);
+
+  // Create a settings frame with no settings.
+  SettingsMap settings;
+  scoped_ptr<SpdySettingsControlFrame> settings_frame(
+      framer.CreateSettings(settings));
+  EXPECT_EQ(framer.protocol_version(), settings_frame->version());
+  EXPECT_TRUE(settings_frame->is_control_frame());
+  EXPECT_EQ(SETTINGS, settings_frame->type());
+  EXPECT_EQ(0u, settings_frame->num_entries());
+
+  // We'll add several different ID/Flag combinations and then verify
+  // that they encode and decode properly.
+  SettingsFlagsAndId ids[] = {
+    SettingsFlagsAndId::FromWireFormat(spdy_version_, 0x00000000),
+    SettingsFlagsAndId::FromWireFormat(spdy_version_, 0xffffffff),
+    SettingsFlagsAndId::FromWireFormat(spdy_version_, 0xff000001),
+    SettingsFlagsAndId::FromWireFormat(spdy_version_, 0x01000002),
+    SettingsFlagsAndId(6, 9)
+  };
+
+  for (size_t index = 0; index < arraysize(ids); ++index) {
+    SettingsFlagsAndId flags_and_id = ids[index];
+    SpdySettingsIds id = static_cast<SpdySettingsIds>(flags_and_id.id());
+    SpdySettingsFlags flags =
+        static_cast<SpdySettingsFlags>(flags_and_id.flags());
+    settings[id] = SettingsFlagsAndValue(flags, index);
+    settings_frame.reset(framer.CreateSettings(settings));
+    EXPECT_EQ(framer.protocol_version(), settings_frame->version());
+    EXPECT_TRUE(settings_frame->is_control_frame());
+    EXPECT_EQ(SETTINGS, settings_frame->type());
+    EXPECT_EQ(index + 1, settings_frame->num_entries());
+
+    SettingsMap parsed_settings;
+    EXPECT_TRUE(framer.ParseSettings(settings_frame.get(), &parsed_settings));
+    EXPECT_EQ(settings.size(), parsed_settings.size());
+    for (SettingsMap::const_iterator it = parsed_settings.begin();
+         it != parsed_settings.end();
+         it++) {
+      SettingsMap::const_iterator it2 = settings.find(it->first);
+      EXPECT_EQ(it->first, it2->first);
+      SettingsFlagsAndValue parsed = it->second;
+      SettingsFlagsAndValue created = it2->second;
+      EXPECT_EQ(created.first, parsed.first);
+      EXPECT_EQ(created.second, parsed.second);
+    }
+  }
+}
+
+TEST_P(SpdyProtocolTest, HasHeaderBlock) {
+  SpdyControlFrame frame(SpdyControlFrame::kHeaderSize);
+  for (SpdyControlType type = SYN_STREAM;
+      type < NUM_CONTROL_FRAME_TYPES;
+      type = static_cast<SpdyControlType>(type + 1)) {
+    frame.set_type(type);
+    if (type == SYN_STREAM || type == SYN_REPLY || type == HEADERS) {
+      EXPECT_TRUE(frame.has_header_block());
+    } else {
+      EXPECT_FALSE(frame.has_header_block());
+    }
+  }
+}
+
+class SpdyProtocolDeathTest : public SpdyProtocolTest {};
+
+// All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
+INSTANTIATE_TEST_CASE_P(SpdyProtocolDeathTests,
+                        SpdyProtocolDeathTest,
+                        ::testing::Values(SPDY2, SPDY3));
+
+// Make sure that overflows both die in debug mode, and do not cause problems
+// in opt mode.  Note:  The EXPECT_DEBUG_DEATH call does not work on Win32 yet,
+// so we comment it out.
+TEST_P(SpdyProtocolDeathTest, TestDataFrame) {
+  SpdyDataFrame frame;
+
+  frame.set_stream_id(0);
+  // TODO(mbelshe):  implement EXPECT_DEBUG_DEATH on windows.
+#if !defined(WIN32) && defined(GTEST_HAS_DEATH_TEST)
+#if !defined(DCHECK_ALWAYS_ON)
+  EXPECT_DEBUG_DEATH(frame.set_stream_id(~0), "");
+#else
+  EXPECT_DEATH(frame.set_stream_id(~0), "");
+#endif
+#endif
+  EXPECT_FALSE(frame.is_control_frame());
+
+  frame.set_flags(0);
+#if !defined(WIN32) && defined(GTEST_HAS_DEATH_TEST)
+#if !defined(DCHECK_ALWAYS_ON)
+  EXPECT_DEBUG_DEATH(frame.set_length(~0), "");
+#else
+  EXPECT_DEATH(frame.set_length(~0), "");
+#endif
+#endif
+  EXPECT_EQ(0, frame.flags());
+}
+
+TEST_P(SpdyProtocolDeathTest, TestSpdyControlFrameStreamId) {
+  SpdyControlFrame frame_store(SpdySynStreamControlFrame::size());
+  memset(frame_store.data(), '1', SpdyControlFrame::kHeaderSize);
+  SpdySynStreamControlFrame* frame =
+      reinterpret_cast<SpdySynStreamControlFrame*>(&frame_store);
+
+  // Set the stream ID to various values.
+  frame->set_stream_id(0);
+  EXPECT_EQ(0u, frame->stream_id());
+  EXPECT_FALSE(frame->is_control_frame());
+  frame->set_stream_id(kStreamIdMask);
+  EXPECT_EQ(kStreamIdMask, frame->stream_id());
+  EXPECT_FALSE(frame->is_control_frame());
+}
+
+TEST_P(SpdyProtocolDeathTest, TestSpdyControlFrameVersion) {
+  const unsigned int kVersionMask = 0x7fff;
+  SpdyControlFrame frame(SpdySynStreamControlFrame::size());
+  memset(frame.data(), '1', SpdyControlFrame::kHeaderSize);
+
+  // Set the version to various values, and make sure it does not affect the
+  // type.
+  frame.set_type(SYN_STREAM);
+  frame.set_version(0);
+  EXPECT_EQ(0, frame.version());
+  EXPECT_TRUE(frame.is_control_frame());
+  EXPECT_EQ(SYN_STREAM, frame.type());
+
+  SpdySynStreamControlFrame* syn_stream =
+      reinterpret_cast<SpdySynStreamControlFrame*>(&frame);
+  syn_stream->set_stream_id(~0 & kVersionMask);
+  EXPECT_EQ(~0 & kVersionMask, syn_stream->stream_id());
+  EXPECT_TRUE(frame.is_control_frame());
+  EXPECT_EQ(SYN_STREAM, frame.type());
+}
+
+TEST_P(SpdyProtocolDeathTest, TestSpdyControlFrameType) {
+  SpdyControlFrame frame(SpdyControlFrame::kHeaderSize);
+  memset(frame.data(), 255, SpdyControlFrame::kHeaderSize);
+
+  // type() should be out of bounds.
+  EXPECT_FALSE(frame.AppearsToBeAValidControlFrame());
+
+  frame.set_version(spdy_version_);
+  uint16 version = frame.version();
+
+  for (int i = SYN_STREAM; i <= WINDOW_UPDATE; ++i) {
+    frame.set_type(static_cast<SpdyControlType>(i));
+    EXPECT_EQ(i, static_cast<int>(frame.type()));
+    if (!IsSpdy2() && i == NOOP) {
+      // NOOP frames aren't 'valid'.
+      EXPECT_FALSE(frame.AppearsToBeAValidControlFrame());
+    } else {
+      EXPECT_TRUE(frame.AppearsToBeAValidControlFrame());
+    }
+    // Make sure setting type does not alter the version block.
+    EXPECT_EQ(version, frame.version());
+    EXPECT_TRUE(frame.is_control_frame());
+  }
+}
+
+TEST_P(SpdyProtocolDeathTest, TestRstStreamStatusBounds) {
+  SpdyFramer framer(spdy_version_);
+  scoped_ptr<SpdyRstStreamControlFrame> rst_frame;
+
+  rst_frame.reset(framer.CreateRstStream(123, PROTOCOL_ERROR));
+  EXPECT_EQ(PROTOCOL_ERROR, rst_frame->status());
+
+  rst_frame->set_status(INVALID);
+  EXPECT_EQ(INVALID, rst_frame->status());
+
+  rst_frame->set_status(
+      static_cast<SpdyStatusCodes>(INVALID - 1));
+  EXPECT_EQ(INVALID, rst_frame->status());
+
+  rst_frame->set_status(NUM_STATUS_CODES);
+  EXPECT_EQ(INVALID, rst_frame->status());
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_proxy_client_socket.cc b/src/net/spdy/spdy_proxy_client_socket.cc
new file mode 100644
index 0000000..0d62ce7
--- /dev/null
+++ b/src/net/spdy/spdy_proxy_client_socket.cc
@@ -0,0 +1,591 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_proxy_client_socket.h"
+
+#include <algorithm>  // min
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/auth.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_util.h"
+#include "net/http/http_auth_cache.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_response_headers.h"
+#include "net/spdy/spdy_http_utils.h"
+
+namespace net {
+
+SpdyProxyClientSocket::SpdyProxyClientSocket(
+    SpdyStream* spdy_stream,
+    const std::string& user_agent,
+    const HostPortPair& endpoint,
+    const GURL& url,
+    const HostPortPair& proxy_server,
+    HttpAuthCache* auth_cache,
+    HttpAuthHandlerFactory* auth_handler_factory)
+    : next_state_(STATE_DISCONNECTED),
+      spdy_stream_(spdy_stream),
+      endpoint_(endpoint),
+      auth_(
+          new HttpAuthController(HttpAuth::AUTH_PROXY,
+                                 GURL("https://" + proxy_server.ToString()),
+                                 auth_cache,
+                                 auth_handler_factory)),
+      user_buffer_(NULL),
+      write_buffer_len_(0),
+      write_bytes_outstanding_(0),
+      ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+      net_log_(spdy_stream->net_log()) {
+  request_.method = "CONNECT";
+  request_.url = url;
+  if (!user_agent.empty())
+    request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
+                                     user_agent);
+  spdy_stream_->SetDelegate(this);
+  was_ever_used_ = spdy_stream_->WasEverUsed();
+}
+
+SpdyProxyClientSocket::~SpdyProxyClientSocket() {
+  Disconnect();
+}
+
+const HttpResponseInfo* SpdyProxyClientSocket::GetConnectResponseInfo() const {
+  return response_.headers ? &response_ : NULL;
+}
+
+const scoped_refptr<HttpAuthController>&
+SpdyProxyClientSocket::GetAuthController() const {
+  return auth_;
+}
+
+int SpdyProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) {
+  // A SPDY Stream can only handle a single request, so the underlying
+  // stream may not be reused and a new SpdyProxyClientSocket must be
+  // created (possibly on top of the same SPDY Session).
+  next_state_ = STATE_DISCONNECTED;
+  return OK;
+}
+
+bool SpdyProxyClientSocket::IsUsingSpdy() const {
+  return true;
+}
+
+NextProto SpdyProxyClientSocket::GetProtocolNegotiated() const {
+  // Save the negotiated protocol
+  SSLInfo ssl_info;
+  bool was_npn_negotiated;
+  NextProto protocol_negotiated;
+  spdy_stream_->GetSSLInfo(&ssl_info, &was_npn_negotiated,
+                           &protocol_negotiated);
+  return protocol_negotiated;
+}
+
+HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() {
+  DCHECK(response_stream_.get());
+  return response_stream_.release();
+}
+
+// Sends a SYN_STREAM frame to the proxy with a CONNECT request
+// for the specified endpoint.  Waits for the server to send back
+// a SYN_REPLY frame.  OK will be returned if the status is 200.
+// ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status.
+// In any of these cases, Read() may be called to retrieve the HTTP
+// response body.  Any other return values should be considered fatal.
+// TODO(rch): handle 407 proxy auth requested correctly, perhaps
+// by creating a new stream for the subsequent request.
+// TODO(rch): create a more appropriate error code to disambiguate
+// the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure.
+int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) {
+  DCHECK(read_callback_.is_null());
+  if (next_state_ == STATE_OPEN)
+    return OK;
+
+  DCHECK_EQ(STATE_DISCONNECTED, next_state_);
+  next_state_ = STATE_GENERATE_AUTH_TOKEN;
+
+  int rv = DoLoop(OK);
+  if (rv == ERR_IO_PENDING)
+    read_callback_ = callback;
+  return rv;
+}
+
+void SpdyProxyClientSocket::Disconnect() {
+  read_buffer_.clear();
+  user_buffer_ = NULL;
+  read_callback_.Reset();
+
+  write_buffer_len_ = 0;
+  write_bytes_outstanding_ = 0;
+  write_callback_.Reset();
+
+  next_state_ = STATE_DISCONNECTED;
+
+  if (spdy_stream_)
+    // This will cause OnClose to be invoked, which takes care of
+    // cleaning up all the internal state.
+    spdy_stream_->Cancel();
+}
+
+bool SpdyProxyClientSocket::IsConnected() const {
+  return next_state_ == STATE_OPEN;
+}
+
+bool SpdyProxyClientSocket::IsConnectedAndIdle() const {
+  return IsConnected() && read_buffer_.empty() && spdy_stream_->is_idle();
+}
+
+const BoundNetLog& SpdyProxyClientSocket::NetLog() const {
+  return net_log_;
+}
+
+void SpdyProxyClientSocket::SetSubresourceSpeculation() {
+  // TODO(rch): what should this implementation be?
+}
+
+void SpdyProxyClientSocket::SetOmniboxSpeculation() {
+  // TODO(rch): what should this implementation be?
+}
+
+bool SpdyProxyClientSocket::WasEverUsed() const {
+  return was_ever_used_ || (spdy_stream_ && spdy_stream_->WasEverUsed());
+}
+
+bool SpdyProxyClientSocket::UsingTCPFastOpen() const {
+  return false;
+}
+
+int64 SpdyProxyClientSocket::NumBytesRead() const {
+  return -1;
+}
+
+base::TimeDelta SpdyProxyClientSocket::GetConnectTimeMicros() const {
+  return base::TimeDelta::FromMicroseconds(-1);
+}
+
+bool SpdyProxyClientSocket::WasNpnNegotiated() const {
+  return false;
+}
+
+NextProto SpdyProxyClientSocket::GetNegotiatedProtocol() const {
+  return kProtoUnknown;
+}
+
+bool SpdyProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
+  bool was_npn_negotiated;
+  NextProto protocol_negotiated;
+  return spdy_stream_->GetSSLInfo(ssl_info, &was_npn_negotiated,
+                                  &protocol_negotiated);
+}
+
+int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len,
+                                const CompletionCallback& callback) {
+  DCHECK(read_callback_.is_null());
+  DCHECK(!user_buffer_);
+
+  if (next_state_ == STATE_DISCONNECTED)
+    return ERR_SOCKET_NOT_CONNECTED;
+
+  if (next_state_ == STATE_CLOSED && read_buffer_.empty()) {
+    return 0;
+  }
+
+  DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED);
+  DCHECK(buf);
+  user_buffer_ = new DrainableIOBuffer(buf, buf_len);
+  int result = PopulateUserReadBuffer();
+  if (result == 0) {
+    DCHECK(!callback.is_null());
+    read_callback_ = callback;
+    return ERR_IO_PENDING;
+  }
+  user_buffer_ = NULL;
+  return result;
+}
+
+int SpdyProxyClientSocket::PopulateUserReadBuffer() {
+  if (!user_buffer_)
+    return ERR_IO_PENDING;
+
+  int bytes_read = 0;
+  while (!read_buffer_.empty() && user_buffer_->BytesRemaining() > 0) {
+    scoped_refptr<DrainableIOBuffer> data = read_buffer_.front();
+    const int bytes_to_copy = std::min(user_buffer_->BytesRemaining(),
+                                       data->BytesRemaining());
+    memcpy(user_buffer_->data(), data->data(), bytes_to_copy);
+    user_buffer_->DidConsume(bytes_to_copy);
+    bytes_read += bytes_to_copy;
+    if (data->BytesRemaining() == bytes_to_copy) {
+      // Consumed all data from this buffer
+      read_buffer_.pop_front();
+    } else {
+      data->DidConsume(bytes_to_copy);
+    }
+  }
+
+  if (bytes_read > 0 && spdy_stream_)
+    spdy_stream_->IncreaseRecvWindowSize(bytes_read);
+
+  return user_buffer_->BytesConsumed();
+}
+
+int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len,
+                                 const CompletionCallback& callback) {
+  DCHECK(write_callback_.is_null());
+  if (next_state_ != STATE_OPEN)
+    return ERR_SOCKET_NOT_CONNECTED;
+
+  DCHECK(spdy_stream_);
+  write_bytes_outstanding_= buf_len;
+  if (buf_len <= kMaxSpdyFrameChunkSize) {
+    int rv = spdy_stream_->WriteStreamData(buf, buf_len, DATA_FLAG_NONE);
+    if (rv == ERR_IO_PENDING) {
+      write_callback_ = callback;
+      write_buffer_len_ = buf_len;
+    }
+    return rv;
+  }
+
+  // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes
+  // we need to send multiple data frames
+  for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) {
+    int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i);
+    scoped_refptr<DrainableIOBuffer> iobuf(new DrainableIOBuffer(buf, i + len));
+    iobuf->SetOffset(i);
+    int rv = spdy_stream_->WriteStreamData(iobuf, len, DATA_FLAG_NONE);
+    if (rv > 0) {
+      write_bytes_outstanding_ -= rv;
+    } else if (rv != ERR_IO_PENDING) {
+      return rv;
+    }
+  }
+  if (write_bytes_outstanding_ > 0) {
+    write_callback_ = callback;
+    write_buffer_len_ = buf_len;
+    return ERR_IO_PENDING;
+  } else {
+    return buf_len;
+  }
+}
+
+bool SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) {
+  // Since this StreamSocket sits on top of a shared SpdySession, it
+  // is not safe for callers to set change this underlying socket.
+  return false;
+}
+
+bool SpdyProxyClientSocket::SetSendBufferSize(int32 size) {
+  // Since this StreamSocket sits on top of a shared SpdySession, it
+  // is not safe for callers to set change this underlying socket.
+  return false;
+}
+
+int SpdyProxyClientSocket::GetPeerAddress(IPEndPoint* address) const {
+  if (!IsConnected())
+    return ERR_SOCKET_NOT_CONNECTED;
+  return spdy_stream_->GetPeerAddress(address);
+}
+
+int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
+  if (!IsConnected())
+    return ERR_SOCKET_NOT_CONNECTED;
+  return spdy_stream_->GetLocalAddress(address);
+}
+
+void SpdyProxyClientSocket::LogBlockedTunnelResponse() const {
+  ProxyClientSocket::LogBlockedTunnelResponse(
+      response_.headers->response_code(),
+      request_.url,
+      /* is_https_proxy = */ true);
+}
+
+void SpdyProxyClientSocket::OnIOComplete(int result) {
+  DCHECK_NE(STATE_DISCONNECTED, next_state_);
+  int rv = DoLoop(result);
+  if (rv != ERR_IO_PENDING) {
+    CompletionCallback c = read_callback_;
+    read_callback_.Reset();
+    c.Run(rv);
+  }
+}
+
+int SpdyProxyClientSocket::DoLoop(int last_io_result) {
+  DCHECK_NE(next_state_, STATE_DISCONNECTED);
+  int rv = last_io_result;
+  do {
+    State state = next_state_;
+    next_state_ = STATE_DISCONNECTED;
+    switch (state) {
+      case STATE_GENERATE_AUTH_TOKEN:
+        DCHECK_EQ(OK, rv);
+        rv = DoGenerateAuthToken();
+        break;
+      case STATE_GENERATE_AUTH_TOKEN_COMPLETE:
+        rv = DoGenerateAuthTokenComplete(rv);
+        break;
+      case STATE_SEND_REQUEST:
+        DCHECK_EQ(OK, rv);
+        net_log_.BeginEvent(
+            NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST);
+        rv = DoSendRequest();
+        break;
+      case STATE_SEND_REQUEST_COMPLETE:
+        net_log_.EndEventWithNetErrorCode(
+            NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv);
+        rv = DoSendRequestComplete(rv);
+        break;
+      case STATE_READ_REPLY_COMPLETE:
+        rv = DoReadReplyComplete(rv);
+        net_log_.EndEventWithNetErrorCode(
+            NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv);
+        break;
+      default:
+        NOTREACHED() << "bad state";
+        rv = ERR_UNEXPECTED;
+        break;
+    }
+  } while (rv != ERR_IO_PENDING && next_state_ != STATE_DISCONNECTED &&
+           next_state_ != STATE_OPEN);
+  return rv;
+}
+
+int SpdyProxyClientSocket::DoGenerateAuthToken() {
+  next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE;
+  return auth_->MaybeGenerateAuthToken(
+      &request_,
+      base::Bind(&SpdyProxyClientSocket::OnIOComplete, base::Unretained(this)),
+      net_log_);
+}
+
+int SpdyProxyClientSocket::DoGenerateAuthTokenComplete(int result) {
+  DCHECK_NE(ERR_IO_PENDING, result);
+  if (result == OK)
+    next_state_ = STATE_SEND_REQUEST;
+  return result;
+}
+
+int SpdyProxyClientSocket::DoSendRequest() {
+  next_state_ = STATE_SEND_REQUEST_COMPLETE;
+
+  // Add Proxy-Authentication header if necessary.
+  HttpRequestHeaders authorization_headers;
+  if (auth_->HaveAuth()) {
+    auth_->AddAuthorizationHeader(&authorization_headers);
+  }
+
+  std::string request_line;
+  HttpRequestHeaders request_headers;
+  BuildTunnelRequest(request_, authorization_headers, endpoint_, &request_line,
+                     &request_headers);
+
+  net_log_.AddEvent(
+      NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+      base::Bind(&HttpRequestHeaders::NetLogCallback,
+                 base::Unretained(&request_headers),
+                 &request_line));
+
+  request_.extra_headers.MergeFrom(request_headers);
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
+  CreateSpdyHeadersFromHttpRequest(request_, request_headers, headers.get(),
+                                   spdy_stream_->GetProtocolVersion(), true);
+  // Reset the URL to be the endpoint of the connection
+  if (spdy_stream_->GetProtocolVersion() > 2) {
+    (*headers)[":path"] = endpoint_.ToString();
+    headers->erase(":scheme");
+  } else {
+    (*headers)["url"] = endpoint_.ToString();
+    headers->erase("scheme");
+  }
+  spdy_stream_->set_spdy_headers(headers.Pass());
+
+  return spdy_stream_->SendRequest(true);
+}
+
+int SpdyProxyClientSocket::DoSendRequestComplete(int result) {
+  if (result < 0)
+    return result;
+
+  // Wait for SYN_REPLY frame from the server
+  next_state_ = STATE_READ_REPLY_COMPLETE;
+  return ERR_IO_PENDING;
+}
+
+int SpdyProxyClientSocket::DoReadReplyComplete(int result) {
+  // We enter this method directly from DoSendRequestComplete, since
+  // we are notified by a callback when the SYN_REPLY frame arrives
+
+  if (result < 0)
+    return result;
+
+  // Require the "HTTP/1.x" status line for SSL CONNECT.
+  if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0))
+    return ERR_TUNNEL_CONNECTION_FAILED;
+
+  net_log_.AddEvent(
+      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+      base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
+
+  switch (response_.headers->response_code()) {
+    case 200:  // OK
+      next_state_ = STATE_OPEN;
+      return OK;
+
+    case 302:  // Found / Moved Temporarily
+      // Try to return a sanitized response so we can follow auth redirects.
+      // If we can't, fail the tunnel connection.
+      if (SanitizeProxyRedirect(&response_, request_.url)) {
+        // Immediately hand off our SpdyStream to a newly created
+        // SpdyHttpStream so that any subsequent SpdyFrames are processed in
+        // the context of the HttpStream, not the socket.
+        DCHECK(spdy_stream_);
+        SpdyStream* stream = spdy_stream_;
+        spdy_stream_ = NULL;
+        response_stream_.reset(new SpdyHttpStream(NULL, false));
+        response_stream_->InitializeWithExistingStream(stream);
+        next_state_ = STATE_DISCONNECTED;
+        return ERR_HTTPS_PROXY_TUNNEL_RESPONSE;
+      } else {
+        LogBlockedTunnelResponse();
+        return ERR_TUNNEL_CONNECTION_FAILED;
+      }
+
+    case 407:  // Proxy Authentication Required
+      next_state_ = STATE_OPEN;
+      return HandleProxyAuthChallenge(auth_, &response_, net_log_);
+
+    default:
+      // Ignore response to avoid letting the proxy impersonate the target
+      // server.  (See http://crbug.com/137891.)
+      LogBlockedTunnelResponse();
+      return ERR_TUNNEL_CONNECTION_FAILED;
+  }
+}
+
+// SpdyStream::Delegate methods:
+// Called when SYN frame has been sent.
+// Returns true if no more data to be sent after SYN frame.
+bool SpdyProxyClientSocket::OnSendHeadersComplete(int status) {
+  DCHECK_EQ(next_state_, STATE_SEND_REQUEST_COMPLETE);
+
+  OnIOComplete(status);
+
+  // We return true here so that we send |spdy_stream_| into
+  // STATE_OPEN (ala WebSockets).
+  return true;
+}
+
+int SpdyProxyClientSocket::OnSendBody() {
+  // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets)
+  // OnSendBody() should never be called.
+  NOTREACHED();
+  return ERR_UNEXPECTED;
+}
+
+int SpdyProxyClientSocket::OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
+  // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets)
+  // OnSendBodyComplete() should never be called.
+  NOTREACHED();
+  return ERR_UNEXPECTED;
+}
+
+int SpdyProxyClientSocket::OnResponseReceived(
+    const SpdyHeaderBlock& response,
+    base::Time response_time,
+    int status) {
+  // If we've already received the reply, existing headers are too late.
+  // TODO(mbelshe): figure out a way to make HEADERS frames useful after the
+  //                initial response.
+  if (next_state_ != STATE_READ_REPLY_COMPLETE)
+    return OK;
+
+  // Save the response
+  if (!SpdyHeadersToHttpResponse(
+          response, spdy_stream_->GetProtocolVersion(), &response_))
+      return ERR_INCOMPLETE_SPDY_HEADERS;
+
+  OnIOComplete(status);
+  return OK;
+}
+
+void SpdyProxyClientSocket::OnHeadersSent() {
+  // Proxy client sockets don't send any HEADERS frame.
+  NOTREACHED();
+}
+
+// Called when data is received.
+int SpdyProxyClientSocket::OnDataReceived(const char* data, int length) {
+  if (length > 0) {
+    // Save the received data.
+    scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length));
+    memcpy(io_buffer->data(), data, length);
+    read_buffer_.push_back(
+        make_scoped_refptr(new DrainableIOBuffer(io_buffer, length)));
+  }
+
+  if (!read_callback_.is_null()) {
+    int rv = PopulateUserReadBuffer();
+    CompletionCallback c = read_callback_;
+    read_callback_.Reset();
+    user_buffer_ = NULL;
+    c.Run(rv);
+  }
+  return OK;
+}
+
+void SpdyProxyClientSocket::OnDataSent(int length)  {
+  DCHECK(!write_callback_.is_null());
+
+  write_bytes_outstanding_ -= length;
+
+  DCHECK_GE(write_bytes_outstanding_, 0);
+
+  if (write_bytes_outstanding_ == 0) {
+    int rv = write_buffer_len_;
+    write_buffer_len_ = 0;
+    write_bytes_outstanding_ = 0;
+    CompletionCallback c = write_callback_;
+    write_callback_.Reset();
+    c.Run(rv);
+  }
+}
+
+void SpdyProxyClientSocket::OnClose(int status)  {
+  DCHECK(spdy_stream_);
+  was_ever_used_ = spdy_stream_->WasEverUsed();
+  spdy_stream_ = NULL;
+
+  bool connecting = next_state_ != STATE_DISCONNECTED &&
+      next_state_ < STATE_OPEN;
+  if (next_state_ == STATE_OPEN)
+    next_state_ = STATE_CLOSED;
+  else
+    next_state_ = STATE_DISCONNECTED;
+
+  base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr();
+  CompletionCallback write_callback = write_callback_;
+  write_callback_.Reset();
+  write_buffer_len_ = 0;
+  write_bytes_outstanding_ = 0;
+
+  // If we're in the middle of connecting, we need to make sure
+  // we invoke the connect callback.
+  if (connecting) {
+    DCHECK(!read_callback_.is_null());
+    CompletionCallback read_callback = read_callback_;
+    read_callback_.Reset();
+    read_callback.Run(status);
+  } else if (!read_callback_.is_null()) {
+    // If we have a read_callback_, the we need to make sure we call it back.
+    OnDataReceived(NULL, 0);
+  }
+  // This may have been deleted by read_callback_, so check first.
+  if (weak_ptr && !write_callback.is_null())
+    write_callback.Run(ERR_CONNECTION_CLOSED);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_proxy_client_socket.h b/src/net/spdy/spdy_proxy_client_socket.h
new file mode 100644
index 0000000..a5da281
--- /dev/null
+++ b/src/net/spdy/spdy_proxy_client_socket.h
@@ -0,0 +1,177 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
+#define NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
+
+#include <string>
+#include <list>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "net/base/completion_callback.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_log.h"
+#include "net/http/http_auth_controller.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_info.h"
+#include "net/http/proxy_client_socket.h"
+#include "net/spdy/spdy_http_stream.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_stream.h"
+
+
+class GURL;
+
+namespace net {
+
+class AddressList;
+class HttpStream;
+class IOBuffer;
+class SpdyStream;
+
+class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
+                                                 public SpdyStream::Delegate {
+ public:
+  // Create a socket on top of the |spdy_stream| by sending a SYN_STREAM
+  // CONNECT frame for |endpoint|.  After the SYN_REPLY is received,
+  // any data read/written to the socket will be transferred in data
+  // frames.
+  SpdyProxyClientSocket(SpdyStream* spdy_stream,
+                        const std::string& user_agent,
+                        const HostPortPair& endpoint,
+                        const GURL& url,
+                        const HostPortPair& proxy_server,
+                        HttpAuthCache* auth_cache,
+                        HttpAuthHandlerFactory* auth_handler_factory);
+
+
+  // On destruction Disconnect() is called.
+  virtual ~SpdyProxyClientSocket();
+
+  // ProxyClientSocket methods:
+  virtual const HttpResponseInfo* GetConnectResponseInfo() const OVERRIDE;
+  virtual HttpStream* CreateConnectResponseStream() OVERRIDE;
+  virtual const scoped_refptr<HttpAuthController>& GetAuthController() const
+      OVERRIDE;
+  virtual int RestartWithAuth(const CompletionCallback& callback) OVERRIDE;
+  virtual bool IsUsingSpdy() const OVERRIDE;
+  virtual NextProto GetProtocolNegotiated() const OVERRIDE;
+
+  // StreamSocket implementation.
+  virtual int Connect(const CompletionCallback& callback) OVERRIDE;
+  virtual void Disconnect() OVERRIDE;
+  virtual bool IsConnected() const OVERRIDE;
+  virtual bool IsConnectedAndIdle() const OVERRIDE;
+  virtual const BoundNetLog& NetLog() const OVERRIDE;
+  virtual void SetSubresourceSpeculation() OVERRIDE;
+  virtual void SetOmniboxSpeculation() OVERRIDE;
+  virtual bool WasEverUsed() const OVERRIDE;
+  virtual bool UsingTCPFastOpen() const OVERRIDE;
+  virtual int64 NumBytesRead() const OVERRIDE;
+  virtual base::TimeDelta GetConnectTimeMicros() const OVERRIDE;
+  virtual bool WasNpnNegotiated() const OVERRIDE;
+  virtual NextProto GetNegotiatedProtocol() const OVERRIDE;
+  virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
+
+  // Socket implementation.
+  virtual int Read(IOBuffer* buf,
+                   int buf_len,
+                   const CompletionCallback& callback) OVERRIDE;
+  virtual int Write(IOBuffer* buf,
+                    int buf_len,
+                    const CompletionCallback& callback) OVERRIDE;
+  virtual bool SetReceiveBufferSize(int32 size) OVERRIDE;
+  virtual bool SetSendBufferSize(int32 size) OVERRIDE;
+  virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE;
+  virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE;
+
+  // SpdyStream::Delegate implementation.
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE;
+  virtual int OnSendBody() OVERRIDE;
+  virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE;
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE;
+  virtual void OnHeadersSent() OVERRIDE;
+  virtual int OnDataReceived(const char* data, int length) OVERRIDE;
+  virtual void OnDataSent(int length) OVERRIDE;
+  virtual void OnClose(int status) OVERRIDE;
+
+ private:
+  enum State {
+    STATE_DISCONNECTED,
+    STATE_GENERATE_AUTH_TOKEN,
+    STATE_GENERATE_AUTH_TOKEN_COMPLETE,
+    STATE_SEND_REQUEST,
+    STATE_SEND_REQUEST_COMPLETE,
+    STATE_READ_REPLY_COMPLETE,
+    STATE_OPEN,
+    STATE_CLOSED
+  };
+
+  void LogBlockedTunnelResponse() const;
+
+  void OnIOComplete(int result);
+
+  int DoLoop(int last_io_result);
+  int DoGenerateAuthToken();
+  int DoGenerateAuthTokenComplete(int result);
+  int DoSendRequest();
+  int DoSendRequestComplete(int result);
+  int DoReadReplyComplete(int result);
+
+  // Populates |user_buffer_| with as much read data as possible
+  // and returns the number of bytes read.
+  int PopulateUserReadBuffer();
+
+  State next_state_;
+
+  // Pointer to the SPDY Stream that this sits on top of.
+  scoped_refptr<SpdyStream> spdy_stream_;
+
+  // Stores the callback to the layer above, called on completing Read() or
+  // Connect().
+  CompletionCallback read_callback_;
+  // Stores the callback to the layer above, called on completing Write().
+  CompletionCallback write_callback_;
+
+  // CONNECT request and response.
+  HttpRequestInfo request_;
+  HttpResponseInfo response_;
+
+  // The hostname and port of the endpoint.  This is not necessarily the one
+  // specified by the URL, due to Alternate-Protocol or fixed testing ports.
+  const HostPortPair endpoint_;
+  scoped_refptr<HttpAuthController> auth_;
+
+  // We buffer the response body as it arrives asynchronously from the stream.
+  std::list<scoped_refptr<DrainableIOBuffer> > read_buffer_;
+
+  // User provided buffer for the Read() response.
+  scoped_refptr<DrainableIOBuffer> user_buffer_;
+
+  // User specified number of bytes to be written.
+  int write_buffer_len_;
+  // Number of bytes written which have not been confirmed
+  int write_bytes_outstanding_;
+
+  // True if the transport socket has ever sent data.
+  bool was_ever_used_;
+
+  scoped_ptr<SpdyHttpStream> response_stream_;
+
+  base::WeakPtrFactory<SpdyProxyClientSocket> weak_factory_;
+
+  const BoundNetLog net_log_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocket);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
diff --git a/src/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc b/src/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc
new file mode 100644
index 0000000..5216e4a
--- /dev/null
+++ b/src/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc
@@ -0,0 +1,1357 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_proxy_client_socket.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/address_list.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/test_completion_callback.h"
+#include "net/base/winsock_init.h"
+#include "net/http/http_response_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/socket/client_socket_factory.h"
+#include "net/socket/tcp_client_socket.h"
+#include "net/socket/socket_test_util.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "testing/platform_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy2;
+
+//-----------------------------------------------------------------------------
+
+namespace {
+
+static const char kRequestUrl[] = "https://www.google.com/";
+static const char kOriginHost[] = "www.google.com";
+static const int kOriginPort = 443;
+static const char kOriginHostPort[] = "www.google.com:443";
+static const char kProxyUrl[] = "https://myproxy:6121/";
+static const char kProxyHost[] = "myproxy";
+static const int kProxyPort = 6121;
+static const char kUserAgent[] = "Mozilla/1.0";
+
+static const int kStreamId = 1;
+
+static const char kMsg1[] = "\0hello!\xff";
+static const int kLen1 = 8;
+static const char kMsg2[] = "\00012345678\0";
+static const int kLen2 = 10;
+static const char kMsg3[] = "bye!";
+static const int kLen3 = 4;
+static const char kMsg33[] = "bye!bye!";
+static const int kLen33 = kLen3 + kLen3;
+static const char kMsg333[] = "bye!bye!bye!";
+static const int kLen333 = kLen3 + kLen3 + kLen3;
+
+static const char kRedirectUrl[] = "https://example.com/";
+
+}  // anonymous namespace
+
+namespace net {
+
+class SpdyProxyClientSocketSpdy2Test : public PlatformTest {
+ public:
+  SpdyProxyClientSocketSpdy2Test();
+
+  virtual void TearDown();
+
+ protected:
+  void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
+                  size_t writes_count);
+  SpdyFrame* ConstructConnectRequestFrame();
+  SpdyFrame* ConstructConnectAuthRequestFrame();
+  SpdyFrame* ConstructConnectReplyFrame();
+  SpdyFrame* ConstructConnectAuthReplyFrame();
+  SpdyFrame* ConstructConnectRedirectReplyFrame();
+  SpdyFrame* ConstructConnectErrorReplyFrame();
+  SpdyFrame* ConstructBodyFrame(const char* data, int length);
+  scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
+  void AssertConnectSucceeds();
+  void AssertConnectFails(int result);
+  void AssertConnectionEstablished();
+  void AssertSyncReadEquals(const char* data, int len);
+  void AssertAsyncReadEquals(const char* data, int len);
+  void AssertReadStarts(const char* data, int len);
+  void AssertReadReturns(const char* data, int len);
+  void AssertAsyncWriteSucceeds(const char* data, int len);
+  void AssertWriteReturns(const char* data, int len, int rv);
+  void AssertWriteLength(int len);
+  void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
+                                        int num_reads);
+
+  void AddAuthToCache() {
+    const string16 kFoo(ASCIIToUTF16("foo"));
+    const string16 kBar(ASCIIToUTF16("bar"));
+    session_->http_auth_cache()->Add(GURL(kProxyUrl),
+                                     "MyRealm1",
+                                     HttpAuth::AUTH_SCHEME_BASIC,
+                                     "Basic realm=MyRealm1",
+                                     AuthCredentials(kFoo, kBar),
+                                     "/");
+  }
+
+  void Run(int steps) {
+    data_->StopAfter(steps);
+    data_->Run();
+  }
+
+  scoped_ptr<SpdyProxyClientSocket> sock_;
+  TestCompletionCallback read_callback_;
+  TestCompletionCallback write_callback_;
+  scoped_ptr<DeterministicSocketData> data_;
+
+ private:
+  scoped_refptr<HttpNetworkSession> session_;
+  scoped_refptr<IOBuffer> read_buf_;
+  SpdySessionDependencies session_deps_;
+  MockConnect connect_data_;
+  scoped_refptr<SpdySession> spdy_session_;
+  scoped_refptr<SpdyStream> spdy_stream_;
+  BufferedSpdyFramer framer_;
+
+  std::string user_agent_;
+  GURL url_;
+  HostPortPair proxy_host_port_;
+  HostPortPair endpoint_host_port_pair_;
+  ProxyServer proxy_;
+  HostPortProxyPair endpoint_host_port_proxy_pair_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy2Test);
+};
+
+SpdyProxyClientSocketSpdy2Test::SpdyProxyClientSocketSpdy2Test()
+    : sock_(NULL),
+      data_(NULL),
+      session_(NULL),
+      read_buf_(NULL),
+      session_deps_(),
+      connect_data_(SYNCHRONOUS, OK),
+      spdy_session_(NULL),
+      spdy_stream_(NULL),
+      framer_(2, false),
+      user_agent_(kUserAgent),
+      url_(kRequestUrl),
+      proxy_host_port_(kProxyHost, kProxyPort),
+      endpoint_host_port_pair_(kOriginHost, kOriginPort),
+      proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
+      endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
+      transport_params_(new TransportSocketParams(proxy_host_port_,
+                                                  LOWEST,
+                                                  false,
+                                                  false,
+                                                  OnHostResolutionCallback())) {
+}
+
+void SpdyProxyClientSocketSpdy2Test::TearDown() {
+  sock_.reset(NULL);
+  if (session_ != NULL)
+    session_->spdy_session_pool()->CloseAllSessions();
+
+  // Empty the current queue.
+  MessageLoop::current()->RunUntilIdle();
+  PlatformTest::TearDown();
+}
+
+void SpdyProxyClientSocketSpdy2Test::Initialize(MockRead* reads,
+                                           size_t reads_count,
+                                           MockWrite* writes,
+                                           size_t writes_count) {
+  data_.reset(new DeterministicSocketData(reads, reads_count,
+                                          writes, writes_count));
+  data_->set_connect_data(connect_data_);
+  data_->SetStop(2);
+
+  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
+      data_.get());
+  session_deps_.host_resolver->set_synchronous_mode(true);
+
+  session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+      &session_deps_);
+
+  // Creates a new spdy session
+  spdy_session_ =
+      session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
+                                         BoundNetLog());
+
+  // Perform the TCP connect
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK,
+            connection->Init(endpoint_host_port_pair_.ToString(),
+                             transport_params_, LOWEST, CompletionCallback(),
+                             session_->GetTransportSocketPool(
+                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
+                             BoundNetLog()));
+  spdy_session_->InitializeWithSocket(connection.release(), false, OK);
+
+  // Create the SPDY Stream
+  ASSERT_EQ(
+      OK,
+      spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
+                                  CompletionCallback()));
+
+  // Create the SpdyProxyClientSocket
+  sock_.reset(
+      new SpdyProxyClientSocket(spdy_stream_, user_agent_,
+                                endpoint_host_port_pair_, url_,
+                                proxy_host_port_, session_->http_auth_cache(),
+                                session_->http_auth_handler_factory()));
+}
+
+scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketSpdy2Test::CreateBuffer(
+    const char* data, int size) {
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
+  memcpy(buf->data(), data, size);
+  return buf;
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertConnectSucceeds() {
+  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
+  data_->Run();
+  ASSERT_EQ(OK, read_callback_.WaitForResult());
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertConnectFails(int result) {
+  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
+  data_->Run();
+  ASSERT_EQ(result, read_callback_.WaitForResult());
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertConnectionEstablished() {
+  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  ASSERT_EQ(200, response->headers->response_code());
+  ASSERT_EQ("Connection Established", response->headers->GetStatusText());
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertSyncReadEquals(const char* data,
+                                                     int len) {
+  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
+  ASSERT_EQ(len, sock_->Read(buf, len, CompletionCallback()));
+  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
+  ASSERT_TRUE(sock_->IsConnected());
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertAsyncReadEquals(const char* data,
+                                                           int len) {
+  data_->StopAfter(1);
+  // Issue the read, which will be completed asynchronously
+  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
+  ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, read_callback_.callback()));
+  EXPECT_TRUE(sock_->IsConnected());
+  data_->Run();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  // Now the read will return
+  EXPECT_EQ(len, read_callback_.WaitForResult());
+  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertReadStarts(const char* data,
+                                                      int len) {
+  data_->StopAfter(1);
+  // Issue the read, which will be completed asynchronously
+  read_buf_ = new IOBuffer(len);
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf_, len, read_callback_.callback()));
+  EXPECT_TRUE(sock_->IsConnected());
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertReadReturns(const char* data,
+                                                       int len) {
+  EXPECT_TRUE(sock_->IsConnected());
+
+  // Now the read will return
+  EXPECT_EQ(len, read_callback_.WaitForResult());
+  ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertAsyncWriteSucceeds(const char* data,
+                                                              int len) {
+  AssertWriteReturns(data, len, ERR_IO_PENDING);
+  data_->RunFor(1);
+  AssertWriteLength(len);
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertWriteReturns(const char* data,
+                                                        int len,
+                                                        int rv) {
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
+  EXPECT_EQ(rv, sock_->Write(buf, buf->size(), write_callback_.callback()));
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertWriteLength(int len) {
+  EXPECT_EQ(len, write_callback_.WaitForResult());
+}
+
+void SpdyProxyClientSocketSpdy2Test::AssertAsyncWriteWithReadsSucceeds(
+    const char* data, int len, int num_reads) {
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
+
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
+                                         write_callback_.callback()));
+
+  for (int i = 0; i < num_reads; i++) {
+    Run(1);
+    AssertSyncReadEquals(kMsg2, kLen2);
+  }
+
+  write_callback_.WaitForResult();
+}
+
+// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
+SpdyFrame*
+SpdyProxyClientSocketSpdy2Test::ConstructConnectRequestFrame() {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    kStreamId,
+    0,
+    net::ConvertRequestPriorityToSpdyPriority(LOWEST, 2),
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  const char* const kConnectHeaders[] = {
+    "method", "CONNECT",
+    "url", kOriginHostPort,
+    "host", kOriginHost,
+    "user-agent", kUserAgent,
+    "version", "HTTP/1.1",
+  };
+  return ConstructSpdyPacket(
+      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
+}
+
+// Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
+// Proxy-Authorization headers.
+SpdyFrame*
+SpdyProxyClientSocketSpdy2Test::ConstructConnectAuthRequestFrame() {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    kStreamId,
+    0,
+    net::ConvertRequestPriorityToSpdyPriority(LOWEST, 2),
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  const char* const kConnectHeaders[] = {
+    "method", "CONNECT",
+    "url", kOriginHostPort,
+    "host", kOriginHost,
+    "user-agent", kUserAgent,
+    "version", "HTTP/1.1",
+    "proxy-authorization", "Basic Zm9vOmJhcg==",
+  };
+  return ConstructSpdyPacket(
+      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
+}
+
+// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
+SpdyFrame* SpdyProxyClientSocketSpdy2Test::ConstructConnectReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      "status", "200 Connection Established",
+      "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
+SpdyFrame*
+SpdyProxyClientSocketSpdy2Test::ConstructConnectAuthReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      "status", "407 Proxy Authentication Required",
+      "version", "HTTP/1.1",
+      "proxy-authenticate", "Basic realm=\"MyRealm1\"",
+  };
+
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+// Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
+SpdyFrame*
+SpdyProxyClientSocketSpdy2Test::ConstructConnectRedirectReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      "status", "302 Found",
+      "version", "HTTP/1.1",
+      "location", kRedirectUrl,
+      "set-cookie", "foo=bar"
+  };
+
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+// Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
+SpdyFrame*
+SpdyProxyClientSocketSpdy2Test::ConstructConnectErrorReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      "status", "500 Internal Server Error",
+      "version", "HTTP/1.1",
+  };
+
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+SpdyFrame* SpdyProxyClientSocketSpdy2Test::ConstructBodyFrame(
+    const char* data,  int length) {
+  return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
+}
+
+// ----------- Connect
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ConnectSendsCorrectRequest) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  ASSERT_FALSE(sock_->IsConnected());
+
+  AssertConnectSucceeds();
+
+  AssertConnectionEstablished();
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ConnectWithAuthRequested) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
+
+  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  ASSERT_EQ(407, response->headers->response_code());
+  ASSERT_EQ("Proxy Authentication Required",
+            response->headers->GetStatusText());
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ConnectWithAuthCredentials) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+  AddAuthToCache();
+
+  AssertConnectSucceeds();
+
+  AssertConnectionEstablished();
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ConnectRedirects) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
+
+  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
+  ASSERT_TRUE(response != NULL);
+
+  const HttpResponseHeaders* headers = response->headers;
+  ASSERT_EQ(302, headers->response_code());
+  ASSERT_FALSE(headers->HasHeader("set-cookie"));
+  ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
+
+  std::string location;
+  ASSERT_TRUE(headers->IsRedirect(&location));
+  ASSERT_EQ(location, kRedirectUrl);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ConnectFails) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 1),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  ASSERT_FALSE(sock_->IsConnected());
+
+  AssertConnectFails(ERR_CONNECTION_CLOSED);
+
+  ASSERT_FALSE(sock_->IsConnected());
+}
+
+// ----------- WasEverUsed
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, WasEverUsedReturnsCorrectValues) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  EXPECT_FALSE(sock_->WasEverUsed());
+  AssertConnectSucceeds();
+  EXPECT_TRUE(sock_->WasEverUsed());
+  sock_->Disconnect();
+  EXPECT_TRUE(sock_->WasEverUsed());
+}
+
+// ----------- GetPeerAddress
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, GetPeerAddressReturnsCorrectValues) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  net::IPEndPoint addr;
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
+
+  AssertConnectSucceeds();
+  EXPECT_TRUE(sock_->IsConnected());
+  EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
+
+  Run(1);
+
+  EXPECT_FALSE(sock_->IsConnected());
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
+
+  sock_->Disconnect();
+
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
+}
+
+// ----------- Write
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, WriteSendsDataInDataFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*msg1, 2, SYNCHRONOUS),
+    CreateMockWrite(*msg2, 3, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  AssertAsyncWriteSucceeds(kMsg1, kLen1);
+  AssertAsyncWriteSucceeds(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, WriteSplitsLargeDataIntoMultipleFrames) {
+  std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
+                                                       chunk_data.length()));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*chunk, 2, SYNCHRONOUS),
+    CreateMockWrite(*chunk, 3, SYNCHRONOUS),
+    CreateMockWrite(*chunk, 4, SYNCHRONOUS)
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 5),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
+                                                   big_data.length()));
+
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
+                                         write_callback_.callback()));
+  data_->RunFor(3);
+
+  EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
+}
+
+// ----------- Read
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadReadsDataInDataFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadDataFromBufferedFrames) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadDataMultipleBufferedFrames) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test,
+       LargeReadWillMergeDataFromDifferentFrames) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg3, 2, ASYNC),
+    CreateMockRead(*msg3, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  // The payload from two data frames, each with kMsg3 will be combined
+  // together into a single read().
+  AssertSyncReadEquals(kMsg33, kLen33);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, MultipleShortReadsThenMoreRead) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg3, 3, ASYNC),
+    CreateMockRead(*msg3, 4, ASYNC),
+    CreateMockRead(*msg2, 5, ASYNC),
+    MockRead(ASYNC, 0, 6),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(4);  // SpdySession consumes the next four reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  // The payload from two data frames, each with kMsg3 will be combined
+  // together into a single read().
+  AssertSyncReadEquals(kMsg33, kLen33);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadWillSplitDataFromLargeFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg33, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  // The payload from the single large data frame will be read across
+  // two different reads.
+  AssertSyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg3, kLen3);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, MultipleReadsFromSameLargeFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg333, 2, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  // The payload from the single large data frame will be read across
+  // two different reads.
+  AssertSyncReadEquals(kMsg33, kLen33);
+
+  // Now attempt to do a read of more data than remains buffered
+  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
+  ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, read_callback_.callback()));
+  ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
+  ASSERT_TRUE(sock_->IsConnected());
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadAuthResponseBody) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadErrorResponseBody) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
+}
+
+// ----------- Reads and Writes
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, AsyncReadAroundWrite) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*msg2, 3, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),  // sync read
+    CreateMockRead(*msg3, 4, ASYNC),  // async read
+    MockRead(ASYNC, 0, 5),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);
+  AssertSyncReadEquals(kMsg1, kLen1);
+
+  AssertReadStarts(kMsg3, kLen3);
+  // Read should block until after the write succeeds
+
+  AssertAsyncWriteSucceeds(kMsg2, kLen2);  // Runs 1 step
+
+  ASSERT_FALSE(read_callback_.have_result());
+  Run(1);
+  // Now the read will return
+  AssertReadReturns(kMsg3, kLen3);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy2Test, AsyncWriteAroundReads) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*msg2, 4, ASYNC),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg3, 3, ASYNC),
+    MockRead(ASYNC, 0, 5),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);
+  AssertSyncReadEquals(kMsg1, kLen1);
+  // Write should block until the read completes
+  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
+
+  AssertAsyncReadEquals(kMsg3, kLen3);
+
+  ASSERT_FALSE(write_callback_.have_result());
+
+  // Now the write will complete
+  Run(1);
+  AssertWriteLength(kLen2);
+}
+
+// ----------- Reading/Writing on Closed socket
+
+// Reading from an already closed socket should return 0
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadOnClosedSocketReturnsZero) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);
+
+  ASSERT_FALSE(sock_->IsConnected());
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_FALSE(sock_->IsConnectedAndIdle());
+}
+
+// Read pending when socket is closed should return 0
+TEST_F(SpdyProxyClientSocketSpdy2Test, PendingReadOnCloseReturnsZero) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  AssertReadStarts(kMsg1, kLen1);
+
+  Run(1);
+
+  ASSERT_EQ(0, read_callback_.WaitForResult());
+}
+
+// Reading from a disconnected socket is an error
+TEST_F(SpdyProxyClientSocketSpdy2Test,
+       ReadOnDisconnectSocketReturnsNotConnected) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  sock_->Disconnect();
+
+  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Read(NULL, 1, CompletionCallback()));
+}
+
+// Reading buffered data from an already closed socket should return
+// buffered data, then 0.
+TEST_F(SpdyProxyClientSocketSpdy2Test, ReadOnClosedSocketReturnsBufferedData) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);
+
+  ASSERT_FALSE(sock_->IsConnected());
+  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
+  ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, CompletionCallback()));
+  ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
+
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  sock_->Disconnect();
+  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Read(NULL, 1, CompletionCallback()));
+}
+
+// Calling Write() on a closed socket is an error
+TEST_F(SpdyProxyClientSocketSpdy2Test, WriteOnClosedStream) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // Read EOF which will close the stream
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Write(buf, buf->size(), CompletionCallback()));
+}
+
+// Calling Write() on a disconnected socket is an error
+TEST_F(SpdyProxyClientSocketSpdy2Test, WriteOnDisconnectedSocket) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  sock_->Disconnect();
+
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Write(buf, buf->size(), CompletionCallback()));
+}
+
+// If the socket is closed with a pending Write(), the callback
+// should be called with ERR_CONNECTION_CLOSED.
+TEST_F(SpdyProxyClientSocketSpdy2Test, WritePendingOnClose) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(ASYNC, ERR_IO_PENDING, 2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING,
+            sock_->Write(buf, buf->size(), write_callback_.callback()));
+
+  Run(1);
+
+  EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
+}
+
+// If the socket is Disconnected with a pending Write(), the callback
+// should not be called.
+TEST_F(SpdyProxyClientSocketSpdy2Test, DisconnectWithWritePending) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(SYNCHRONOUS, 0, 2),  // EOF
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING,
+            sock_->Write(buf, buf->size(), write_callback_.callback()));
+
+  sock_->Disconnect();
+
+  EXPECT_FALSE(sock_->IsConnected());
+  EXPECT_FALSE(write_callback_.have_result());
+}
+
+// If the socket is Disconnected with a pending Read(), the callback
+// should not be called.
+TEST_F(SpdyProxyClientSocketSpdy2Test, DisconnectWithReadPending) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(buf, kLen1, read_callback_.callback()));
+
+  sock_->Disconnect();
+
+  EXPECT_FALSE(sock_->IsConnected());
+  EXPECT_FALSE(read_callback_.have_result());
+}
+
+// If the socket is Reset when both a read and write are pending,
+// both should be called back.
+TEST_F(SpdyProxyClientSocketSpdy2Test, RstWithReadAndWritePending) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(ASYNC, ERR_IO_PENDING, 2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*rst, 3, ASYNC),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf, kLen1, read_callback_.callback()));
+
+  scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING,
+            sock_->Write(write_buf, write_buf->size(),
+                         write_callback_.callback()));
+
+  Run(2);
+
+  EXPECT_TRUE(sock_.get());
+  EXPECT_TRUE(read_callback_.have_result());
+  EXPECT_TRUE(write_callback_.have_result());
+}
+
+// CompletionCallback that causes the SpdyProxyClientSocket to be
+// deleted when Run is invoked.
+class DeleteSockCallback : public TestCompletionCallbackBase {
+ public:
+  explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
+    : sock_(sock),
+      ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+          base::Bind(&DeleteSockCallback::OnComplete,
+                     base::Unretained(this)))) {
+  }
+
+  virtual ~DeleteSockCallback() {
+  }
+
+  const CompletionCallback& callback() const { return callback_; }
+
+ private:
+  void OnComplete(int result) {
+    sock_->reset(NULL);
+    SetResult(result);
+  }
+
+  scoped_ptr<SpdyProxyClientSocket>* sock_;
+  CompletionCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
+};
+
+// If the socket is Reset when both a read and write are pending, and the
+// read callback causes the socket to be deleted, the write callback should
+// not be called.
+TEST_F(SpdyProxyClientSocketSpdy2Test, RstWithReadAndWritePendingDelete) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(ASYNC, ERR_IO_PENDING, 2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*rst, 3, ASYNC),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  DeleteSockCallback read_callback(&sock_);
+
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf, kLen1, read_callback.callback()));
+
+  scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, write_buf->size(),
+                                         write_callback_.callback()));
+
+  Run(2);
+
+  EXPECT_FALSE(sock_.get());
+  EXPECT_TRUE(read_callback.have_result());
+  EXPECT_FALSE(write_callback_.have_result());
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc b/src/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc
new file mode 100644
index 0000000..627568f
--- /dev/null
+++ b/src/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc
@@ -0,0 +1,1360 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_proxy_client_socket.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/address_list.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/test_completion_callback.h"
+#include "net/base/winsock_init.h"
+#include "net/http/http_response_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/socket/client_socket_factory.h"
+#include "net/socket/tcp_client_socket.h"
+#include "net/socket/socket_test_util.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "testing/platform_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy3;
+
+//-----------------------------------------------------------------------------
+
+namespace {
+
+static const char kRequestUrl[] = "https://www.google.com/";
+static const char kOriginHost[] = "www.google.com";
+static const int kOriginPort = 443;
+static const char kOriginHostPort[] = "www.google.com:443";
+static const char kProxyUrl[] = "https://myproxy:6121/";
+static const char kProxyHost[] = "myproxy";
+static const int kProxyPort = 6121;
+static const char kUserAgent[] = "Mozilla/1.0";
+
+static const int kStreamId = 1;
+
+static const char kMsg1[] = "\0hello!\xff";
+static const int kLen1 = 8;
+static const char kMsg2[] = "\00012345678\0";
+static const int kLen2 = 10;
+static const char kMsg3[] = "bye!";
+static const int kLen3 = 4;
+static const char kMsg33[] = "bye!bye!";
+static const int kLen33 = kLen3 + kLen3;
+static const char kMsg333[] = "bye!bye!bye!";
+static const int kLen333 = kLen3 + kLen3 + kLen3;
+
+static const char kRedirectUrl[] = "https://example.com/";
+
+}  // anonymous namespace
+
+namespace net {
+
+class SpdyProxyClientSocketSpdy3Test : public PlatformTest {
+ public:
+  SpdyProxyClientSocketSpdy3Test();
+
+  virtual void TearDown();
+
+ protected:
+  void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
+                  size_t writes_count);
+  SpdyFrame* ConstructConnectRequestFrame();
+  SpdyFrame* ConstructConnectAuthRequestFrame();
+  SpdyFrame* ConstructConnectReplyFrame();
+  SpdyFrame* ConstructConnectAuthReplyFrame();
+  SpdyFrame* ConstructConnectRedirectReplyFrame();
+  SpdyFrame* ConstructConnectErrorReplyFrame();
+  SpdyFrame* ConstructBodyFrame(const char* data, int length);
+  scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
+  void AssertConnectSucceeds();
+  void AssertConnectFails(int result);
+  void AssertConnectionEstablished();
+  void AssertSyncReadEquals(const char* data, int len);
+  void AssertAsyncReadEquals(const char* data, int len);
+  void AssertReadStarts(const char* data, int len);
+  void AssertReadReturns(const char* data, int len);
+  void AssertAsyncWriteSucceeds(const char* data, int len);
+  void AssertWriteReturns(const char* data, int len, int rv);
+  void AssertWriteLength(int len);
+  void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
+                                        int num_reads);
+
+  void AddAuthToCache() {
+    const string16 kFoo(ASCIIToUTF16("foo"));
+    const string16 kBar(ASCIIToUTF16("bar"));
+    session_->http_auth_cache()->Add(GURL(kProxyUrl),
+                                     "MyRealm1",
+                                     HttpAuth::AUTH_SCHEME_BASIC,
+                                     "Basic realm=MyRealm1",
+                                     AuthCredentials(kFoo, kBar),
+                                     "/");
+  }
+
+  void Run(int steps) {
+    data_->StopAfter(steps);
+    data_->Run();
+  }
+
+  scoped_ptr<SpdyProxyClientSocket> sock_;
+  TestCompletionCallback read_callback_;
+  TestCompletionCallback write_callback_;
+  scoped_ptr<DeterministicSocketData> data_;
+
+ private:
+  scoped_refptr<HttpNetworkSession> session_;
+  scoped_refptr<IOBuffer> read_buf_;
+  SpdySessionDependencies session_deps_;
+  MockConnect connect_data_;
+  scoped_refptr<SpdySession> spdy_session_;
+  scoped_refptr<SpdyStream> spdy_stream_;
+  BufferedSpdyFramer framer_;
+
+  std::string user_agent_;
+  GURL url_;
+  HostPortPair proxy_host_port_;
+  HostPortPair endpoint_host_port_pair_;
+  ProxyServer proxy_;
+  HostPortProxyPair endpoint_host_port_proxy_pair_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy3Test);
+};
+
+SpdyProxyClientSocketSpdy3Test::SpdyProxyClientSocketSpdy3Test()
+    : sock_(NULL),
+      data_(NULL),
+      session_(NULL),
+      read_buf_(NULL),
+      session_deps_(),
+      connect_data_(SYNCHRONOUS, OK),
+      spdy_session_(NULL),
+      spdy_stream_(NULL),
+      framer_(3, false),
+      user_agent_(kUserAgent),
+      url_(kRequestUrl),
+      proxy_host_port_(kProxyHost, kProxyPort),
+      endpoint_host_port_pair_(kOriginHost, kOriginPort),
+      proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
+      endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
+      transport_params_(new TransportSocketParams(proxy_host_port_,
+                                                  LOWEST,
+                                                  false,
+                                                  false,
+                                                  OnHostResolutionCallback())) {
+}
+
+void SpdyProxyClientSocketSpdy3Test::TearDown() {
+  sock_.reset(NULL);
+  if (session_ != NULL)
+    session_->spdy_session_pool()->CloseAllSessions();
+
+  // Empty the current queue.
+  MessageLoop::current()->RunUntilIdle();
+  PlatformTest::TearDown();
+}
+
+void SpdyProxyClientSocketSpdy3Test::Initialize(MockRead* reads,
+                                           size_t reads_count,
+                                           MockWrite* writes,
+                                           size_t writes_count) {
+  data_.reset(new DeterministicSocketData(reads, reads_count,
+                                          writes, writes_count));
+  data_->set_connect_data(connect_data_);
+  data_->SetStop(2);
+
+  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
+      data_.get());
+  session_deps_.host_resolver->set_synchronous_mode(true);
+
+  session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
+      &session_deps_);
+
+  // Creates a new spdy session
+  spdy_session_ =
+      session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
+                                         BoundNetLog());
+
+  // Perform the TCP connect
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK,
+            connection->Init(endpoint_host_port_pair_.ToString(),
+                             transport_params_, LOWEST, CompletionCallback(),
+                             session_->GetTransportSocketPool(
+                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
+                             BoundNetLog()));
+  spdy_session_->InitializeWithSocket(connection.release(), false, OK);
+
+  // Create the SPDY Stream
+  ASSERT_EQ(
+      OK,
+      spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
+                                  CompletionCallback()));
+
+  // Create the SpdyProxyClientSocket
+  sock_.reset(
+      new SpdyProxyClientSocket(spdy_stream_, user_agent_,
+                                endpoint_host_port_pair_, url_,
+                                proxy_host_port_, session_->http_auth_cache(),
+                                session_->http_auth_handler_factory()));
+}
+
+scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketSpdy3Test::CreateBuffer(
+    const char* data, int size) {
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
+  memcpy(buf->data(), data, size);
+  return buf;
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertConnectSucceeds() {
+  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
+  data_->Run();
+  ASSERT_EQ(OK, read_callback_.WaitForResult());
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertConnectFails(int result) {
+  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
+  data_->Run();
+  ASSERT_EQ(result, read_callback_.WaitForResult());
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertConnectionEstablished() {
+  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  ASSERT_EQ(200, response->headers->response_code());
+  ASSERT_EQ("Connection Established", response->headers->GetStatusText());
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertSyncReadEquals(const char* data,
+                                                          int len) {
+  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
+  ASSERT_EQ(len, sock_->Read(buf, len, CompletionCallback()));
+  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
+  ASSERT_TRUE(sock_->IsConnected());
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertAsyncReadEquals(const char* data,
+                                                           int len) {
+  data_->StopAfter(1);
+  // Issue the read, which will be completed asynchronously
+  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
+  ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, read_callback_.callback()));
+  EXPECT_TRUE(sock_->IsConnected());
+  data_->Run();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  // Now the read will return
+  EXPECT_EQ(len, read_callback_.WaitForResult());
+  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertReadStarts(const char* data,
+                                                      int len) {
+  data_->StopAfter(1);
+  // Issue the read, which will be completed asynchronously
+  read_buf_ = new IOBuffer(len);
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf_, len, read_callback_.callback()));
+  EXPECT_TRUE(sock_->IsConnected());
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertReadReturns(const char* data,
+                                                       int len) {
+  EXPECT_TRUE(sock_->IsConnected());
+
+  // Now the read will return
+  EXPECT_EQ(len, read_callback_.WaitForResult());
+  ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteSucceeds(const char* data,
+                                                              int len) {
+  AssertWriteReturns(data, len, ERR_IO_PENDING);
+  data_->RunFor(1);
+  AssertWriteLength(len);
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertWriteReturns(const char* data,
+                                                        int len,
+                                                        int rv) {
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
+  EXPECT_EQ(rv, sock_->Write(buf, buf->size(), write_callback_.callback()));
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertWriteLength(int len) {
+  EXPECT_EQ(len, write_callback_.WaitForResult());
+}
+
+void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteWithReadsSucceeds(
+    const char* data, int len, int num_reads) {
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
+
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
+                                         write_callback_.callback()));
+
+  for (int i = 0; i < num_reads; i++) {
+    Run(1);
+    AssertSyncReadEquals(kMsg2, kLen2);
+  }
+
+  write_callback_.WaitForResult();
+}
+
+// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
+SpdyFrame*
+SpdyProxyClientSocketSpdy3Test::ConstructConnectRequestFrame() {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    kStreamId,
+    0,
+    net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
+    0,
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  const char* const kConnectHeaders[] = {
+    ":method", "CONNECT",
+    ":path", kOriginHostPort,
+    ":host", kOriginHost,
+    "user-agent", kUserAgent,
+    ":version", "HTTP/1.1",
+  };
+  return ConstructSpdyPacket(
+      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
+}
+
+// Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
+// Proxy-Authorization headers.
+SpdyFrame*
+SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthRequestFrame() {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    kStreamId,
+    0,
+    net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
+    0,
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  const char* const kConnectHeaders[] = {
+    ":method", "CONNECT",
+    ":path", kOriginHostPort,
+    ":host", kOriginHost,
+    "user-agent", kUserAgent,
+    ":version", "HTTP/1.1",
+    "proxy-authorization", "Basic Zm9vOmJhcg==",
+  };
+  return ConstructSpdyPacket(
+      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
+}
+
+// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
+SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructConnectReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      ":status", "200 Connection Established",
+      ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
+SpdyFrame*
+SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      ":status", "407 Proxy Authentication Required",
+      ":version", "HTTP/1.1",
+      "proxy-authenticate", "Basic realm=\"MyRealm1\"",
+  };
+
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+// Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
+SpdyFrame*
+SpdyProxyClientSocketSpdy3Test::ConstructConnectRedirectReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      ":status", "302 Found",
+      ":version", "HTTP/1.1",
+      "location", kRedirectUrl,
+      "set-cookie", "foo=bar"
+  };
+
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+// Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
+SpdyFrame*
+SpdyProxyClientSocketSpdy3Test::ConstructConnectErrorReplyFrame() {
+  const char* const kStandardReplyHeaders[] = {
+      ":status", "500 Internal Server Error",
+      ":version", "HTTP/1.1",
+  };
+
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   kStreamId,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardReplyHeaders,
+                                   arraysize(kStandardReplyHeaders));
+}
+
+SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructBodyFrame(
+    const char* data,
+    int length) {
+  return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
+}
+
+// ----------- Connect
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectSendsCorrectRequest) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  ASSERT_FALSE(sock_->IsConnected());
+
+  AssertConnectSucceeds();
+
+  AssertConnectionEstablished();
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthRequested) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
+
+  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
+  ASSERT_TRUE(response != NULL);
+  ASSERT_EQ(407, response->headers->response_code());
+  ASSERT_EQ("Proxy Authentication Required",
+            response->headers->GetStatusText());
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthCredentials) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+  AddAuthToCache();
+
+  AssertConnectSucceeds();
+
+  AssertConnectionEstablished();
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectRedirects) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
+
+  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
+  ASSERT_TRUE(response != NULL);
+
+  const HttpResponseHeaders* headers = response->headers;
+  ASSERT_EQ(302, headers->response_code());
+  ASSERT_FALSE(headers->HasHeader("set-cookie"));
+  ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
+
+  std::string location;
+  ASSERT_TRUE(headers->IsRedirect(&location));
+  ASSERT_EQ(location, kRedirectUrl);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectFails) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 1),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  ASSERT_FALSE(sock_->IsConnected());
+
+  AssertConnectFails(ERR_CONNECTION_CLOSED);
+
+  ASSERT_FALSE(sock_->IsConnected());
+}
+
+// ----------- WasEverUsed
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, WasEverUsedReturnsCorrectValues) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  EXPECT_FALSE(sock_->WasEverUsed());
+  AssertConnectSucceeds();
+  EXPECT_TRUE(sock_->WasEverUsed());
+  sock_->Disconnect();
+  EXPECT_TRUE(sock_->WasEverUsed());
+}
+
+// ----------- GetPeerAddress
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, GetPeerAddressReturnsCorrectValues) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  net::IPEndPoint addr;
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
+
+  AssertConnectSucceeds();
+  EXPECT_TRUE(sock_->IsConnected());
+  EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
+
+  Run(1);
+
+  EXPECT_FALSE(sock_->IsConnected());
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
+
+  sock_->Disconnect();
+
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
+}
+
+// ----------- Write
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSendsDataInDataFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*msg1, 2, SYNCHRONOUS),
+    CreateMockWrite(*msg2, 3, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  AssertAsyncWriteSucceeds(kMsg1, kLen1);
+  AssertAsyncWriteSucceeds(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSplitsLargeDataIntoMultipleFrames) {
+  std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
+                                                       chunk_data.length()));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*chunk, 2, SYNCHRONOUS),
+    CreateMockWrite(*chunk, 3, SYNCHRONOUS),
+    CreateMockWrite(*chunk, 4, SYNCHRONOUS)
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 5),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
+                                                   big_data.length()));
+
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
+                                         write_callback_.callback()));
+  data_->RunFor(3);
+
+  EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
+}
+
+// ----------- Read
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadReadsDataInDataFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataFromBufferedFrames) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataMultipleBufferedFrames) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test,
+       LargeReadWillMergeDataFromDifferentFrames) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg3, 2, ASYNC),
+    CreateMockRead(*msg3, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  // The payload from two data frames, each with kMsg3 will be combined
+  // together into a single read().
+  AssertSyncReadEquals(kMsg33, kLen33);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleShortReadsThenMoreRead) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg3, 3, ASYNC),
+    CreateMockRead(*msg3, 4, ASYNC),
+    CreateMockRead(*msg2, 5, ASYNC),
+    MockRead(ASYNC, 0, 6),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(4);  // SpdySession consumes the next four reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  // The payload from two data frames, each with kMsg3 will be combined
+  // together into a single read().
+  AssertSyncReadEquals(kMsg33, kLen33);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadWillSplitDataFromLargeFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg33, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  // The payload from the single large data frame will be read across
+  // two different reads.
+  AssertSyncReadEquals(kMsg3, kLen3);
+  AssertSyncReadEquals(kMsg3, kLen3);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleReadsFromSameLargeFrame) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg333, 2, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // SpdySession consumes the next read and sends it to
+           // sock_ to be buffered.
+  // The payload from the single large data frame will be read across
+  // two different reads.
+  AssertSyncReadEquals(kMsg33, kLen33);
+
+  // Now attempt to do a read of more data than remains buffered
+  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
+  ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, read_callback_.callback()));
+  ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
+  ASSERT_TRUE(sock_->IsConnected());
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadAuthResponseBody) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
+
+  Run(2);  // SpdySession consumes the next two reads and sends then to
+           // sock_ to be buffered.
+  AssertSyncReadEquals(kMsg1, kLen1);
+  AssertSyncReadEquals(kMsg2, kLen2);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadErrorResponseBody) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg2, 3, ASYNC),
+    MockRead(ASYNC, 0, 4),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
+}
+
+// ----------- Reads and Writes
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncReadAroundWrite) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*msg2, 3, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),  // sync read
+    CreateMockRead(*msg3, 4, ASYNC),  // async read
+    MockRead(ASYNC, 0, 5),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);
+  AssertSyncReadEquals(kMsg1, kLen1);
+
+  AssertReadStarts(kMsg3, kLen3);
+  // Read should block until after the write succeeds
+
+  AssertAsyncWriteSucceeds(kMsg2, kLen2);  // Runs 1 step
+
+  ASSERT_FALSE(read_callback_.have_result());
+  Run(1);
+  // Now the read will return
+  AssertReadReturns(kMsg3, kLen3);
+}
+
+TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncWriteAroundReads) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    CreateMockWrite(*msg2, 4, ASYNC),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    CreateMockRead(*msg3, 3, ASYNC),
+    MockRead(ASYNC, 0, 5),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);
+  AssertSyncReadEquals(kMsg1, kLen1);
+  // Write should block until the read completes
+  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
+
+  AssertAsyncReadEquals(kMsg3, kLen3);
+
+  ASSERT_FALSE(write_callback_.have_result());
+
+  // Now the write will complete
+  Run(1);
+  AssertWriteLength(kLen2);
+}
+
+// ----------- Reading/Writing on Closed socket
+
+// Reading from an already closed socket should return 0
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsZero) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);
+
+  ASSERT_FALSE(sock_->IsConnected());
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_FALSE(sock_->IsConnectedAndIdle());
+}
+
+// Read pending when socket is closed should return 0
+TEST_F(SpdyProxyClientSocketSpdy3Test, PendingReadOnCloseReturnsZero) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  AssertReadStarts(kMsg1, kLen1);
+
+  Run(1);
+
+  ASSERT_EQ(0, read_callback_.WaitForResult());
+}
+
+// Reading from a disconnected socket is an error
+TEST_F(SpdyProxyClientSocketSpdy3Test,
+       ReadOnDisconnectSocketReturnsNotConnected) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  sock_->Disconnect();
+
+  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Read(NULL, 1, CompletionCallback()));
+}
+
+// Reading buffered data from an already closed socket should return
+// buffered data, then 0.
+TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsBufferedData) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*msg1, 2, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(2);
+
+  ASSERT_FALSE(sock_->IsConnected());
+  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
+  ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, CompletionCallback()));
+  ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
+
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
+  sock_->Disconnect();
+  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Read(NULL, 1, CompletionCallback()));
+}
+
+// Calling Write() on a closed socket is an error
+TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnClosedStream) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  Run(1);  // Read EOF which will close the stream
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Write(buf, buf->size(), CompletionCallback()));
+}
+
+// Calling Write() on a disconnected socket is an error
+TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnDisconnectedSocket) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  sock_->Disconnect();
+
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
+            sock_->Write(buf, buf->size(), CompletionCallback()));
+}
+
+// If the socket is closed with a pending Write(), the callback
+// should be called with ERR_CONNECTION_CLOSED.
+TEST_F(SpdyProxyClientSocketSpdy3Test, WritePendingOnClose) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(ASYNC, ERR_IO_PENDING, 2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING,
+            sock_->Write(buf, buf->size(), write_callback_.callback()));
+
+  Run(1);
+
+  EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
+}
+
+// If the socket is Disconnected with a pending Write(), the callback
+// should not be called.
+TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithWritePending) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(SYNCHRONOUS, 0, 2),  // EOF
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 3),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING,
+            sock_->Write(buf, buf->size(), write_callback_.callback()));
+
+  sock_->Disconnect();
+
+  EXPECT_FALSE(sock_->IsConnected());
+  EXPECT_FALSE(write_callback_.have_result());
+}
+
+// If the socket is Disconnected with a pending Read(), the callback
+// should not be called.
+TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithReadPending) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    MockRead(ASYNC, 0, 2),  // EOF
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(buf, kLen1, read_callback_.callback()));
+
+  sock_->Disconnect();
+
+  EXPECT_FALSE(sock_->IsConnected());
+  EXPECT_FALSE(read_callback_.have_result());
+}
+
+// If the socket is Reset when both a read and write are pending,
+// both should be called back.
+TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePending) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(ASYNC, ERR_IO_PENDING, 2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*rst, 3, ASYNC),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf, kLen1, read_callback_.callback()));
+
+  scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING,
+            sock_->Write(write_buf, write_buf->size(),
+                         write_callback_.callback()));
+
+  Run(2);
+
+  EXPECT_TRUE(sock_.get());
+  EXPECT_TRUE(read_callback_.have_result());
+  EXPECT_TRUE(write_callback_.have_result());
+}
+
+// CompletionCallback that causes the SpdyProxyClientSocket to be
+// deleted when Run is invoked.
+class DeleteSockCallback : public TestCompletionCallbackBase {
+ public:
+  explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
+    : sock_(sock),
+      ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+          base::Bind(&DeleteSockCallback::OnComplete,
+                     base::Unretained(this)))) {
+  }
+
+  virtual ~DeleteSockCallback() {
+  }
+
+  const CompletionCallback& callback() const { return callback_; }
+
+ private:
+  void OnComplete(int result) {
+    sock_->reset(NULL);
+    SetResult(result);
+  }
+
+  scoped_ptr<SpdyProxyClientSocket>* sock_;
+  CompletionCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
+};
+
+// If the socket is Reset when both a read and write are pending, and the
+// read callback causes the socket to be deleted, the write callback should
+// not be called.
+TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePendingDelete) {
+  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  MockWrite writes[] = {
+    CreateMockWrite(*conn, 0, SYNCHRONOUS),
+    MockWrite(ASYNC, ERR_IO_PENDING, 2),
+  };
+
+  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
+  MockRead reads[] = {
+    CreateMockRead(*resp, 1, ASYNC),
+    CreateMockRead(*rst, 3, ASYNC),
+  };
+
+  Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+  AssertConnectSucceeds();
+
+  EXPECT_TRUE(sock_->IsConnected());
+
+  DeleteSockCallback read_callback(&sock_);
+
+  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
+  ASSERT_EQ(ERR_IO_PENDING,
+            sock_->Read(read_buf, kLen1, read_callback.callback()));
+
+  scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
+  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, write_buf->size(),
+                                         write_callback_.callback()));
+
+  Run(2);
+
+  EXPECT_FALSE(sock_.get());
+  EXPECT_TRUE(read_callback.have_result());
+  EXPECT_FALSE(write_callback_.have_result());
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_session.cc b/src/net/spdy/spdy_session.cc
new file mode 100644
index 0000000..9982a59
--- /dev/null
+++ b/src/net/spdy/spdy_session.cc
@@ -0,0 +1,1976 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_session.h"
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/stats_counters.h"
+#include "base/stl_util.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/time.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "crypto/ec_private_key.h"
+#include "crypto/ec_signature_creator.h"
+#include "net/base/asn1_util.h"
+#include "net/base/connection_type_histograms.h"
+#include "net/base/net_log.h"
+#include "net/base/net_util.h"
+#include "net/base/server_bound_cert_service.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_server_properties.h"
+#include "net/spdy/spdy_credential_builder.h"
+#include "net/spdy/spdy_frame_builder.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+namespace {
+
+const int kReadBufferSize = 8 * 1024;
+const int kDefaultConnectionAtRiskOfLossSeconds = 10;
+const int kHungIntervalSeconds = 10;
+
+// Minimum seconds that unclaimed pushed streams will be kept in memory.
+const int kMinPushedStreamLifetimeSeconds = 300;
+
+Value* NetLogSpdySynCallback(const SpdyHeaderBlock* headers,
+                             bool fin,
+                             bool unidirectional,
+                             SpdyStreamId stream_id,
+                             SpdyStreamId associated_stream,
+                             NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  ListValue* headers_list = new ListValue();
+  for (SpdyHeaderBlock::const_iterator it = headers->begin();
+       it != headers->end(); ++it) {
+    headers_list->Append(new StringValue(base::StringPrintf(
+        "%s: %s", it->first.c_str(), it->second.c_str())));
+  }
+  dict->SetBoolean("fin", fin);
+  dict->SetBoolean("unidirectional", unidirectional);
+  dict->Set("headers", headers_list);
+  dict->SetInteger("stream_id", stream_id);
+  if (associated_stream)
+    dict->SetInteger("associated_stream", associated_stream);
+  return dict;
+}
+
+Value* NetLogSpdyCredentialCallback(size_t slot,
+                                    const std::string* origin,
+                                    NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("slot", slot);
+  dict->SetString("origin", *origin);
+  return dict;
+}
+
+Value* NetLogSpdySessionCloseCallback(int net_error,
+                                      const std::string* description,
+                                      NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("net_error", net_error);
+  dict->SetString("description", *description);
+  return dict;
+}
+
+Value* NetLogSpdySessionCallback(const HostPortProxyPair* host_pair,
+                                 NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetString("host", host_pair->first.ToString());
+  dict->SetString("proxy", host_pair->second.ToPacString());
+  return dict;
+}
+
+Value* NetLogSpdySettingCallback(SpdySettingsIds id,
+                                 SpdySettingsFlags flags,
+                                 uint32 value,
+                                 NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("id", id);
+  dict->SetInteger("flags", flags);
+  dict->SetInteger("value", value);
+  return dict;
+}
+
+Value* NetLogSpdySettingsCallback(const SettingsMap* settings,
+                                  NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  ListValue* settings_list = new ListValue();
+  for (SettingsMap::const_iterator it = settings->begin();
+       it != settings->end(); ++it) {
+    const SpdySettingsIds id = it->first;
+    const SpdySettingsFlags flags = it->second.first;
+    const uint32 value = it->second.second;
+    settings_list->Append(new StringValue(
+        base::StringPrintf("[id:%u flags:%u value:%u]", id, flags, value)));
+  }
+  dict->Set("settings", settings_list);
+  return dict;
+}
+
+Value* NetLogSpdyWindowUpdateCallback(SpdyStreamId stream_id,
+                                      int32 delta,
+                                      NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("stream_id", static_cast<int>(stream_id));
+  dict->SetInteger("delta", delta);
+  return dict;
+}
+
+Value* NetLogSpdyDataCallback(SpdyStreamId stream_id,
+                              int size,
+                              SpdyDataFlags flags,
+                              NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("stream_id", static_cast<int>(stream_id));
+  dict->SetInteger("size", size);
+  dict->SetInteger("flags", static_cast<int>(flags));
+  return dict;
+}
+
+Value* NetLogSpdyRstCallback(SpdyStreamId stream_id,
+                             int status,
+                             const std::string* description,
+                             NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("stream_id", static_cast<int>(stream_id));
+  dict->SetInteger("status", status);
+  dict->SetString("description", *description);
+  return dict;
+}
+
+Value* NetLogSpdyPingCallback(uint32 unique_id,
+                              const char* type,
+                              NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("unique_id", unique_id);
+  dict->SetString("type", type);
+  return dict;
+}
+
+Value* NetLogSpdyGoAwayCallback(SpdyStreamId last_stream_id,
+                                int active_streams,
+                                int unclaimed_streams,
+                                SpdyGoAwayStatus status,
+                                NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("last_accepted_stream_id",
+                   static_cast<int>(last_stream_id));
+  dict->SetInteger("active_streams", active_streams);
+  dict->SetInteger("unclaimed_streams", unclaimed_streams);
+  dict->SetInteger("status", static_cast<int>(status));
+  return dict;
+}
+
+// Maximum number of concurrent streams we will create, unless the server
+// sends a SETTINGS frame with a different value.
+const size_t kInitialMaxConcurrentStreams = 100;
+// The maximum number of concurrent streams we will ever create.  Even if
+// the server permits more, we will never exceed this limit.
+const size_t kMaxConcurrentStreamLimit = 256;
+const size_t kDefaultInitialRecvWindowSize = 10 * 1024 * 1024;  // 10MB
+
+}  // namespace
+
+// static
+void SpdySession::SpdyIOBufferProducer::ActivateStream(
+    SpdySession* spdy_session,
+    SpdyStream* spdy_stream) {
+  spdy_session->ActivateStream(spdy_stream);
+}
+
+// static
+SpdyIOBuffer* SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
+    SpdyFrame* frame,
+    RequestPriority priority,
+    SpdyStream* stream) {
+  size_t size = frame->length() + SpdyFrame::kHeaderSize;
+  DCHECK_GT(size, 0u);
+
+  // TODO(mbelshe): We have too much copying of data here.
+  IOBufferWithSize* buffer = new IOBufferWithSize(size);
+  memcpy(buffer->data(), frame->data(), size);
+
+  return new SpdyIOBuffer(buffer, size, priority, stream);
+}
+
+SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
+                         SpdySessionPool* spdy_session_pool,
+                         HttpServerProperties* http_server_properties,
+                         bool verify_domain_authentication,
+                         bool enable_sending_initial_settings,
+                         bool enable_credential_frames,
+                         bool enable_compression,
+                         bool enable_ping_based_connection_checking,
+                         NextProto default_protocol,
+                         size_t initial_recv_window_size,
+                         size_t initial_max_concurrent_streams,
+                         size_t max_concurrent_streams_limit,
+                         TimeFunc time_func,
+                         const HostPortPair& trusted_spdy_proxy,
+                         NetLog* net_log)
+    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+      host_port_proxy_pair_(host_port_proxy_pair),
+      spdy_session_pool_(spdy_session_pool),
+      http_server_properties_(http_server_properties),
+      connection_(new ClientSocketHandle),
+      read_buffer_(new IOBuffer(kReadBufferSize)),
+      read_pending_(false),
+      stream_hi_water_mark_(1),  // Always start at 1 for the first stream id.
+      write_pending_(false),
+      delayed_write_pending_(false),
+      is_secure_(false),
+      certificate_error_code_(OK),
+      error_(OK),
+      state_(IDLE),
+      max_concurrent_streams_(initial_max_concurrent_streams == 0 ?
+                              kInitialMaxConcurrentStreams :
+                              initial_max_concurrent_streams),
+      max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ?
+                                    kMaxConcurrentStreamLimit :
+                                    max_concurrent_streams_limit),
+      streams_initiated_count_(0),
+      streams_pushed_count_(0),
+      streams_pushed_and_claimed_count_(0),
+      streams_abandoned_count_(0),
+      bytes_received_(0),
+      sent_settings_(false),
+      received_settings_(false),
+      stalled_streams_(0),
+      pings_in_flight_(0),
+      next_ping_id_(1),
+      last_activity_time_(base::TimeTicks::Now()),
+      check_ping_status_pending_(false),
+      flow_control_(false),
+      initial_send_window_size_(kSpdyStreamInitialWindowSize),
+      initial_recv_window_size_(initial_recv_window_size == 0 ?
+                                kDefaultInitialRecvWindowSize :
+                                initial_recv_window_size),
+      net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)),
+      verify_domain_authentication_(verify_domain_authentication),
+      enable_sending_initial_settings_(enable_sending_initial_settings),
+      enable_credential_frames_(enable_credential_frames),
+      enable_compression_(enable_compression),
+      enable_ping_based_connection_checking_(
+          enable_ping_based_connection_checking),
+      default_protocol_(default_protocol),
+      credential_state_(SpdyCredentialState::kDefaultNumSlots),
+      connection_at_risk_of_loss_time_(
+          base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)),
+      hung_interval_(
+          base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
+      trusted_spdy_proxy_(trusted_spdy_proxy),
+      time_func_(time_func) {
+  DCHECK(HttpStreamFactory::spdy_enabled());
+  net_log_.BeginEvent(
+      NetLog::TYPE_SPDY_SESSION,
+      base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_));
+  next_unclaimed_push_stream_sweep_time_ = time_func_() +
+      base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
+  // TODO(mbelshe): consider randomization of the stream_hi_water_mark.
+}
+
+SpdySession::PendingCreateStream::PendingCreateStream(
+    const GURL& url, RequestPriority priority,
+    scoped_refptr<SpdyStream>* spdy_stream,
+    const BoundNetLog& stream_net_log,
+    const CompletionCallback& callback)
+    : url(&url),
+      priority(priority),
+      spdy_stream(spdy_stream),
+      stream_net_log(&stream_net_log),
+      callback(callback) {
+}
+
+SpdySession::PendingCreateStream::~PendingCreateStream() {}
+
+SpdySession::CallbackResultPair::CallbackResultPair(
+    const CompletionCallback& callback_in, int result_in)
+    : callback(callback_in),
+      result(result_in) {
+}
+
+SpdySession::CallbackResultPair::~CallbackResultPair() {}
+
+SpdySession::~SpdySession() {
+  if (state_ != CLOSED) {
+    state_ = CLOSED;
+
+    // Cleanup all the streams.
+    CloseAllStreams(net::ERR_ABORTED);
+  }
+
+  if (connection_->is_initialized()) {
+    // With SPDY we can't recycle sockets.
+    connection_->socket()->Disconnect();
+  }
+
+  // Streams should all be gone now.
+  DCHECK_EQ(0u, num_active_streams());
+  DCHECK_EQ(0u, num_unclaimed_pushed_streams());
+
+  DCHECK(pending_callback_map_.empty());
+
+  RecordHistograms();
+
+  net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION);
+}
+
+net::Error SpdySession::InitializeWithSocket(
+    ClientSocketHandle* connection,
+    bool is_secure,
+    int certificate_error_code) {
+  base::StatsCounter spdy_sessions("spdy.sessions");
+  spdy_sessions.Increment();
+
+  state_ = CONNECTED;
+  connection_.reset(connection);
+  is_secure_ = is_secure;
+  certificate_error_code_ = certificate_error_code;
+
+  NextProto protocol = default_protocol_;
+  NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol();
+  if (protocol_negotiated != kProtoUnknown) {
+    protocol = protocol_negotiated;
+  }
+
+  SSLClientSocket* ssl_socket = GetSSLClientSocket();
+  if (ssl_socket && ssl_socket->WasChannelIDSent()) {
+    // According to the SPDY spec, the credential associated with the TLS
+    // connection is stored in slot[1].
+    credential_state_.SetHasCredential(GURL("https://" +
+                                            host_port_pair().ToString()));
+  }
+
+  DCHECK(protocol >= kProtoSPDY2);
+  DCHECK(protocol <= kProtoSPDY3);
+  int version = (protocol == kProtoSPDY3) ? 3 : 2;
+  flow_control_ = (protocol >= kProtoSPDY3);
+
+  buffered_spdy_framer_.reset(new BufferedSpdyFramer(version,
+                                                     enable_compression_));
+  buffered_spdy_framer_->set_visitor(this);
+  SendInitialSettings();
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol, kProtoMaximumVersion);
+
+  // Write out any data that we might have to send, such as the settings frame.
+  WriteSocketLater();
+  net::Error error = ReadSocket();
+  if (error == ERR_IO_PENDING)
+    return OK;
+  return error;
+}
+
+bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
+  if (!verify_domain_authentication_)
+    return true;
+
+  if (state_ != CONNECTED)
+    return false;
+
+  SSLInfo ssl_info;
+  bool was_npn_negotiated;
+  NextProto protocol_negotiated = kProtoUnknown;
+  if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
+    return true;   // This is not a secure session, so all domains are okay.
+
+  return !ssl_info.client_cert_sent &&
+      (enable_credential_frames_ || !ssl_info.channel_id_sent ||
+       ServerBoundCertService::GetDomainForHost(domain) ==
+       ServerBoundCertService::GetDomainForHost(
+           host_port_proxy_pair_.first.host())) &&
+      ssl_info.cert->VerifyNameMatch(domain);
+}
+
+void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream,
+                                             SpdyIOBufferProducer* producer) {
+  write_queue_.push(producer);
+  stream_producers_[producer] = stream;
+  WriteSocketLater();
+}
+
+int SpdySession::GetPushStream(
+    const GURL& url,
+    scoped_refptr<SpdyStream>* stream,
+    const BoundNetLog& stream_net_log) {
+  CHECK_NE(state_, CLOSED);
+
+  *stream = NULL;
+
+  // Don't allow access to secure push streams over an unauthenticated, but
+  // encrypted SSL socket.
+  if (is_secure_ && certificate_error_code_ != OK &&
+      (url.SchemeIs("https") || url.SchemeIs("wss"))) {
+    RecordProtocolErrorHistogram(
+        PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
+    CloseSessionOnError(
+        static_cast<net::Error>(certificate_error_code_),
+        true,
+        "Tried to get SPDY stream for secure content over an unauthenticated "
+        "session.");
+    return ERR_SPDY_PROTOCOL_ERROR;
+  }
+
+  *stream = GetActivePushStream(url.spec());
+  if (stream->get()) {
+    DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_);
+    streams_pushed_and_claimed_count_++;
+    return OK;
+  }
+  return 0;
+}
+
+int SpdySession::CreateStream(
+    const GURL& url,
+    RequestPriority priority,
+    scoped_refptr<SpdyStream>* spdy_stream,
+    const BoundNetLog& stream_net_log,
+    const CompletionCallback& callback) {
+  if (!max_concurrent_streams_ ||
+      (active_streams_.size() + created_streams_.size() <
+       max_concurrent_streams_)) {
+    return CreateStreamImpl(url, priority, spdy_stream, stream_net_log);
+  }
+
+  stalled_streams_++;
+  net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS);
+  pending_create_stream_queues_[priority].push(
+      PendingCreateStream(url, priority, spdy_stream,
+                          stream_net_log, callback));
+  return ERR_IO_PENDING;
+}
+
+void SpdySession::ProcessPendingCreateStreams() {
+  while (!max_concurrent_streams_ ||
+         (active_streams_.size() + created_streams_.size() <
+          max_concurrent_streams_)) {
+    bool no_pending_create_streams = true;
+    for (int i = NUM_PRIORITIES - 1; i >= MINIMUM_PRIORITY; --i) {
+      if (!pending_create_stream_queues_[i].empty()) {
+        PendingCreateStream pending_create =
+            pending_create_stream_queues_[i].front();
+        pending_create_stream_queues_[i].pop();
+        no_pending_create_streams = false;
+        int error = CreateStreamImpl(*pending_create.url,
+                                     pending_create.priority,
+                                     pending_create.spdy_stream,
+                                     *pending_create.stream_net_log);
+        scoped_refptr<SpdyStream>* stream = pending_create.spdy_stream;
+        DCHECK(!ContainsKey(pending_callback_map_, stream));
+        pending_callback_map_.insert(std::make_pair(stream,
+            CallbackResultPair(pending_create.callback, error)));
+        MessageLoop::current()->PostTask(
+            FROM_HERE,
+            base::Bind(&SpdySession::InvokeUserStreamCreationCallback,
+                       weak_factory_.GetWeakPtr(), stream));
+        break;
+      }
+    }
+    if (no_pending_create_streams)
+      return;  // there were no streams in any queue
+  }
+}
+
+void SpdySession::CancelPendingCreateStreams(
+    const scoped_refptr<SpdyStream>* spdy_stream) {
+  PendingCallbackMap::iterator it = pending_callback_map_.find(spdy_stream);
+  if (it != pending_callback_map_.end()) {
+    pending_callback_map_.erase(it);
+    return;
+  }
+
+  for (int i = 0; i < NUM_PRIORITIES; ++i) {
+    PendingCreateStreamQueue tmp;
+    // Make a copy removing this trans
+    while (!pending_create_stream_queues_[i].empty()) {
+      PendingCreateStream pending_create =
+          pending_create_stream_queues_[i].front();
+      pending_create_stream_queues_[i].pop();
+      if (pending_create.spdy_stream != spdy_stream)
+        tmp.push(pending_create);
+    }
+    // Now copy it back
+    while (!tmp.empty()) {
+      pending_create_stream_queues_[i].push(tmp.front());
+      tmp.pop();
+    }
+  }
+}
+
+int SpdySession::CreateStreamImpl(
+    const GURL& url,
+    RequestPriority priority,
+    scoped_refptr<SpdyStream>* spdy_stream,
+    const BoundNetLog& stream_net_log) {
+  DCHECK_GE(priority, MINIMUM_PRIORITY);
+  DCHECK_LT(priority, NUM_PRIORITIES);
+
+  // Make sure that we don't try to send https/wss over an unauthenticated, but
+  // encrypted SSL socket.
+  if (is_secure_ && certificate_error_code_ != OK &&
+      (url.SchemeIs("https") || url.SchemeIs("wss"))) {
+    RecordProtocolErrorHistogram(
+        PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
+    CloseSessionOnError(
+        static_cast<net::Error>(certificate_error_code_),
+        true,
+        "Tried to create SPDY stream for secure content over an "
+        "unauthenticated session.");
+    return ERR_SPDY_PROTOCOL_ERROR;
+  }
+
+  const std::string& path = url.PathForRequest();
+
+  *spdy_stream = new SpdyStream(this,
+                                false,
+                                stream_net_log);
+  const scoped_refptr<SpdyStream>& stream = *spdy_stream;
+
+  stream->set_priority(priority);
+  stream->set_path(path);
+  stream->set_send_window_size(initial_send_window_size_);
+  stream->set_recv_window_size(initial_recv_window_size_);
+  created_streams_.insert(stream);
+
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount",
+      static_cast<int>(priority), 0, 10, 11);
+
+  // TODO(mbelshe): Optimize memory allocations
+
+  return OK;
+}
+
+bool SpdySession::NeedsCredentials() const {
+  if (!is_secure_)
+    return false;
+  SSLClientSocket* ssl_socket = GetSSLClientSocket();
+  if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3)
+    return false;
+  return ssl_socket->WasChannelIDSent();
+}
+
+void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) {
+  pooled_aliases_.insert(alias);
+}
+
+int SpdySession::GetProtocolVersion() const {
+  DCHECK(buffered_spdy_framer_.get());
+  return buffered_spdy_framer_->protocol_version();
+}
+
+SpdySynStreamControlFrame* SpdySession::CreateSynStream(
+    SpdyStreamId stream_id,
+    RequestPriority priority,
+    uint8 credential_slot,
+    SpdyControlFlags flags,
+    const SpdyHeaderBlock& headers) {
+  CHECK(IsStreamActive(stream_id));
+  const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+
+  SendPrefacePingIfNoneInFlight();
+
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdySynStreamControlFrame> syn_frame(
+      buffered_spdy_framer_->CreateSynStream(
+          stream_id, 0,
+          ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()),
+          credential_slot, flags, true, &headers));
+
+  base::StatsCounter spdy_requests("spdy.requests");
+  spdy_requests.Increment();
+  streams_initiated_count_++;
+
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
+        base::Bind(&NetLogSpdySynCallback, &headers,
+                   (flags & CONTROL_FLAG_FIN) != 0,
+                   (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0,
+                   stream_id, 0));
+  }
+
+  return syn_frame.release();
+}
+
+SpdyCredentialControlFrame* SpdySession::CreateCredentialFrame(
+    const std::string& origin,
+    SSLClientCertType type,
+    const std::string& key,
+    const std::string& cert,
+    RequestPriority priority) {
+  DCHECK(is_secure_);
+  SSLClientSocket* ssl_socket = GetSSLClientSocket();
+  DCHECK(ssl_socket);
+  DCHECK(ssl_socket->WasChannelIDSent());
+
+  SpdyCredential credential;
+  std::string tls_unique;
+  ssl_socket->GetTLSUniqueChannelBinding(&tls_unique);
+  size_t slot = credential_state_.SetHasCredential(GURL(origin));
+  int rv = SpdyCredentialBuilder::Build(tls_unique, type, key, cert, slot,
+                                        &credential);
+  DCHECK_EQ(OK, rv);
+  if (rv != OK)
+    return NULL;
+
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdyCredentialControlFrame> credential_frame(
+      buffered_spdy_framer_->CreateCredentialFrame(credential));
+
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL,
+        base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin));
+  }
+  return credential_frame.release();
+}
+
+SpdyHeadersControlFrame* SpdySession::CreateHeadersFrame(
+    SpdyStreamId stream_id,
+    const SpdyHeaderBlock& headers,
+    SpdyControlFlags flags) {
+  // Find our stream
+  CHECK(IsStreamActive(stream_id));
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+
+  // Create a HEADER frame.
+  scoped_ptr<SpdyHeadersControlFrame> frame(
+      buffered_spdy_framer_->CreateHeaders(stream_id, flags, true, &headers));
+
+  if (net_log().IsLoggingAllEvents()) {
+    bool fin = flags & CONTROL_FLAG_FIN;
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_SEND_HEADERS,
+        base::Bind(&NetLogSpdySynCallback,
+                   &headers, fin, /*unidirectional=*/false,
+                   stream_id, 0));
+  }
+  return frame.release();
+}
+
+SpdyDataFrame* SpdySession::CreateDataFrame(SpdyStreamId stream_id,
+                                            net::IOBuffer* data, int len,
+                                            SpdyDataFlags flags) {
+  // Find our stream
+  CHECK(IsStreamActive(stream_id));
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+
+  if (len > kMaxSpdyFrameChunkSize) {
+    len = kMaxSpdyFrameChunkSize;
+    flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
+  }
+
+  // Obey send window size of the stream if flow control is enabled.
+  if (flow_control_) {
+    if (stream->send_window_size() <= 0) {
+      // Because we queue frames onto the session, it is possible that
+      // a stream was not flow controlled at the time it attempted the
+      // write, but when we go to fulfill the write, it is now flow
+      // controlled.  This is why we need the session to mark the stream
+      // as stalled - because only the session knows for sure when the
+      // stall occurs.
+      stream->set_stalled_by_flow_control(true);
+      net_log().AddEvent(
+          NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW,
+          NetLog::IntegerCallback("stream_id", stream_id));
+      return NULL;
+    }
+    int new_len = std::min(len, stream->send_window_size());
+    if (new_len < len) {
+      len = new_len;
+      flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
+    }
+    stream->DecreaseSendWindowSize(len);
+  }
+
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_SEND_DATA,
+        base::Bind(&NetLogSpdyDataCallback, stream_id, len, flags));
+  }
+
+  // Send PrefacePing for DATA_FRAMEs with nonzero payload size.
+  if (len > 0)
+    SendPrefacePingIfNoneInFlight();
+
+  // TODO(mbelshe): reduce memory copies here.
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdyDataFrame> frame(
+      buffered_spdy_framer_->CreateDataFrame(
+          stream_id, data->data(), len, flags));
+
+  return frame.release();
+}
+
+void SpdySession::CloseStream(SpdyStreamId stream_id, int status) {
+  DCHECK_NE(0u, stream_id);
+  // TODO(mbelshe): We should send a RST_STREAM control frame here
+  //                so that the server can cancel a large send.
+
+  DeleteStream(stream_id, status);
+}
+
+void SpdySession::CloseCreatedStream(SpdyStream* stream, int status) {
+  DCHECK_EQ(0u, stream->stream_id());
+  created_streams_.erase(scoped_refptr<SpdyStream>(stream));
+  ProcessPendingCreateStreams();
+}
+
+void SpdySession::ResetStream(SpdyStreamId stream_id,
+                              SpdyStatusCodes status,
+                              const std::string& description) {
+  net_log().AddEvent(
+      NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM,
+      base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description));
+
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdyRstStreamControlFrame> rst_frame(
+      buffered_spdy_framer_->CreateRstStream(stream_id, status));
+
+  // Default to lowest priority unless we know otherwise.
+  RequestPriority priority = net::IDLE;
+  if(IsStreamActive(stream_id)) {
+    scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+    priority = stream->priority();
+  }
+  QueueFrame(rst_frame.release(), priority);
+  RecordProtocolErrorHistogram(
+      static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID));
+  DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
+}
+
+bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const {
+  return ContainsKey(active_streams_, stream_id);
+}
+
+LoadState SpdySession::GetLoadState() const {
+  // NOTE: The application only queries the LoadState via the
+  //       SpdyNetworkTransaction, and details are only needed when
+  //       we're in the process of connecting.
+
+  // If we're connecting, defer to the connection to give us the actual
+  // LoadState.
+  if (state_ == CONNECTING)
+    return connection_->GetLoadState();
+
+  // Just report that we're idle since the session could be doing
+  // many things concurrently.
+  return LOAD_STATE_IDLE;
+}
+
+void SpdySession::OnReadComplete(int bytes_read) {
+  // Parse a frame.  For now this code requires that the frame fit into our
+  // buffer (32KB).
+  // TODO(mbelshe): support arbitrarily large frames!
+
+  read_pending_ = false;
+
+  if (bytes_read <= 0) {
+    // Session is tearing down.
+    net::Error error = static_cast<net::Error>(bytes_read);
+    if (bytes_read == 0)
+      error = ERR_CONNECTION_CLOSED;
+    CloseSessionOnError(error, true, "bytes_read is <= 0.");
+    return;
+  }
+
+  bytes_received_ += bytes_read;
+
+  last_activity_time_ = base::TimeTicks::Now();
+
+  // The SpdyFramer will use callbacks onto |this| as it parses frames.
+  // When errors occur, those callbacks can lead to teardown of all references
+  // to |this|, so maintain a reference to self during this call for safe
+  // cleanup.
+  scoped_refptr<SpdySession> self(this);
+
+  DCHECK(buffered_spdy_framer_.get());
+  char *data = read_buffer_->data();
+  while (bytes_read &&
+         buffered_spdy_framer_->error_code() ==
+             SpdyFramer::SPDY_NO_ERROR) {
+    uint32 bytes_processed =
+        buffered_spdy_framer_->ProcessInput(data, bytes_read);
+    bytes_read -= bytes_processed;
+    data += bytes_processed;
+    if (buffered_spdy_framer_->state() == SpdyFramer::SPDY_DONE)
+      buffered_spdy_framer_->Reset();
+  }
+
+  if (state_ != CLOSED)
+    ReadSocket();
+}
+
+void SpdySession::OnWriteComplete(int result) {
+  DCHECK(write_pending_);
+  DCHECK(in_flight_write_.size());
+
+  last_activity_time_ = base::TimeTicks::Now();
+  write_pending_ = false;
+
+  scoped_refptr<SpdyStream> stream = in_flight_write_.stream();
+
+  if (result >= 0) {
+    // It should not be possible to have written more bytes than our
+    // in_flight_write_.
+    DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining());
+
+    in_flight_write_.buffer()->DidConsume(result);
+
+    // We only notify the stream when we've fully written the pending frame.
+    if (!in_flight_write_.buffer()->BytesRemaining()) {
+      if (stream) {
+        // Report the number of bytes written to the caller, but exclude the
+        // frame size overhead.  NOTE: if this frame was compressed the
+        // reported bytes written is the compressed size, not the original
+        // size.
+        if (result > 0) {
+          result = in_flight_write_.buffer()->size();
+          DCHECK_GE(result, static_cast<int>(SpdyFrame::kHeaderSize));
+          result -= static_cast<int>(SpdyFrame::kHeaderSize);
+        }
+
+        // It is possible that the stream was cancelled while we were writing
+        // to the socket.
+        if (!stream->cancelled())
+          stream->OnWriteComplete(result);
+      }
+
+      // Cleanup the write which just completed.
+      in_flight_write_.release();
+    }
+
+    // Write more data.  We're already in a continuation, so we can
+    // go ahead and write it immediately (without going back to the
+    // message loop).
+    WriteSocketLater();
+  } else {
+    in_flight_write_.release();
+
+    // The stream is now errored.  Close it down.
+    CloseSessionOnError(
+        static_cast<net::Error>(result), true, "The stream has errored.");
+  }
+}
+
+net::Error SpdySession::ReadSocket() {
+  if (read_pending_)
+    return OK;
+
+  if (state_ == CLOSED) {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  CHECK(connection_.get());
+  CHECK(connection_->socket());
+  int bytes_read = connection_->socket()->Read(
+      read_buffer_.get(),
+      kReadBufferSize,
+      base::Bind(&SpdySession::OnReadComplete, base::Unretained(this)));
+  switch (bytes_read) {
+    case 0:
+      // Socket is closed!
+      CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0.");
+      return ERR_CONNECTION_CLOSED;
+    case net::ERR_IO_PENDING:
+      // Waiting for data.  Nothing to do now.
+      read_pending_ = true;
+      return ERR_IO_PENDING;
+    default:
+      // Data was read, process it.
+      // Schedule the work through the message loop to avoid recursive
+      // callbacks.
+      read_pending_ = true;
+      MessageLoop::current()->PostTask(
+          FROM_HERE,
+          base::Bind(&SpdySession::OnReadComplete,
+                     weak_factory_.GetWeakPtr(), bytes_read));
+      break;
+  }
+  return OK;
+}
+
+void SpdySession::WriteSocketLater() {
+  if (delayed_write_pending_)
+    return;
+
+  if (state_ < CONNECTED)
+    return;
+
+  delayed_write_pending_ = true;
+  MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr()));
+}
+
+void SpdySession::WriteSocket() {
+  // This function should only be called via WriteSocketLater.
+  DCHECK(delayed_write_pending_);
+  delayed_write_pending_ = false;
+
+  // If the socket isn't connected yet, just wait; we'll get called
+  // again when the socket connection completes.  If the socket is
+  // closed, just return.
+  if (state_ < CONNECTED || state_ == CLOSED)
+    return;
+
+  if (write_pending_)   // Another write is in progress still.
+    return;
+
+  // Loop sending frames until we've sent everything or until the write
+  // returns error (or ERR_IO_PENDING).
+  DCHECK(buffered_spdy_framer_.get());
+  while (in_flight_write_.buffer() || !write_queue_.empty()) {
+    if (!in_flight_write_.buffer()) {
+      // Grab the next SpdyBuffer to send.
+      scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top());
+      write_queue_.pop();
+      scoped_ptr<SpdyIOBuffer> buffer(producer->ProduceNextBuffer(this));
+      stream_producers_.erase(producer.get());
+      // It is possible that a stream had data to write, but a
+      // WINDOW_UPDATE frame has been received which made that
+      // stream no longer writable.
+      // TODO(rch): consider handling that case by removing the
+      // stream from the writable queue?
+      if (buffer == NULL)
+        continue;
+
+      in_flight_write_ = *buffer;
+    } else {
+      DCHECK(in_flight_write_.buffer()->BytesRemaining());
+    }
+
+    write_pending_ = true;
+    int rv = connection_->socket()->Write(
+        in_flight_write_.buffer(),
+        in_flight_write_.buffer()->BytesRemaining(),
+        base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this)));
+    if (rv == net::ERR_IO_PENDING)
+      break;
+
+    // We sent the frame successfully.
+    OnWriteComplete(rv);
+
+    // TODO(mbelshe):  Test this error case.  Maybe we should mark the socket
+    //                 as in an error state.
+    if (rv < 0)
+      break;
+  }
+}
+
+void SpdySession::CloseAllStreams(net::Error status) {
+  base::StatsCounter abandoned_streams("spdy.abandoned_streams");
+  base::StatsCounter abandoned_push_streams(
+      "spdy.abandoned_push_streams");
+
+  if (!active_streams_.empty())
+    abandoned_streams.Add(active_streams_.size());
+  if (!unclaimed_pushed_streams_.empty()) {
+    streams_abandoned_count_ += unclaimed_pushed_streams_.size();
+    abandoned_push_streams.Add(unclaimed_pushed_streams_.size());
+    unclaimed_pushed_streams_.clear();
+  }
+
+  for (int i = 0; i < NUM_PRIORITIES; ++i) {
+    while (!pending_create_stream_queues_[i].empty()) {
+      PendingCreateStream pending_create =
+          pending_create_stream_queues_[i].front();
+      pending_create_stream_queues_[i].pop();
+      pending_create.callback.Run(ERR_ABORTED);
+    }
+  }
+
+  while (!active_streams_.empty()) {
+    ActiveStreamMap::iterator it = active_streams_.begin();
+    const scoped_refptr<SpdyStream>& stream = it->second;
+    LogAbandonedStream(stream, status);
+    DeleteStream(stream->stream_id(), status);
+  }
+
+  while (!created_streams_.empty()) {
+    CreatedStreamSet::iterator it = created_streams_.begin();
+    const scoped_refptr<SpdyStream> stream = *it;
+    created_streams_.erase(it);
+    LogAbandonedStream(stream, status);
+    stream->OnClose(status);
+  }
+
+  // We also need to drain the queue.
+  while (!write_queue_.empty()) {
+    scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top());
+    write_queue_.pop();
+    stream_producers_.erase(producer.get());
+  }
+}
+
+void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream,
+                                     net::Error status) {
+  DCHECK(stream);
+  std::string description = base::StringPrintf(
+      "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path();
+  stream->LogStreamError(status, description);
+}
+
+int SpdySession::GetNewStreamId() {
+  int id = stream_hi_water_mark_;
+  stream_hi_water_mark_ += 2;
+  if (stream_hi_water_mark_ > 0x7fff)
+    stream_hi_water_mark_ = 1;
+  return id;
+}
+
+void SpdySession::CloseSessionOnError(net::Error err,
+                                      bool remove_from_pool,
+                                      const std::string& description) {
+  // Closing all streams can have a side-effect of dropping the last reference
+  // to |this|.  Hold a reference through this function.
+  scoped_refptr<SpdySession> self(this);
+
+  DCHECK_LT(err, OK);
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_CLOSE,
+      base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
+
+  // Don't close twice.  This can occur because we can have both
+  // a read and a write outstanding, and each can complete with
+  // an error.
+  if (state_ != CLOSED) {
+    state_ = CLOSED;
+    error_ = err;
+    if (remove_from_pool)
+      RemoveFromPool();
+    CloseAllStreams(err);
+  }
+}
+
+Value* SpdySession::GetInfoAsValue() const {
+  DictionaryValue* dict = new DictionaryValue();
+
+  dict->SetInteger("source_id", net_log_.source().id);
+
+  dict->SetString("host_port_pair", host_port_proxy_pair_.first.ToString());
+  if (!pooled_aliases_.empty()) {
+    ListValue* alias_list = new ListValue();
+    for (std::set<HostPortProxyPair>::const_iterator it =
+             pooled_aliases_.begin();
+         it != pooled_aliases_.end(); it++) {
+      alias_list->Append(Value::CreateStringValue(it->first.ToString()));
+    }
+    dict->Set("aliases", alias_list);
+  }
+  dict->SetString("proxy", host_port_proxy_pair_.second.ToURI());
+
+  dict->SetInteger("active_streams", active_streams_.size());
+
+  dict->SetInteger("unclaimed_pushed_streams",
+      unclaimed_pushed_streams_.size());
+
+  dict->SetBoolean("is_secure", is_secure_);
+
+  dict->SetString("protocol_negotiated",
+                  SSLClientSocket::NextProtoToString(
+                      connection_->socket()->GetNegotiatedProtocol()));
+
+  dict->SetInteger("error", error_);
+  dict->SetInteger("max_concurrent_streams", max_concurrent_streams_);
+
+  dict->SetInteger("streams_initiated_count", streams_initiated_count_);
+  dict->SetInteger("streams_pushed_count", streams_pushed_count_);
+  dict->SetInteger("streams_pushed_and_claimed_count",
+      streams_pushed_and_claimed_count_);
+  dict->SetInteger("streams_abandoned_count", streams_abandoned_count_);
+  DCHECK(buffered_spdy_framer_.get());
+  dict->SetInteger("frames_received", buffered_spdy_framer_->frames_received());
+
+  dict->SetBoolean("sent_settings", sent_settings_);
+  dict->SetBoolean("received_settings", received_settings_);
+  return dict;
+}
+
+bool SpdySession::IsReused() const {
+  return buffered_spdy_framer_->frames_received() > 0;
+}
+
+int SpdySession::GetPeerAddress(IPEndPoint* address) const {
+  if (!connection_->socket())
+    return ERR_SOCKET_NOT_CONNECTED;
+
+  return connection_->socket()->GetPeerAddress(address);
+}
+
+int SpdySession::GetLocalAddress(IPEndPoint* address) const {
+  if (!connection_->socket())
+    return ERR_SOCKET_NOT_CONNECTED;
+
+  return connection_->socket()->GetLocalAddress(address);
+}
+
+class SimpleSpdyIOBufferProducer : public SpdySession::SpdyIOBufferProducer {
+ public:
+  SimpleSpdyIOBufferProducer(SpdyFrame* frame,
+                             RequestPriority priority)
+      : frame_(frame),
+        priority_(priority) {
+  }
+
+  virtual RequestPriority GetPriority() const OVERRIDE {
+    return priority_;
+  }
+
+  virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) OVERRIDE {
+    return SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
+        frame_.get(), priority_, NULL);
+  }
+
+ private:
+  scoped_ptr<SpdyFrame> frame_;
+  RequestPriority priority_;
+};
+
+void SpdySession::QueueFrame(SpdyFrame* frame,
+                             RequestPriority priority) {
+  SimpleSpdyIOBufferProducer* producer =
+      new SimpleSpdyIOBufferProducer(frame, priority);
+  write_queue_.push(producer);
+  WriteSocketLater();
+}
+
+void SpdySession::ActivateStream(SpdyStream* stream) {
+  if (stream->stream_id() == 0) {
+    stream->set_stream_id(GetNewStreamId());
+    created_streams_.erase(scoped_refptr<SpdyStream>(stream));
+  }
+  const SpdyStreamId id = stream->stream_id();
+  DCHECK(!IsStreamActive(id));
+
+  active_streams_[id] = stream;
+}
+
+void SpdySession::DeleteStream(SpdyStreamId id, int status) {
+  // For push streams, if they are being deleted normally, we leave
+  // the stream in the unclaimed_pushed_streams_ list.  However, if
+  // the stream is errored out, clean it up entirely.
+  if (status != OK) {
+    PushedStreamMap::iterator it;
+    for (it = unclaimed_pushed_streams_.begin();
+         it != unclaimed_pushed_streams_.end(); ++it) {
+      scoped_refptr<SpdyStream> curr = it->second.first;
+      if (id == curr->stream_id()) {
+        unclaimed_pushed_streams_.erase(it);
+        break;
+      }
+    }
+  }
+
+  // The stream might have been deleted.
+  ActiveStreamMap::iterator it2 = active_streams_.find(id);
+  if (it2 == active_streams_.end())
+    return;
+
+  // Possibly remove from the write queue.
+  WriteQueue old = write_queue_;
+  write_queue_ = WriteQueue();
+  while (!old.empty()) {
+    scoped_ptr<SpdyIOBufferProducer> producer(old.top());
+    old.pop();
+    StreamProducerMap::iterator it = stream_producers_.find(producer.get());
+    if (it == stream_producers_.end() || it->second->stream_id() != id) {
+      write_queue_.push(producer.release());
+    } else {
+      stream_producers_.erase(producer.get());
+      producer.reset(NULL);
+    }
+  }
+
+  // If this is an active stream, call the callback.
+  const scoped_refptr<SpdyStream> stream(it2->second);
+  active_streams_.erase(it2);
+  if (stream)
+    stream->OnClose(status);
+  ProcessPendingCreateStreams();
+}
+
+void SpdySession::RemoveFromPool() {
+  if (spdy_session_pool_) {
+    SpdySessionPool* pool = spdy_session_pool_;
+    spdy_session_pool_ = NULL;
+    pool->Remove(make_scoped_refptr(this));
+  }
+}
+
+scoped_refptr<SpdyStream> SpdySession::GetActivePushStream(
+    const std::string& path) {
+  base::StatsCounter used_push_streams("spdy.claimed_push_streams");
+
+  PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path);
+  if (it != unclaimed_pushed_streams_.end()) {
+    net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM);
+    scoped_refptr<SpdyStream> stream = it->second.first;
+    unclaimed_pushed_streams_.erase(it);
+    used_push_streams.Increment();
+    return stream;
+  }
+  return NULL;
+}
+
+bool SpdySession::GetSSLInfo(SSLInfo* ssl_info,
+                             bool* was_npn_negotiated,
+                             NextProto* protocol_negotiated) {
+
+  *was_npn_negotiated = connection_->socket()->WasNpnNegotiated();
+  *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol();
+  return connection_->socket()->GetSSLInfo(ssl_info);
+}
+
+bool SpdySession::GetSSLCertRequestInfo(
+    SSLCertRequestInfo* cert_request_info) {
+  if (!is_secure_)
+    return false;
+  GetSSLClientSocket()->GetSSLCertRequestInfo(cert_request_info);
+  return true;
+}
+
+ServerBoundCertService* SpdySession::GetServerBoundCertService() const {
+  if (!is_secure_)
+    return NULL;
+  return GetSSLClientSocket()->GetServerBoundCertService();
+}
+
+void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
+  RecordProtocolErrorHistogram(
+      static_cast<SpdyProtocolErrorDetails>(error_code));
+  std::string description = base::StringPrintf(
+      "SPDY_ERROR error_code: %d.", error_code);
+  CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true, description);
+}
+
+void SpdySession::OnStreamError(SpdyStreamId stream_id,
+                                const std::string& description) {
+  if (IsStreamActive(stream_id))
+    ResetStream(stream_id, PROTOCOL_ERROR, description);
+}
+
+void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
+                                    const char* data,
+                                    size_t len,
+                                    SpdyDataFlags flags) {
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_RECV_DATA,
+        base::Bind(&NetLogSpdyDataCallback, stream_id, len, flags));
+  }
+
+  if (!IsStreamActive(stream_id)) {
+    // NOTE:  it may just be that the stream was cancelled.
+    return;
+  }
+
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  stream->OnDataReceived(data, len);
+}
+
+void SpdySession::OnSetting(SpdySettingsIds id,
+                            uint8 flags,
+                            uint32 value) {
+  HandleSetting(id, value);
+  http_server_properties_->SetSpdySetting(
+      host_port_pair(),
+      id,
+      static_cast<SpdySettingsFlags>(flags),
+      value);
+  received_settings_ = true;
+
+  // Log the setting.
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_RECV_SETTING,
+      base::Bind(&NetLogSpdySettingCallback,
+                 id, static_cast<SpdySettingsFlags>(flags), value));
+}
+
+void SpdySession::OnControlFrameCompressed(
+    const SpdyControlFrame& uncompressed_frame,
+    const SpdyControlFrame& compressed_frame) {
+  if (uncompressed_frame.type() == SYN_STREAM) {
+    int uncompressed_size = uncompressed_frame.length();
+    int compressed_size = compressed_frame.length();
+    // Make sure we avoid early decimal truncation.
+    int compression_pct = 100 - (100 * compressed_size) / uncompressed_size;
+    UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage",
+                             compression_pct);
+  }
+}
+
+
+bool SpdySession::Respond(const SpdyHeaderBlock& headers,
+                          const scoped_refptr<SpdyStream> stream) {
+  int rv = OK;
+  rv = stream->OnResponseReceived(headers);
+  if (rv < 0) {
+    DCHECK_NE(rv, ERR_IO_PENDING);
+    const SpdyStreamId stream_id = stream->stream_id();
+    DeleteStream(stream_id, rv);
+    return false;
+  }
+  return true;
+}
+
+void SpdySession::OnSynStream(SpdyStreamId stream_id,
+                              SpdyStreamId associated_stream_id,
+                              SpdyPriority priority,
+                              uint8 credential_slot,
+                              bool fin,
+                              bool unidirectional,
+                              const SpdyHeaderBlock& headers) {
+  if (net_log_.IsLoggingAllEvents()) {
+    net_log_.AddEvent(
+        NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM,
+        base::Bind(&NetLogSpdySynCallback,
+                   &headers, fin, unidirectional,
+                   stream_id, associated_stream_id));
+  }
+
+  // Server-initiated streams should have even sequence numbers.
+  if ((stream_id & 0x1) != 0) {
+    LOG(WARNING) << "Received invalid OnSyn stream id " << stream_id;
+    return;
+  }
+
+  if (IsStreamActive(stream_id)) {
+    LOG(WARNING) << "Received OnSyn for active stream " << stream_id;
+    return;
+  }
+
+  if (associated_stream_id == 0) {
+    std::string description = base::StringPrintf(
+        "Received invalid OnSyn associated stream id %d for stream %d",
+        associated_stream_id, stream_id);
+    ResetStream(stream_id, REFUSED_STREAM, description);
+    return;
+  }
+
+  streams_pushed_count_++;
+
+  // TODO(mbelshe): DCHECK that this is a GET method?
+
+  // Verify that the response had a URL for us.
+  GURL gurl = GetUrlFromHeaderBlock(headers, GetProtocolVersion(), true);
+  if (!gurl.is_valid()) {
+    ResetStream(stream_id, PROTOCOL_ERROR,
+                "Pushed stream url was invalid: " + gurl.spec());
+    return;
+  }
+  const std::string& url = gurl.spec();
+
+  // Verify we have a valid stream association.
+  if (!IsStreamActive(associated_stream_id)) {
+    ResetStream(stream_id, INVALID_STREAM,
+                base::StringPrintf(
+                    "Received OnSyn with inactive associated stream %d",
+                    associated_stream_id));
+    return;
+  }
+
+  // Check that the SYN advertises the same origin as its associated stream.
+  // Bypass this check if and only if this session is with a SPDY proxy that
+  // is trusted explicitly via the --trusted-spdy-proxy switch.
+  if (trusted_spdy_proxy_.Equals(host_port_pair())) {
+    // Disallow pushing of HTTPS content.
+    if (gurl.SchemeIs("https")) {
+      ResetStream(stream_id, REFUSED_STREAM,
+                  base::StringPrintf(
+                      "Rejected push of Cross Origin HTTPS content %d",
+                      associated_stream_id));
+    }
+  } else {
+    scoped_refptr<SpdyStream> associated_stream =
+        active_streams_[associated_stream_id];
+    GURL associated_url(associated_stream->GetUrl());
+    if (associated_url.GetOrigin() != gurl.GetOrigin()) {
+      ResetStream(stream_id, REFUSED_STREAM,
+                  base::StringPrintf(
+                      "Rejected Cross Origin Push Stream %d",
+                      associated_stream_id));
+      return;
+    }
+  }
+
+  // There should not be an existing pushed stream with the same path.
+  PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url);
+  if (it != unclaimed_pushed_streams_.end()) {
+    ResetStream(stream_id, PROTOCOL_ERROR,
+                "Received duplicate pushed stream with url: " + url);
+    return;
+  }
+
+  scoped_refptr<SpdyStream> stream(new SpdyStream(this, true, net_log_));
+  stream->set_stream_id(stream_id);
+
+  stream->set_path(gurl.PathForRequest());
+  stream->set_send_window_size(initial_send_window_size_);
+  stream->set_recv_window_size(initial_recv_window_size_);
+
+  DeleteExpiredPushedStreams();
+  unclaimed_pushed_streams_[url] =
+      std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> (
+          stream, time_func_());
+
+
+  ActivateStream(stream);
+  stream->set_response_received();
+
+  // Parse the headers.
+  if (!Respond(headers, stream))
+    return;
+
+  base::StatsCounter push_requests("spdy.pushed_streams");
+  push_requests.Increment();
+}
+
+void SpdySession::DeleteExpiredPushedStreams() {
+  if (unclaimed_pushed_streams_.empty())
+    return;
+
+  // Check that adequate time has elapsed since the last sweep.
+  if (time_func_() < next_unclaimed_push_stream_sweep_time_)
+    return;
+
+  // Delete old streams.
+  base::TimeTicks minimum_freshness = time_func_() -
+      base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
+  PushedStreamMap::iterator it;
+  for (it = unclaimed_pushed_streams_.begin();
+      it != unclaimed_pushed_streams_.end(); ) {
+    const scoped_refptr<SpdyStream>& stream = it->second.first;
+    base::TimeTicks creation_time = it->second.second;
+    // DeleteStream() will invalidate the current iterator, so move to next.
+    ++it;
+    if (minimum_freshness > creation_time) {
+      DeleteStream(stream->stream_id(), ERR_INVALID_SPDY_STREAM);
+      base::StatsCounter abandoned_push_streams(
+          "spdy.abandoned_push_streams");
+      base::StatsCounter abandoned_streams("spdy.abandoned_streams");
+      abandoned_push_streams.Increment();
+      abandoned_streams.Increment();
+      streams_abandoned_count_++;
+    }
+  }
+  next_unclaimed_push_stream_sweep_time_ = time_func_() +
+      base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
+}
+
+void SpdySession::OnSynReply(SpdyStreamId stream_id,
+                             bool fin,
+                             const SpdyHeaderBlock& headers) {
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_SYN_REPLY,
+        base::Bind(&NetLogSpdySynCallback,
+                   &headers, fin, false,// not unidirectional
+                   stream_id, 0));
+  }
+
+  if (!IsStreamActive(stream_id)) {
+    // NOTE:  it may just be that the stream was cancelled.
+    LOG(WARNING) << "Received SYN_REPLY for invalid stream " << stream_id;
+    return;
+  }
+
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+  CHECK(!stream->cancelled());
+
+  if (stream->response_received()) {
+    stream->LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED,
+                           "Received duplicate SYN_REPLY for stream.");
+    RecordProtocolErrorHistogram(PROTOCOL_ERROR_SYN_REPLY_NOT_RECEIVED);
+    CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR);
+    return;
+  }
+  stream->set_response_received();
+
+  Respond(headers, stream);
+}
+
+void SpdySession::OnHeaders(SpdyStreamId stream_id,
+                            bool fin,
+                            const SpdyHeaderBlock& headers) {
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_RECV_HEADERS,
+        base::Bind(&NetLogSpdySynCallback,
+                   &headers, fin, /*unidirectional=*/false,
+                   stream_id, 0));
+  }
+
+  if (!IsStreamActive(stream_id)) {
+    // NOTE:  it may just be that the stream was cancelled.
+    LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id;
+    return;
+  }
+
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+  CHECK(!stream->cancelled());
+
+  int rv = stream->OnHeaders(headers);
+  if (rv < 0) {
+    DCHECK_NE(rv, ERR_IO_PENDING);
+    const SpdyStreamId stream_id = stream->stream_id();
+    DeleteStream(stream_id, rv);
+  }
+}
+
+void SpdySession::OnRstStream(SpdyStreamId stream_id, SpdyStatusCodes status) {
+  std::string description;
+  net_log().AddEvent(
+      NetLog::TYPE_SPDY_SESSION_RST_STREAM,
+      base::Bind(&NetLogSpdyRstCallback,
+                 stream_id, status, &description));
+
+  if (!IsStreamActive(stream_id)) {
+    // NOTE:  it may just be that the stream was cancelled.
+    LOG(WARNING) << "Received RST for invalid stream" << stream_id;
+    return;
+  }
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+  CHECK(!stream->cancelled());
+
+  if (status == 0) {
+    stream->OnDataReceived(NULL, 0);
+  } else if (status == REFUSED_STREAM) {
+    DeleteStream(stream_id, ERR_SPDY_SERVER_REFUSED_STREAM);
+  } else {
+    RecordProtocolErrorHistogram(
+        PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM);
+    stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR,
+                           base::StringPrintf("SPDY stream closed: %d",
+                                              status));
+    // TODO(mbelshe): Map from Spdy-protocol errors to something sensical.
+    //                For now, it doesn't matter much - it is a protocol error.
+    DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
+  }
+}
+
+void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
+                           SpdyGoAwayStatus status) {
+  net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY,
+      base::Bind(&NetLogSpdyGoAwayCallback,
+                 last_accepted_stream_id,
+                 active_streams_.size(),
+                 unclaimed_pushed_streams_.size(),
+                 status));
+  RemoveFromPool();
+  CloseAllStreams(net::ERR_ABORTED);
+
+  // TODO(willchan): Cancel any streams that are past the GoAway frame's
+  // |last_accepted_stream_id|.
+
+  // Don't bother killing any streams that are still reading.  They'll either
+  // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is
+  // closed.
+}
+
+void SpdySession::OnPing(uint32 unique_id) {
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_PING,
+      base::Bind(&NetLogSpdyPingCallback, unique_id, "received"));
+
+  // Send response to a PING from server.
+  if (unique_id % 2 == 0) {
+    WritePingFrame(unique_id);
+    return;
+  }
+
+  --pings_in_flight_;
+  if (pings_in_flight_ < 0) {
+    RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING);
+    CloseSessionOnError(
+        net::ERR_SPDY_PROTOCOL_ERROR, true, "pings_in_flight_ is < 0.");
+    pings_in_flight_ = 0;
+    return;
+  }
+
+  if (pings_in_flight_ > 0)
+    return;
+
+  // We will record RTT in histogram when there are no more client sent
+  // pings_in_flight_.
+  RecordPingRTTHistogram(base::TimeTicks::Now() - last_ping_sent_time_);
+}
+
+void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
+                                 int delta_window_size) {
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_RECEIVED_WINDOW_UPDATE,
+      base::Bind(&NetLogSpdyWindowUpdateCallback,
+                 stream_id, delta_window_size));
+
+  if (!IsStreamActive(stream_id)) {
+    LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id;
+    return;
+  }
+
+  if (delta_window_size < 1) {
+    ResetStream(stream_id, FLOW_CONTROL_ERROR,
+                base::StringPrintf(
+                    "Received WINDOW_UPDATE with an invalid "
+                    "delta_window_size %d", delta_window_size));
+    return;
+  }
+
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+  CHECK(!stream->cancelled());
+
+  if (flow_control_)
+    stream->IncreaseSendWindowSize(delta_window_size);
+}
+
+void SpdySession::SendWindowUpdate(SpdyStreamId stream_id,
+                                   int32 delta_window_size) {
+  CHECK(IsStreamActive(stream_id));
+  scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+  CHECK_EQ(stream->stream_id(), stream_id);
+
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE,
+      base::Bind(&NetLogSpdyWindowUpdateCallback,
+                 stream_id, delta_window_size));
+
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
+      buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size));
+  QueueFrame(window_update_frame.release(), stream->priority());
+}
+
+// Given a cwnd that we would have sent to the server, modify it based on the
+// field trial policy.
+uint32 ApplyCwndFieldTrialPolicy(int cwnd) {
+#if defined(COBALT)
+  // Cobalt doesn't support field trials.
+  return cwnd;
+#else
+  base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd");
+  if (!trial) {
+      LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList";
+      return cwnd;
+  }
+  if (trial->group_name() == "cwnd10")
+    return 10;
+  else if (trial->group_name() == "cwnd16")
+    return 16;
+  else if (trial->group_name() == "cwndMin16")
+    return std::max(cwnd, 16);
+  else if (trial->group_name() == "cwndMin10")
+    return std::max(cwnd, 10);
+  else if (trial->group_name() == "cwndDynamic")
+    return cwnd;
+  NOTREACHED();
+  return cwnd;
+#endif
+}
+
+void SpdySession::SendInitialSettings() {
+  // First notify the server about the settings they should use when
+  // communicating with us.
+  if (GetProtocolVersion() >= 2 && enable_sending_initial_settings_) {
+    SettingsMap settings_map;
+    // Create a new settings frame notifying the sever of our
+    // max_concurrent_streams_ and initial window size.
+    settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
+        SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
+    if (GetProtocolVersion() > 2 &&
+        initial_recv_window_size_ != kSpdyStreamInitialWindowSize) {
+      settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
+          SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_recv_window_size_);
+    }
+    SendSettings(settings_map);
+  }
+
+  // Next notify the server about the settings they have previously
+  // told us to use when communicating with them.
+  const SettingsMap& settings_map =
+      http_server_properties_->GetSpdySettings(host_port_pair());
+  if (settings_map.empty())
+    return;
+
+  // Record Histogram Data and Apply the SpdyCwnd FieldTrial if applicable.
+  const SpdySettingsIds id = SETTINGS_CURRENT_CWND;
+  SettingsMap::const_iterator it = settings_map.find(id);
+  uint32 value = 0;
+  if (it != settings_map.end())
+    value = it->second.second;
+  uint32 cwnd = ApplyCwndFieldTrialPolicy(value);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100);
+  if (cwnd != value) {
+    http_server_properties_->SetSpdySetting(
+        host_port_pair(), id, SETTINGS_FLAG_PLEASE_PERSIST, cwnd);
+  }
+
+  const SettingsMap& settings_map_new =
+      http_server_properties_->GetSpdySettings(host_port_pair());
+  for (SettingsMap::const_iterator i = settings_map_new.begin(),
+           end = settings_map_new.end(); i != end; ++i) {
+    const SpdySettingsIds new_id = i->first;
+    const uint32 new_val = i->second.second;
+    HandleSetting(new_id, new_val);
+  }
+
+  SendSettings(settings_map_new);
+}
+
+
+void SpdySession::SendSettings(const SettingsMap& settings) {
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
+      base::Bind(&NetLogSpdySettingsCallback, &settings));
+
+  // Create the SETTINGS frame and send it.
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdySettingsControlFrame> settings_frame(
+      buffered_spdy_framer_->CreateSettings(settings));
+  sent_settings_ = true;
+  QueueFrame(settings_frame.release(), HIGHEST);
+}
+
+void SpdySession::HandleSetting(uint32 id, uint32 value) {
+  switch (id) {
+    case SETTINGS_MAX_CONCURRENT_STREAMS:
+      max_concurrent_streams_ = std::min(static_cast<size_t>(value),
+                                         kMaxConcurrentStreamLimit);
+      ProcessPendingCreateStreams();
+      break;
+    case SETTINGS_INITIAL_WINDOW_SIZE:
+      if (static_cast<int32>(value) < 0) {
+        net_log().AddEvent(
+            NetLog::TYPE_SPDY_SESSION_NEGATIVE_INITIAL_WINDOW_SIZE,
+            NetLog::IntegerCallback("initial_window_size", value));
+      } else {
+        // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only.
+        int32 delta_window_size = value - initial_send_window_size_;
+        initial_send_window_size_ = value;
+        UpdateStreamsSendWindowSize(delta_window_size);
+        net_log().AddEvent(
+            NetLog::TYPE_SPDY_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE,
+            NetLog::IntegerCallback("delta_window_size", delta_window_size));
+      }
+      break;
+  }
+}
+
+void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) {
+  ActiveStreamMap::iterator it;
+  for (it = active_streams_.begin(); it != active_streams_.end(); ++it) {
+    const scoped_refptr<SpdyStream>& stream = it->second;
+    DCHECK(stream);
+    stream->AdjustSendWindowSize(delta_window_size);
+  }
+
+  CreatedStreamSet::iterator i;
+  for (i = created_streams_.begin(); i != created_streams_.end(); i++) {
+    const scoped_refptr<SpdyStream>& stream = *i;
+    stream->AdjustSendWindowSize(delta_window_size);
+  }
+}
+
+void SpdySession::SendPrefacePingIfNoneInFlight() {
+  if (pings_in_flight_ || !enable_ping_based_connection_checking_)
+    return;
+
+  base::TimeTicks now = base::TimeTicks::Now();
+  // If there is no activity in the session, then send a preface-PING.
+  if ((now - last_activity_time_) > connection_at_risk_of_loss_time_)
+    SendPrefacePing();
+}
+
+void SpdySession::SendPrefacePing() {
+  WritePingFrame(next_ping_id_);
+}
+
+void SpdySession::WritePingFrame(uint32 unique_id) {
+  DCHECK(buffered_spdy_framer_.get());
+  scoped_ptr<SpdyPingControlFrame> ping_frame(
+      buffered_spdy_framer_->CreatePingFrame(unique_id));
+  QueueFrame(ping_frame.release(), HIGHEST);
+
+  if (net_log().IsLoggingAllEvents()) {
+    net_log().AddEvent(
+        NetLog::TYPE_SPDY_SESSION_PING,
+        base::Bind(&NetLogSpdyPingCallback, unique_id, "sent"));
+  }
+  if (unique_id % 2 != 0) {
+    next_ping_id_ += 2;
+    ++pings_in_flight_;
+    PlanToCheckPingStatus();
+    last_ping_sent_time_ = base::TimeTicks::Now();
+  }
+}
+
+void SpdySession::PlanToCheckPingStatus() {
+  if (check_ping_status_pending_)
+    return;
+
+  check_ping_status_pending_ = true;
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(),
+                 base::TimeTicks::Now()), hung_interval_);
+}
+
+void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) {
+  // Check if we got a response back for all PINGs we had sent.
+  if (pings_in_flight_ == 0) {
+    check_ping_status_pending_ = false;
+    return;
+  }
+
+  DCHECK(check_ping_status_pending_);
+
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::TimeDelta delay = hung_interval_ - (now - last_activity_time_);
+
+  if (delay.InMilliseconds() < 0 || last_activity_time_ < last_check_time) {
+    CloseSessionOnError(net::ERR_SPDY_PING_FAILED, true, "Failed ping.");
+    // Track all failed PING messages in a separate bucket.
+    const base::TimeDelta kFailedPing =
+        base::TimeDelta::FromInternalValue(INT_MAX);
+    RecordPingRTTHistogram(kFailedPing);
+    return;
+  }
+
+  // Check the status of connection after a delay.
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(),
+                 now),
+      delay);
+}
+
+void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) {
+  UMA_HISTOGRAM_TIMES("Net.SpdyPing.RTT", duration);
+}
+
+void SpdySession::RecordProtocolErrorHistogram(
+    SpdyProtocolErrorDetails details) {
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails", details,
+                            NUM_SPDY_PROTOCOL_ERROR_DETAILS);
+  if (EndsWith(host_port_pair().host(), "google.com", false)) {
+    UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails_Google", details,
+                              NUM_SPDY_PROTOCOL_ERROR_DETAILS);
+  }
+}
+
+void SpdySession::RecordHistograms() {
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession",
+                              streams_initiated_count_,
+                              0, 300, 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession",
+                              streams_pushed_count_,
+                              0, 300, 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession",
+                              streams_pushed_and_claimed_count_,
+                              0, 300, 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsAbandonedPerSession",
+                              streams_abandoned_count_,
+                              0, 300, 50);
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdySettingsSent",
+                            sent_settings_ ? 1 : 0, 2);
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdySettingsReceived",
+                            received_settings_ ? 1 : 0, 2);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamStallsPerSession",
+                              stalled_streams_,
+                              0, 300, 50);
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionsWithStalls",
+                            stalled_streams_ > 0 ? 1 : 0, 2);
+
+  if (received_settings_) {
+    // Enumerate the saved settings, and set histograms for it.
+    const SettingsMap& settings_map =
+        http_server_properties_->GetSpdySettings(host_port_pair());
+
+    SettingsMap::const_iterator it;
+    for (it = settings_map.begin(); it != settings_map.end(); ++it) {
+      const SpdySettingsIds id = it->first;
+      const uint32 val = it->second.second;
+      switch (id) {
+        case SETTINGS_CURRENT_CWND:
+          // Record several different histograms to see if cwnd converges
+          // for larger volumes of data being sent.
+          UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd",
+                                      val, 1, 200, 100);
+          if (bytes_received_ > 10 * 1024) {
+            UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K",
+                                        val, 1, 200, 100);
+            if (bytes_received_ > 25 * 1024) {
+              UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K",
+                                          val, 1, 200, 100);
+              if (bytes_received_ > 50 * 1024) {
+                UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K",
+                                            val, 1, 200, 100);
+                if (bytes_received_ > 100 * 1024) {
+                  UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K",
+                                              val, 1, 200, 100);
+                }
+              }
+            }
+          }
+          break;
+        case SETTINGS_ROUND_TRIP_TIME:
+          UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT",
+                                      val, 1, 1200, 100);
+          break;
+        case SETTINGS_DOWNLOAD_RETRANS_RATE:
+          UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate",
+                                      val, 1, 100, 50);
+          break;
+        default:
+          break;
+      }
+    }
+  }
+}
+
+void SpdySession::InvokeUserStreamCreationCallback(
+    scoped_refptr<SpdyStream>* stream) {
+  PendingCallbackMap::iterator it = pending_callback_map_.find(stream);
+
+  // Exit if the request has already been cancelled.
+  if (it == pending_callback_map_.end())
+    return;
+
+  CompletionCallback callback = it->second.callback;
+  int result = it->second.result;
+  pending_callback_map_.erase(it);
+  callback.Run(result);
+}
+
+SSLClientSocket* SpdySession::GetSSLClientSocket() const {
+  if (!is_secure_)
+    return NULL;
+  SSLClientSocket* ssl_socket =
+      reinterpret_cast<SSLClientSocket*>(connection_->socket());
+  DCHECK(ssl_socket);
+  return ssl_socket;
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_session.h b/src/net/spdy/spdy_session.h
new file mode 100644
index 0000000..abb5e92
--- /dev/null
+++ b/src/net/spdy/spdy_session.h
@@ -0,0 +1,746 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_SESSION_H_
+#define NET_SPDY_SPDY_SESSION_H_
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <queue>
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time.h"
+#include "net/base/io_buffer.h"
+#include "net/base/load_states.h"
+#include "net/base/net_errors.h"
+#include "net/base/request_priority.h"
+#include "net/base/ssl_client_cert_type.h"
+#include "net/base/ssl_config_service.h"
+#include "net/socket/client_socket_handle.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/socket/stream_socket.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_credential_state.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_io_buffer.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session_pool.h"
+
+namespace net {
+
+// This is somewhat arbitrary and not really fixed, but it will always work
+// reasonably with ethernet. Chop the world into 2-packet chunks.  This is
+// somewhat arbitrary, but is reasonably small and ensures that we elicit
+// ACKs quickly from TCP (because TCP tries to only ACK every other packet).
+const int kMss = 1430;
+const int kMaxSpdyFrameChunkSize = (2 * kMss) - SpdyFrame::kHeaderSize;
+
+// Specifies the maxiumum concurrent streams server could send (via push).
+const int kMaxConcurrentPushedStreams = 1000;
+
+class BoundNetLog;
+class SpdyStream;
+class SSLInfo;
+
+enum SpdyProtocolErrorDetails {
+  // SpdyFramer::SpdyErrors
+  SPDY_ERROR_NO_ERROR,
+  SPDY_ERROR_INVALID_CONTROL_FRAME,
+  SPDY_ERROR_CONTROL_PAYLOAD_TOO_LARGE,
+  SPDY_ERROR_ZLIB_INIT_FAILURE,
+  SPDY_ERROR_UNSUPPORTED_VERSION,
+  SPDY_ERROR_DECOMPRESS_FAILURE,
+  SPDY_ERROR_COMPRESS_FAILURE,
+  SPDY_ERROR_CREDENTIAL_FRAME_CORRUPT,
+  SPDY_ERROR_INVALID_DATA_FRAME_FLAGS,
+
+  // SpdyStatusCodes
+  STATUS_CODE_INVALID,
+  STATUS_CODE_PROTOCOL_ERROR,
+  STATUS_CODE_INVALID_STREAM,
+  STATUS_CODE_REFUSED_STREAM,
+  STATUS_CODE_UNSUPPORTED_VERSION,
+  STATUS_CODE_CANCEL,
+  STATUS_CODE_INTERNAL_ERROR,
+  STATUS_CODE_FLOW_CONTROL_ERROR,
+  STATUS_CODE_STREAM_IN_USE,
+  STATUS_CODE_STREAM_ALREADY_CLOSED,
+  STATUS_CODE_INVALID_CREDENTIALS,
+  STATUS_CODE_FRAME_TOO_LARGE,
+
+  // SpdySession errors
+  PROTOCOL_ERROR_UNEXPECTED_PING,
+  PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM,
+  PROTOCOL_ERROR_SPDY_COMPRESSION_FAILURE,
+  PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION,
+  PROTOCOL_ERROR_SYN_REPLY_NOT_RECEIVED,
+  NUM_SPDY_PROTOCOL_ERROR_DETAILS
+};
+
+COMPILE_ASSERT(STATUS_CODE_INVALID ==
+               static_cast<SpdyProtocolErrorDetails>(SpdyFramer::LAST_ERROR),
+               SpdyProtocolErrorDetails_SpdyErrors_mismatch);
+
+COMPILE_ASSERT(PROTOCOL_ERROR_UNEXPECTED_PING ==
+               static_cast<SpdyProtocolErrorDetails>(NUM_STATUS_CODES +
+                                                     STATUS_CODE_INVALID),
+               SpdyProtocolErrorDetails_SpdyErrors_mismatch);
+
+class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
+                               public BufferedSpdyFramerVisitorInterface {
+ public:
+  typedef base::TimeTicks (*TimeFunc)(void);
+
+  // Defines an interface for producing SpdyIOBuffers.
+  class NET_EXPORT_PRIVATE SpdyIOBufferProducer {
+   public:
+    SpdyIOBufferProducer() {}
+
+    // Returns a newly created SpdyIOBuffer, owned by the caller, or NULL
+    // if not buffer is ready to be produced.
+    virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) = 0;
+
+    virtual RequestPriority GetPriority() const = 0;
+
+    virtual ~SpdyIOBufferProducer() {}
+
+   protected:
+    // Activates |spdy_stream| in |spdy_session|.
+    static void ActivateStream(SpdySession* spdy_session,
+                               SpdyStream* spdy_stream);
+
+    static SpdyIOBuffer* CreateIOBuffer(SpdyFrame* frame,
+                                        RequestPriority priority,
+                                        SpdyStream* spdy_stream);
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(SpdyIOBufferProducer);
+  };
+
+  // Create a new SpdySession.
+  // |host_port_proxy_pair| is the host/port that this session connects to, and
+  // the proxy configuration settings that it's using.
+  // |spdy_session_pool| is the SpdySessionPool that owns us.  Its lifetime must
+  // strictly be greater than |this|.
+  // |session| is the HttpNetworkSession.  |net_log| is the NetLog that we log
+  // network events to.
+  SpdySession(const HostPortProxyPair& host_port_proxy_pair,
+              SpdySessionPool* spdy_session_pool,
+              HttpServerProperties* http_server_properties,
+              bool verify_domain_authentication,
+              bool enable_sending_initial_settings,
+              bool enable_credential_frames,
+              bool enable_compression,
+              bool enable_ping_based_connection_checking,
+              NextProto default_protocol_,
+              size_t initial_recv_window_size,
+              size_t initial_max_concurrent_streams,
+              size_t max_concurrent_streams_limit,
+              TimeFunc time_func,
+              const HostPortPair& trusted_spdy_proxy,
+              NetLog* net_log);
+
+  const HostPortPair& host_port_pair() const {
+    return host_port_proxy_pair_.first;
+  }
+  const HostPortProxyPair& host_port_proxy_pair() const {
+    return host_port_proxy_pair_;
+  }
+
+  // Get a pushed stream for a given |url|.
+  // If the server initiates a stream, it might already exist for a given path.
+  // The server might also not have initiated the stream yet, but indicated it
+  // will via X-Associated-Content.  Writes the stream out to |spdy_stream|.
+  // Returns a net error code.
+  int GetPushStream(
+      const GURL& url,
+      scoped_refptr<SpdyStream>* spdy_stream,
+      const BoundNetLog& stream_net_log);
+
+  // Create a new stream for a given |url|.  Writes it out to |spdy_stream|.
+  // Returns a net error code, possibly ERR_IO_PENDING.
+  int CreateStream(
+      const GURL& url,
+      RequestPriority priority,
+      scoped_refptr<SpdyStream>* spdy_stream,
+      const BoundNetLog& stream_net_log,
+      const CompletionCallback& callback);
+
+  // Remove PendingCreateStream objects on transaction deletion
+  void CancelPendingCreateStreams(const scoped_refptr<SpdyStream>* spdy_stream);
+
+  // Used by SpdySessionPool to initialize with a pre-existing SSL socket. For
+  // testing, setting is_secure to false allows initialization with a
+  // pre-existing TCP socket.
+  // Returns OK on success, or an error on failure.
+  net::Error InitializeWithSocket(ClientSocketHandle* connection,
+                                  bool is_secure,
+                                  int certificate_error_code);
+
+  // Check to see if this SPDY session can support an additional domain.
+  // If the session is un-authenticated, then this call always returns true.
+  // For SSL-based sessions, verifies that the server certificate in use by
+  // this session provides authentication for the domain and no client
+  // certificate or channel ID was sent to the original server during the SSL
+  // handshake.  NOTE:  This function can have false negatives on some
+  // platforms.
+  // TODO(wtc): rename this function and the Net.SpdyIPPoolDomainMatch
+  // histogram because this function does more than verifying domain
+  // authentication now.
+  bool VerifyDomainAuthentication(const std::string& domain);
+
+  // Records that |stream| has a write available from |producer|.
+  // |producer| will be owned by this SpdySession.
+  void SetStreamHasWriteAvailable(SpdyStream* stream,
+                                  SpdyIOBufferProducer* producer);
+
+  // Send the SYN frame for |stream_id|. This also sends PING message to check
+  // the status of the connection.
+  SpdySynStreamControlFrame* CreateSynStream(
+      SpdyStreamId stream_id,
+      RequestPriority priority,
+      uint8 credential_slot,
+      SpdyControlFlags flags,
+      const SpdyHeaderBlock& headers);
+
+  // Write a CREDENTIAL frame to the session.
+  SpdyCredentialControlFrame* CreateCredentialFrame(const std::string& origin,
+                                                    SSLClientCertType type,
+                                                    const std::string& key,
+                                                    const std::string& cert,
+                                                    RequestPriority priority);
+
+  // Write a HEADERS frame to the stream.
+  SpdyHeadersControlFrame* CreateHeadersFrame(SpdyStreamId stream_id,
+                                              const SpdyHeaderBlock& headers,
+                                              SpdyControlFlags flags);
+
+  // Write a data frame to the stream.
+  // Used to create and queue a data frame for the given stream.
+  SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id,
+                                 net::IOBuffer* data, int len,
+                                 SpdyDataFlags flags);
+
+  // Close a stream.
+  void CloseStream(SpdyStreamId stream_id, int status);
+
+  // Close a stream that has been created but is not yet active.
+  void CloseCreatedStream(SpdyStream* stream, int status);
+
+  // Reset a stream by sending a RST_STREAM frame with given status code.
+  // Also closes the stream.  Was not piggybacked to CloseStream since not
+  // all of the calls to CloseStream necessitate sending a RST_STREAM.
+  void ResetStream(SpdyStreamId stream_id,
+                   SpdyStatusCodes status,
+                   const std::string& description);
+
+  // Check if a stream is active.
+  bool IsStreamActive(SpdyStreamId stream_id) const;
+
+  // The LoadState is used for informing the user of the current network
+  // status, such as "resolving host", "connecting", etc.
+  LoadState GetLoadState() const;
+
+  // Fills SSL info in |ssl_info| and returns true when SSL is in use.
+  bool GetSSLInfo(SSLInfo* ssl_info,
+                  bool* was_npn_negotiated,
+                  NextProto* protocol_negotiated);
+
+  // Fills SSL Certificate Request info |cert_request_info| and returns
+  // true when SSL is in use.
+  bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+
+  // Returns the ServerBoundCertService used by this Socket, or NULL
+  // if server bound certs are not supported in this session.
+  ServerBoundCertService* GetServerBoundCertService() const;
+
+  // Send WINDOW_UPDATE frame, called by a stream whenever receive window
+  // size is increased.
+  void SendWindowUpdate(SpdyStreamId stream_id, int32 delta_window_size);
+
+  // If session is closed, no new streams/transactions should be created.
+  bool IsClosed() const { return state_ == CLOSED; }
+
+  // Closes this session.  This will close all active streams and mark
+  // the session as permanently closed.
+  // |err| should not be OK; this function is intended to be called on
+  // error.
+  // |remove_from_pool| indicates whether to also remove the session from the
+  // session pool.
+  // |description| indicates the reason for the error.
+  void CloseSessionOnError(net::Error err,
+                           bool remove_from_pool,
+                           const std::string& description);
+
+  // Retrieves information on the current state of the SPDY session as a
+  // Value.  Caller takes possession of the returned value.
+  base::Value* GetInfoAsValue() const;
+
+  // Indicates whether the session is being reused after having successfully
+  // used to send/receive data in the past.
+  bool IsReused() const;
+
+  // Returns true if the underlying transport socket ever had any reads or
+  // writes.
+  bool WasEverUsed() const {
+    return connection_->socket()->WasEverUsed();
+  }
+
+  void set_spdy_session_pool(SpdySessionPool* pool) {
+    spdy_session_pool_ = NULL;
+  }
+
+  // Returns true if session is not currently active
+  bool is_active() const {
+    return !active_streams_.empty() || !created_streams_.empty();
+  }
+
+  // Access to the number of active and pending streams.  These are primarily
+  // available for testing and diagnostics.
+  size_t num_active_streams() const { return active_streams_.size(); }
+  size_t num_unclaimed_pushed_streams() const {
+      return unclaimed_pushed_streams_.size();
+  }
+  size_t num_created_streams() const { return created_streams_.size(); }
+
+  size_t pending_create_stream_queues(int priority) {
+    DCHECK_LT(priority, NUM_PRIORITIES);
+    return pending_create_stream_queues_[priority].size();
+  }
+
+  // Returns true if flow control is enabled for the session.
+  bool is_flow_control_enabled() const {
+    return flow_control_;
+  }
+
+  // Returns the current |initial_send_window_size_|.
+  int32 initial_send_window_size() const {
+    return initial_send_window_size_;
+  }
+
+  // Returns the current |initial_recv_window_size_|.
+  int32 initial_recv_window_size() const { return initial_recv_window_size_; }
+
+  // Sets |initial_recv_window_size_| used by unittests.
+  void set_initial_recv_window_size(int32 window_size) {
+    initial_recv_window_size_ = window_size;
+  }
+
+  const BoundNetLog& net_log() const { return net_log_; }
+
+  int GetPeerAddress(IPEndPoint* address) const;
+  int GetLocalAddress(IPEndPoint* address) const;
+
+  // Returns true if requests on this session require credentials.
+  bool NeedsCredentials() const;
+
+  SpdyCredentialState* credential_state() { return &credential_state_; }
+
+  // Adds |alias| to set of aliases associated with this session.
+  void AddPooledAlias(const HostPortProxyPair& alias);
+
+  // Returns the set of aliases associated with this session.
+  const std::set<HostPortProxyPair>& pooled_aliases() const {
+    return pooled_aliases_;
+  }
+
+  int GetProtocolVersion() const;
+
+ private:
+  friend class base::RefCounted<SpdySession>;
+
+  // Allow tests to access our innards for testing purposes.
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy2Test, ClientPing);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy2Test, FailedPing);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy2Test, GetActivePushStream);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy2Test, DeleteExpiredPushStreams);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, ClientPing);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, FailedPing);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, GetActivePushStream);
+  FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, DeleteExpiredPushStreams);
+
+  struct PendingCreateStream {
+    PendingCreateStream(const GURL& url, RequestPriority priority,
+                        scoped_refptr<SpdyStream>* spdy_stream,
+                        const BoundNetLog& stream_net_log,
+                        const CompletionCallback& callback);
+
+    ~PendingCreateStream();
+
+    const GURL* url;
+    RequestPriority priority;
+    scoped_refptr<SpdyStream>* spdy_stream;
+    const BoundNetLog* stream_net_log;
+    CompletionCallback callback;
+  };
+  typedef std::queue<PendingCreateStream, std::list<PendingCreateStream> >
+      PendingCreateStreamQueue;
+  typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap;
+  typedef std::map<std::string,
+      std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> > PushedStreamMap;
+  typedef std::priority_queue<SpdyIOBuffer> OutputQueue;
+
+  typedef std::set<scoped_refptr<SpdyStream> > CreatedStreamSet;
+  typedef std::map<SpdyIOBufferProducer*, SpdyStream*> StreamProducerMap;
+  class SpdyIOBufferProducerCompare {
+   public:
+    bool operator() (const SpdyIOBufferProducer* lhs,
+                     const SpdyIOBufferProducer* rhs) const {
+      return lhs->GetPriority() < rhs->GetPriority();
+    }
+  };
+  typedef std::priority_queue<SpdyIOBufferProducer*,
+                              std::vector<SpdyIOBufferProducer*>,
+                              SpdyIOBufferProducerCompare> WriteQueue;
+
+  struct CallbackResultPair {
+    CallbackResultPair(const CompletionCallback& callback_in, int result_in);
+    ~CallbackResultPair();
+
+    CompletionCallback callback;
+    int result;
+  };
+
+  typedef std::map<const scoped_refptr<SpdyStream>*, CallbackResultPair>
+      PendingCallbackMap;
+
+  enum State {
+    IDLE,
+    CONNECTING,
+    CONNECTED,
+    CLOSED
+  };
+
+  virtual ~SpdySession();
+
+  void ProcessPendingCreateStreams();
+  int CreateStreamImpl(
+      const GURL& url,
+      RequestPriority priority,
+      scoped_refptr<SpdyStream>* spdy_stream,
+      const BoundNetLog& stream_net_log);
+
+  // IO Callbacks
+  void OnReadComplete(int result);
+  void OnWriteComplete(int result);
+
+  // Send relevant SETTINGS.  This is generally called on connection setup.
+  void SendInitialSettings();
+
+  // Helper method to send SETTINGS a frame.
+  void SendSettings(const SettingsMap& settings);
+
+  // Handle SETTING.  Either when we send settings, or when we receive a
+  // SETTINGS control frame, update our SpdySession accordingly.
+  void HandleSetting(uint32 id, uint32 value);
+
+  // Adjust the send window size of all ActiveStreams and PendingCreateStreams.
+  void UpdateStreamsSendWindowSize(int32 delta_window_size);
+
+  // Send the PING (preface-PING) frame.
+  void SendPrefacePingIfNoneInFlight();
+
+  // Send PING if there are no PINGs in flight and we haven't heard from server.
+  void SendPrefacePing();
+
+  // Send the PING frame.
+  void WritePingFrame(uint32 unique_id);
+
+  // Post a CheckPingStatus call after delay. Don't post if there is already
+  // CheckPingStatus running.
+  void PlanToCheckPingStatus();
+
+  // Check the status of the connection. It calls |CloseSessionOnError| if we
+  // haven't received any data in |kHungInterval| time period.
+  void CheckPingStatus(base::TimeTicks last_check_time);
+
+  // Start reading from the socket.
+  // Returns OK on success, or an error on failure.
+  net::Error ReadSocket();
+
+  // Write current data to the socket.
+  void WriteSocketLater();
+  void WriteSocket();
+
+  // Get a new stream id.
+  int GetNewStreamId();
+
+  // Queue a frame for sending.
+  // |frame| is the frame to send.
+  // |priority| is the priority for insertion into the queue.
+  void QueueFrame(SpdyFrame* frame, RequestPriority priority);
+
+  // Track active streams in the active stream list.
+  void ActivateStream(SpdyStream* stream);
+  void DeleteStream(SpdyStreamId id, int status);
+
+  // Removes this session from the session pool.
+  void RemoveFromPool();
+
+  // Check if we have a pending pushed-stream for this url
+  // Returns the stream if found (and returns it from the pending
+  // list), returns NULL otherwise.
+  scoped_refptr<SpdyStream> GetActivePushStream(const std::string& url);
+
+  // Calls OnResponseReceived().
+  // Returns true if successful.
+  bool Respond(const SpdyHeaderBlock& headers,
+               const scoped_refptr<SpdyStream> stream);
+
+  void RecordPingRTTHistogram(base::TimeDelta duration);
+  void RecordHistograms();
+  void RecordProtocolErrorHistogram(SpdyProtocolErrorDetails details);
+
+  // Closes all streams.  Used as part of shutdown.
+  void CloseAllStreams(net::Error status);
+
+  void LogAbandonedStream(const scoped_refptr<SpdyStream>& stream,
+                          net::Error status);
+
+  // Invokes a user callback for stream creation.  We provide this method so it
+  // can be deferred to the MessageLoop, so we avoid re-entrancy problems.
+  void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream);
+
+  // Remove old unclaimed pushed streams.
+  void DeleteExpiredPushedStreams();
+
+  // BufferedSpdyFramerVisitorInterface:
+  virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE;
+  virtual void OnStreamError(SpdyStreamId stream_id,
+                             const std::string& description) OVERRIDE;
+  virtual void OnPing(uint32 unique_id) OVERRIDE;
+  virtual void OnRstStream(SpdyStreamId stream_id,
+                           SpdyStatusCodes status) OVERRIDE;
+  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                        SpdyGoAwayStatus status) OVERRIDE;
+  virtual void OnStreamFrameData(SpdyStreamId stream_id,
+                                 const char* data,
+                                 size_t len,
+                                 SpdyDataFlags flags) OVERRIDE;
+  virtual void OnSetting(
+      SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE;
+  virtual void OnWindowUpdate(SpdyStreamId stream_id,
+                              int delta_window_size) OVERRIDE;
+  virtual void OnControlFrameCompressed(
+      const SpdyControlFrame& uncompressed_frame,
+      const SpdyControlFrame& compressed_frame) OVERRIDE;
+  virtual void OnSynStream(SpdyStreamId stream_id,
+                           SpdyStreamId associated_stream_id,
+                           SpdyPriority priority,
+                           uint8 credential_slot,
+                           bool fin,
+                           bool unidirectional,
+                           const SpdyHeaderBlock& headers) OVERRIDE;
+  virtual void OnSynReply(
+      SpdyStreamId stream_id,
+      bool fin,
+      const SpdyHeaderBlock& headers) OVERRIDE;
+  virtual void OnHeaders(
+      SpdyStreamId stream_id,
+      bool fin,
+      const SpdyHeaderBlock& headers) OVERRIDE;
+
+  // --------------------------
+  // Helper methods for testing
+  // --------------------------
+
+  void set_connection_at_risk_of_loss_time(base::TimeDelta duration) {
+    connection_at_risk_of_loss_time_ = duration;
+  }
+
+  void set_hung_interval(base::TimeDelta duration) {
+    hung_interval_ = duration;
+  }
+
+  int64 pings_in_flight() const { return pings_in_flight_; }
+
+  uint32 next_ping_id() const { return next_ping_id_; }
+
+  base::TimeTicks last_activity_time() const { return last_activity_time_; }
+
+  bool check_ping_status_pending() const { return check_ping_status_pending_; }
+
+  // Returns the SSLClientSocket that this SPDY session sits on top of,
+  // or NULL, if the transport is not SSL.
+  SSLClientSocket* GetSSLClientSocket() const;
+
+  // Used for posting asynchronous IO tasks.  We use this even though
+  // SpdySession is refcounted because we don't need to keep the SpdySession
+  // alive if the last reference is within a RunnableMethod.  Just revoke the
+  // method.
+  base::WeakPtrFactory<SpdySession> weak_factory_;
+
+  // Map of the SpdyStreams for which we have a pending Task to invoke a
+  // callback.  This is necessary since, before we invoke said callback, it's
+  // possible that the request is cancelled.
+  PendingCallbackMap pending_callback_map_;
+
+  // The domain this session is connected to.
+  const HostPortProxyPair host_port_proxy_pair_;
+
+  // Set set of HostPortProxyPairs for which this session has serviced
+  // requests.
+  std::set<HostPortProxyPair> pooled_aliases_;
+
+  // |spdy_session_pool_| owns us, therefore its lifetime must exceed ours.  We
+  // set this to NULL after we are removed from the pool.
+  SpdySessionPool* spdy_session_pool_;
+  HttpServerProperties* const http_server_properties_;
+
+  // The socket handle for this session.
+  scoped_ptr<ClientSocketHandle> connection_;
+
+  // The read buffer used to read data from the socket.
+  scoped_refptr<IOBuffer> read_buffer_;
+  bool read_pending_;
+
+  int stream_hi_water_mark_;  // The next stream id to use.
+
+  // Queue, for each priority, of pending Create Streams that have not
+  // yet been satisfied
+  PendingCreateStreamQueue pending_create_stream_queues_[NUM_PRIORITIES];
+
+  // Map from stream id to all active streams.  Streams are active in the sense
+  // that they have a consumer (typically SpdyNetworkTransaction and regardless
+  // of whether or not there is currently any ongoing IO [might be waiting for
+  // the server to start pushing the stream]) or there are still network events
+  // incoming even though the consumer has already gone away (cancellation).
+  // TODO(willchan): Perhaps we should separate out cancelled streams and move
+  // them into a separate ActiveStreamMap, and not deliver network events to
+  // them?
+  ActiveStreamMap active_streams_;
+  // Map of all the streams that have already started to be pushed by the
+  // server, but do not have consumers yet.
+  PushedStreamMap unclaimed_pushed_streams_;
+
+  // Set of all created streams but that have not yet sent any frames.
+  CreatedStreamSet created_streams_;
+
+  // As streams have data to be sent, we put them into the write queue.
+  WriteQueue write_queue_;
+
+  // Mapping from SpdyIOBufferProducers to their corresponding SpdyStream
+  // so that when a stream is destroyed, we can remove the corresponding
+  // producer from |write_queue_|.
+  StreamProducerMap stream_producers_;
+
+  // The packet we are currently sending.
+  bool write_pending_;            // Will be true when a write is in progress.
+  SpdyIOBuffer in_flight_write_;  // This is the write buffer in progress.
+
+  // Flag if we have a pending message scheduled for WriteSocket.
+  bool delayed_write_pending_;
+
+  // Flag if we're using an SSL connection for this SpdySession.
+  bool is_secure_;
+
+  // Certificate error code when using a secure connection.
+  int certificate_error_code_;
+
+  // Spdy Frame state.
+  scoped_ptr<BufferedSpdyFramer> buffered_spdy_framer_;
+
+  // If an error has occurred on the session, the session is effectively
+  // dead.  Record this error here.  When no error has occurred, |error_| will
+  // be OK.
+  net::Error error_;
+  State state_;
+
+  // Limits
+  size_t max_concurrent_streams_;  // 0 if no limit
+  size_t max_concurrent_streams_limit_;
+
+  // Some statistics counters for the session.
+  int streams_initiated_count_;
+  int streams_pushed_count_;
+  int streams_pushed_and_claimed_count_;
+  int streams_abandoned_count_;
+  int bytes_received_;
+  bool sent_settings_;      // Did this session send settings when it started.
+  bool received_settings_;  // Did this session receive at least one settings
+                            // frame.
+  int stalled_streams_;     // Count of streams that were ever stalled.
+
+  // Count of all pings on the wire, for which we have not gotten a response.
+  int64 pings_in_flight_;
+
+  // This is the next ping_id (unique_id) to be sent in PING frame.
+  uint32 next_ping_id_;
+
+  // This is the last time we have sent a PING.
+  base::TimeTicks last_ping_sent_time_;
+
+  // This is the last time we had activity in the session.
+  base::TimeTicks last_activity_time_;
+
+  // This is the next time that unclaimed push streams should be checked for
+  // expirations.
+  base::TimeTicks next_unclaimed_push_stream_sweep_time_;
+
+  // Indicate if we have already scheduled a delayed task to check the ping
+  // status.
+  bool check_ping_status_pending_;
+
+  // Indicate if flow control is enabled or not.
+  bool flow_control_;
+
+  // Initial send window size for the session; can be changed by an
+  // arriving SETTINGS frame; newly created streams use this value for the
+  // initial send window size.
+  int32 initial_send_window_size_;
+
+  // Initial receive window size for the session; there are plans to add a
+  // command line switch that would cause a SETTINGS frame with window size
+  // announcement to be sent on startup; newly created streams will use
+  // this value for the initial receive window size.
+  int32 initial_recv_window_size_;
+
+  BoundNetLog net_log_;
+
+  // Outside of tests, these should always be true.
+  bool verify_domain_authentication_;
+  bool enable_sending_initial_settings_;
+  bool enable_credential_frames_;
+  bool enable_compression_;
+  bool enable_ping_based_connection_checking_;
+  NextProto default_protocol_;
+
+  SpdyCredentialState credential_state_;
+
+  // |connection_at_risk_of_loss_time_| is an optimization to avoid sending
+  // wasteful preface pings (when we just got some data).
+  //
+  // If it is zero (the most conservative figure), then we always send the
+  // preface ping (when none are in flight).
+  //
+  // It is common for TCP/IP sessions to time out in about 3-5 minutes.
+  // Certainly if it has been more than 3 minutes, we do want to send a preface
+  // ping.
+  //
+  // We don't think any connection will time out in under about 10 seconds. So
+  // this might as well be set to something conservative like 10 seconds. Later,
+  // we could adjust it to send fewer pings perhaps.
+  base::TimeDelta connection_at_risk_of_loss_time_;
+
+  // The amount of time that we are willing to tolerate with no activity (of any
+  // form), while there is a ping in flight, before we declare the connection to
+  // be hung. TODO(rtenneti): When hung, instead of resetting connection, race
+  // to build a new connection, and see if that completes before we (finally)
+  // get a PING response (http://crbug.com/127812).
+  base::TimeDelta hung_interval_;
+
+  // This SPDY proxy is allowed to push resources from origins that are
+  // different from those of their associated streams.
+  HostPortPair trusted_spdy_proxy_;
+
+  TimeFunc time_func_;
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_SESSION_H_
diff --git a/src/net/spdy/spdy_session_pool.cc b/src/net/spdy/spdy_session_pool.cc
new file mode 100644
index 0000000..b967a46
--- /dev/null
+++ b/src/net/spdy/spdy_session_pool.cc
@@ -0,0 +1,497 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_session_pool.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/values.h"
+#include "net/base/address_list.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_server_properties.h"
+#include "net/spdy/spdy_session.h"
+
+
+namespace net {
+
+namespace {
+
+enum SpdySessionGetTypes {
+  CREATED_NEW                 = 0,
+  FOUND_EXISTING              = 1,
+  FOUND_EXISTING_FROM_IP_POOL = 2,
+  IMPORTED_FROM_SOCKET        = 3,
+  SPDY_SESSION_GET_MAX        = 4
+};
+
+bool HostPortProxyPairsAreEqual(const HostPortProxyPair& a,
+                                const HostPortProxyPair& b) {
+  return a.first.Equals(b.first) && a.second == b.second;
+}
+
+}
+
+// The maximum number of sessions to open to a single domain.
+static const size_t kMaxSessionsPerDomain = 1;
+
+SpdySessionPool::SpdySessionPool(
+    HostResolver* resolver,
+    SSLConfigService* ssl_config_service,
+    HttpServerProperties* http_server_properties,
+    size_t max_sessions_per_domain,
+    bool force_single_domain,
+    bool enable_ip_pooling,
+    bool enable_credential_frames,
+    bool enable_compression,
+    bool enable_ping_based_connection_checking,
+    NextProto default_protocol,
+    size_t initial_recv_window_size,
+    size_t initial_max_concurrent_streams,
+    size_t max_concurrent_streams_limit,
+    SpdySessionPool::TimeFunc time_func,
+    const std::string& trusted_spdy_proxy)
+    : http_server_properties_(http_server_properties),
+      ssl_config_service_(ssl_config_service),
+      resolver_(resolver),
+      verify_domain_authentication_(true),
+      enable_sending_initial_settings_(true),
+      max_sessions_per_domain_(max_sessions_per_domain == 0 ?
+                               kMaxSessionsPerDomain :
+                               max_sessions_per_domain),
+      force_single_domain_(force_single_domain),
+      enable_ip_pooling_(enable_ip_pooling),
+      enable_credential_frames_(enable_credential_frames),
+      enable_compression_(enable_compression),
+      enable_ping_based_connection_checking_(
+          enable_ping_based_connection_checking),
+      default_protocol_(default_protocol),
+      initial_recv_window_size_(initial_recv_window_size),
+      initial_max_concurrent_streams_(initial_max_concurrent_streams),
+      max_concurrent_streams_limit_(max_concurrent_streams_limit),
+      time_func_(time_func),
+      trusted_spdy_proxy_(
+          HostPortPair::FromString(trusted_spdy_proxy)) {
+  NetworkChangeNotifier::AddIPAddressObserver(this);
+  if (ssl_config_service_)
+    ssl_config_service_->AddObserver(this);
+  CertDatabase::GetInstance()->AddObserver(this);
+}
+
+SpdySessionPool::~SpdySessionPool() {
+  CloseAllSessions();
+
+  if (ssl_config_service_)
+    ssl_config_service_->RemoveObserver(this);
+  NetworkChangeNotifier::RemoveIPAddressObserver(this);
+  CertDatabase::GetInstance()->RemoveObserver(this);
+}
+
+scoped_refptr<SpdySession> SpdySessionPool::Get(
+    const HostPortProxyPair& host_port_proxy_pair,
+    const BoundNetLog& net_log) {
+  return GetInternal(host_port_proxy_pair, net_log, false);
+}
+
+scoped_refptr<SpdySession> SpdySessionPool::GetIfExists(
+    const HostPortProxyPair& host_port_proxy_pair,
+    const BoundNetLog& net_log) {
+  return GetInternal(host_port_proxy_pair, net_log, true);
+}
+
+scoped_refptr<SpdySession> SpdySessionPool::GetInternal(
+    const HostPortProxyPair& host_port_proxy_pair,
+    const BoundNetLog& net_log,
+    bool only_use_existing_sessions) {
+  scoped_refptr<SpdySession> spdy_session;
+  SpdySessionList* list = GetSessionList(host_port_proxy_pair);
+  if (!list) {
+    // Check if we have a Session through a domain alias.
+    spdy_session = GetFromAlias(host_port_proxy_pair, net_log, true);
+    if (spdy_session) {
+      UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
+                                FOUND_EXISTING_FROM_IP_POOL,
+                                SPDY_SESSION_GET_MAX);
+      net_log.AddEvent(
+          NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
+          spdy_session->net_log().source().ToEventParametersCallback());
+      // Add this session to the map so that we can find it next time.
+      list = AddSessionList(host_port_proxy_pair);
+      list->push_back(spdy_session);
+      spdy_session->AddPooledAlias(host_port_proxy_pair);
+      return spdy_session;
+    } else if (only_use_existing_sessions) {
+      return NULL;
+    }
+    list = AddSessionList(host_port_proxy_pair);
+  }
+
+  DCHECK(list);
+  if (list->size() && list->size() == max_sessions_per_domain_) {
+    UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
+                              FOUND_EXISTING,
+                              SPDY_SESSION_GET_MAX);
+    spdy_session = GetExistingSession(list, net_log);
+    net_log.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION,
+      spdy_session->net_log().source().ToEventParametersCallback());
+    return spdy_session;
+  }
+
+  DCHECK(!only_use_existing_sessions);
+
+  spdy_session = new SpdySession(host_port_proxy_pair, this,
+                                 http_server_properties_,
+                                 verify_domain_authentication_,
+                                 enable_sending_initial_settings_,
+                                 enable_credential_frames_,
+                                 enable_compression_,
+                                 enable_ping_based_connection_checking_,
+                                 default_protocol_,
+                                 initial_recv_window_size_,
+                                 initial_max_concurrent_streams_,
+                                 max_concurrent_streams_limit_,
+                                 time_func_,
+                                 trusted_spdy_proxy_,
+                                 net_log.net_log());
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
+                            CREATED_NEW,
+                            SPDY_SESSION_GET_MAX);
+  list->push_back(spdy_session);
+  net_log.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_POOL_CREATED_NEW_SESSION,
+      spdy_session->net_log().source().ToEventParametersCallback());
+  DCHECK_LE(list->size(), max_sessions_per_domain_);
+  return spdy_session;
+}
+
+net::Error SpdySessionPool::GetSpdySessionFromSocket(
+    const HostPortProxyPair& host_port_proxy_pair,
+    ClientSocketHandle* connection,
+    const BoundNetLog& net_log,
+    int certificate_error_code,
+    scoped_refptr<SpdySession>* spdy_session,
+    bool is_secure) {
+  UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
+                            IMPORTED_FROM_SOCKET,
+                            SPDY_SESSION_GET_MAX);
+  // Create the SPDY session and add it to the pool.
+  *spdy_session = new SpdySession(host_port_proxy_pair, this,
+                                  http_server_properties_,
+                                  verify_domain_authentication_,
+                                  enable_sending_initial_settings_,
+                                  enable_credential_frames_,
+                                  enable_compression_,
+                                  enable_ping_based_connection_checking_,
+                                  default_protocol_,
+                                  initial_recv_window_size_,
+                                  initial_max_concurrent_streams_,
+                                  max_concurrent_streams_limit_,
+                                  time_func_,
+                                  trusted_spdy_proxy_,
+                                  net_log.net_log());
+  SpdySessionList* list = GetSessionList(host_port_proxy_pair);
+  if (!list)
+    list = AddSessionList(host_port_proxy_pair);
+  DCHECK(list->empty());
+  list->push_back(*spdy_session);
+
+  net_log.AddEvent(
+      NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
+      (*spdy_session)->net_log().source().ToEventParametersCallback());
+
+  // We have a new session.  Lookup the IP address for this session so that we
+  // can match future Sessions (potentially to different domains) which can
+  // potentially be pooled with this one. Because GetPeerAddress() reports the
+  // proxy's address instead of the origin server, check to see if this is a
+  // direct connection.
+  if (enable_ip_pooling_  && host_port_proxy_pair.second.is_direct()) {
+    IPEndPoint address;
+    if (connection->socket()->GetPeerAddress(&address) == OK)
+      AddAlias(address, host_port_proxy_pair);
+  }
+
+  // Now we can initialize the session with the SSL socket.
+  return (*spdy_session)->InitializeWithSocket(connection, is_secure,
+                                               certificate_error_code);
+}
+
+bool SpdySessionPool::HasSession(
+    const HostPortProxyPair& host_port_proxy_pair) const {
+  if (GetSessionList(host_port_proxy_pair))
+    return true;
+
+  // Check if we have a session via an alias.
+  scoped_refptr<SpdySession> spdy_session =
+      GetFromAlias(host_port_proxy_pair, BoundNetLog(), false);
+  return spdy_session.get() != NULL;
+}
+
+void SpdySessionPool::Remove(const scoped_refptr<SpdySession>& session) {
+  bool ok = RemoveFromSessionList(session, session->host_port_proxy_pair());
+  DCHECK(ok);
+  session->net_log().AddEvent(
+      NetLog::TYPE_SPDY_SESSION_POOL_REMOVE_SESSION,
+      session->net_log().source().ToEventParametersCallback());
+
+  const std::set<HostPortProxyPair>& aliases = session->pooled_aliases();
+  for (std::set<HostPortProxyPair>::const_iterator it = aliases.begin();
+       it != aliases.end(); ++it) {
+    ok = RemoveFromSessionList(session, *it);
+    DCHECK(ok);
+  }
+}
+
+bool SpdySessionPool::RemoveFromSessionList(
+    const scoped_refptr<SpdySession>& session,
+    const HostPortProxyPair& pair) {
+  SpdySessionList* list = GetSessionList(pair);
+  if (!list)
+    return false;
+  list->remove(session);
+  if (list->empty())
+    RemoveSessionList(pair);
+  return true;
+}
+
+Value* SpdySessionPool::SpdySessionPoolInfoToValue() const {
+  ListValue* list = new ListValue();
+
+  for (SpdySessionsMap::const_iterator it = sessions_.begin();
+       it != sessions_.end(); ++it) {
+    SpdySessionList* sessions = it->second;
+    for (SpdySessionList::const_iterator session = sessions->begin();
+         session != sessions->end(); ++session) {
+      // Only add the session if the key in the map matches the main
+      // host_port_proxy_pair (not an alias).
+      const HostPortProxyPair& key = it->first;
+      const HostPortProxyPair& pair = session->get()->host_port_proxy_pair();
+      if (key.first.Equals(pair.first) && key.second == pair.second)
+        list->Append(session->get()->GetInfoAsValue());
+    }
+  }
+  return list;
+}
+
+void SpdySessionPool::OnIPAddressChanged() {
+  CloseCurrentSessions(ERR_NETWORK_CHANGED);
+  http_server_properties_->ClearSpdySettings();
+}
+
+void SpdySessionPool::OnSSLConfigChanged() {
+  CloseCurrentSessions(ERR_NETWORK_CHANGED);
+}
+
+scoped_refptr<SpdySession> SpdySessionPool::GetExistingSession(
+    SpdySessionList* list,
+    const BoundNetLog& net_log) const {
+  DCHECK(list);
+  DCHECK_LT(0u, list->size());
+  scoped_refptr<SpdySession> spdy_session = list->front();
+  if (list->size() > 1) {
+    list->pop_front();  // Rotate the list.
+    list->push_back(spdy_session);
+  }
+
+  return spdy_session;
+}
+
+scoped_refptr<SpdySession> SpdySessionPool::GetFromAlias(
+      const HostPortProxyPair& host_port_proxy_pair,
+      const BoundNetLog& net_log,
+      bool record_histograms) const {
+  // We should only be checking aliases when there is no direct session.
+  DCHECK(!GetSessionList(host_port_proxy_pair));
+
+  if (!enable_ip_pooling_)
+    return NULL;
+
+  AddressList addresses;
+  if (!LookupAddresses(host_port_proxy_pair, net_log, &addresses))
+    return NULL;
+  for (AddressList::const_iterator iter = addresses.begin();
+       iter != addresses.end();
+       ++iter) {
+    SpdyAliasMap::const_iterator alias_iter = aliases_.find(*iter);
+    if (alias_iter == aliases_.end())
+      continue;
+
+    // We found an alias.
+    const HostPortProxyPair& alias_pair = alias_iter->second;
+
+    // If the proxy settings match, we can reuse this session.
+    if (!(alias_pair.second == host_port_proxy_pair.second))
+      continue;
+
+    SpdySessionList* list = GetSessionList(alias_pair);
+    if (!list) {
+      NOTREACHED();  // It shouldn't be in the aliases table if we can't get it!
+      continue;
+    }
+
+    scoped_refptr<SpdySession> spdy_session = GetExistingSession(list, net_log);
+    // If the SPDY session is a secure one, we need to verify that the server
+    // is authenticated to serve traffic for |host_port_proxy_pair| too.
+    if (!spdy_session->VerifyDomainAuthentication(
+            host_port_proxy_pair.first.host())) {
+      if (record_histograms)
+        UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2);
+      continue;
+    }
+    if (record_histograms)
+      UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2);
+    return spdy_session;
+  }
+  return NULL;
+}
+
+void SpdySessionPool::OnCertAdded(const X509Certificate* cert) {
+  CloseCurrentSessions(ERR_NETWORK_CHANGED);
+}
+
+void SpdySessionPool::OnCertTrustChanged(const X509Certificate* cert) {
+  // Per wtc, we actually only need to CloseCurrentSessions when trust is
+  // reduced. CloseCurrentSessions now because OnCertTrustChanged does not
+  // tell us this.
+  // See comments in ClientSocketPoolManager::OnCertTrustChanged.
+  CloseCurrentSessions(ERR_NETWORK_CHANGED);
+}
+
+const HostPortProxyPair& SpdySessionPool::NormalizeListPair(
+    const HostPortProxyPair& host_port_proxy_pair) const {
+  if (!force_single_domain_)
+    return host_port_proxy_pair;
+
+  static HostPortProxyPair* single_domain_pair = NULL;
+  if (!single_domain_pair) {
+    HostPortPair single_domain = HostPortPair("singledomain.com", 80);
+    single_domain_pair = new HostPortProxyPair(single_domain,
+                                               ProxyServer::Direct());
+  }
+  return *single_domain_pair;
+}
+
+SpdySessionPool::SpdySessionList*
+    SpdySessionPool::AddSessionList(
+        const HostPortProxyPair& host_port_proxy_pair) {
+  const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair);
+  DCHECK(sessions_.find(pair) == sessions_.end());
+  SpdySessionPool::SpdySessionList* list = new SpdySessionList();
+  sessions_[pair] = list;
+  return list;
+}
+
+SpdySessionPool::SpdySessionList*
+    SpdySessionPool::GetSessionList(
+        const HostPortProxyPair& host_port_proxy_pair) const {
+  const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair);
+  SpdySessionsMap::const_iterator it = sessions_.find(pair);
+  if (it != sessions_.end())
+    return it->second;
+  return NULL;
+}
+
+void SpdySessionPool::RemoveSessionList(
+    const HostPortProxyPair& host_port_proxy_pair) {
+  const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair);
+  SpdySessionList* list = GetSessionList(pair);
+  if (list) {
+    delete list;
+    sessions_.erase(pair);
+  } else {
+    DCHECK(false) << "removing orphaned session list";
+  }
+  RemoveAliases(host_port_proxy_pair);
+}
+
+bool SpdySessionPool::LookupAddresses(const HostPortProxyPair& pair,
+                                      const BoundNetLog& net_log,
+                                      AddressList* addresses) const {
+  net::HostResolver::RequestInfo resolve_info(pair.first);
+  int rv = resolver_->ResolveFromCache(resolve_info, addresses, net_log);
+  DCHECK_NE(ERR_IO_PENDING, rv);
+  return rv == OK;
+}
+
+void SpdySessionPool::AddAlias(const IPEndPoint& endpoint,
+                               const HostPortProxyPair& pair) {
+  DCHECK(enable_ip_pooling_);
+  aliases_[endpoint] = pair;
+}
+
+void SpdySessionPool::RemoveAliases(const HostPortProxyPair& pair) {
+  // Walk the aliases map, find references to this pair.
+  // TODO(mbelshe):  Figure out if this is too expensive.
+  SpdyAliasMap::iterator alias_it = aliases_.begin();
+  while (alias_it != aliases_.end()) {
+    if (HostPortProxyPairsAreEqual(alias_it->second, pair)) {
+      aliases_.erase(alias_it);
+      alias_it = aliases_.begin();  // Iterator was invalidated.
+      continue;
+    }
+    ++alias_it;
+  }
+}
+
+void SpdySessionPool::CloseAllSessions() {
+  while (!sessions_.empty()) {
+    SpdySessionList* list = sessions_.begin()->second;
+    CHECK(list);
+    const scoped_refptr<SpdySession>& session = list->front();
+    CHECK(session);
+    // This call takes care of removing the session from the pool, as well as
+    // removing the session list if the list is empty.
+    session->CloseSessionOnError(
+        net::ERR_ABORTED, true, "Closing all sessions.");
+  }
+}
+
+void SpdySessionPool::CloseCurrentSessions(net::Error error) {
+  SpdySessionsMap old_map;
+  old_map.swap(sessions_);
+  for (SpdySessionsMap::const_iterator it = old_map.begin();
+       it != old_map.end(); ++it) {
+    SpdySessionList* list = it->second;
+    CHECK(list);
+    const scoped_refptr<SpdySession>& session = list->front();
+    CHECK(session);
+    session->set_spdy_session_pool(NULL);
+  }
+
+  while (!old_map.empty()) {
+    SpdySessionList* list = old_map.begin()->second;
+    CHECK(list);
+    const scoped_refptr<SpdySession>& session = list->front();
+    CHECK(session);
+    session->CloseSessionOnError(error, false, "Closing current sessions.");
+    list->pop_front();
+    if (list->empty()) {
+      delete list;
+      RemoveAliases(old_map.begin()->first);
+      old_map.erase(old_map.begin()->first);
+    }
+  }
+  DCHECK(sessions_.empty());
+  DCHECK(aliases_.empty());
+}
+
+void SpdySessionPool::CloseIdleSessions() {
+  SpdySessionsMap::const_iterator map_it = sessions_.begin();
+  while (map_it != sessions_.end()) {
+    SpdySessionList* list = map_it->second;
+    ++map_it;
+    CHECK(list);
+
+    // Assumes there is only 1 element in the list
+    SpdySessionList::iterator session_it = list->begin();
+    const scoped_refptr<SpdySession>& session = *session_it;
+    CHECK(session);
+    if (!session->is_active()) {
+      session->CloseSessionOnError(
+          net::ERR_ABORTED, true, "Closing idle sessions.");
+    }
+  }
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_session_pool.h b/src/net/spdy/spdy_session_pool.h
new file mode 100644
index 0000000..0467583
--- /dev/null
+++ b/src/net/spdy/spdy_session_pool.h
@@ -0,0 +1,230 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_SESSION_POOL_H_
+#define NET_SPDY_SPDY_SESSION_POOL_H_
+
+#include <map>
+#include <list>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/cert_database.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_export.h"
+#include "net/base/network_change_notifier.h"
+#include "net/base/ssl_config_service.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_server.h"
+#include "net/socket/next_proto.h"
+
+namespace net {
+
+class AddressList;
+class BoundNetLog;
+class ClientSocketHandle;
+class HostResolver;
+class HttpServerProperties;
+class SpdySession;
+
+namespace test_spdy2 {
+class SpdySessionPoolPeer;
+}  // namespace test_spdy
+
+namespace test_spdy3 {
+class SpdySessionPoolPeer;
+}  // namespace test_spdy
+
+// This is a very simple pool for open SpdySessions.
+class NET_EXPORT SpdySessionPool
+    : public NetworkChangeNotifier::IPAddressObserver,
+      public SSLConfigService::Observer,
+      public CertDatabase::Observer {
+ public:
+  typedef base::TimeTicks (*TimeFunc)(void);
+
+  SpdySessionPool(HostResolver* host_resolver,
+                  SSLConfigService* ssl_config_service,
+                  HttpServerProperties* http_server_properties,
+                  size_t max_sessions_per_domain,
+                  bool force_single_domain,
+                  bool enable_ip_pooling,
+                  bool enable_credential_frames,
+                  bool enable_compression,
+                  bool enable_ping_based_connection_checking,
+                  NextProto default_protocol,
+                  size_t default_initial_recv_window_size,
+                  size_t initial_max_concurrent_streams,
+                  size_t max_concurrent_streams_limit,
+                  SpdySessionPool::TimeFunc time_func,
+                  const std::string& trusted_spdy_proxy);
+  virtual ~SpdySessionPool();
+
+  // Either returns an existing SpdySession or creates a new SpdySession for
+  // use.
+  scoped_refptr<SpdySession> Get(
+      const HostPortProxyPair& host_port_proxy_pair,
+      const BoundNetLog& net_log);
+
+  // Only returns a SpdySession if it already exists.
+  scoped_refptr<SpdySession> GetIfExists(
+      const HostPortProxyPair& host_port_proxy_pair,
+      const BoundNetLog& net_log);
+
+  // Builds a SpdySession from an existing SSL socket.  Users should try
+  // calling Get() first to use an existing SpdySession so we don't get
+  // multiple SpdySessions per domain.  Note that ownership of |connection| is
+  // transferred from the caller to the SpdySession.
+  // |certificate_error_code| is used to indicate the certificate error
+  // encountered when connecting the SSL socket.  OK means there was no error.
+  // For testing, setting is_secure to false allows Spdy to connect with a
+  // pre-existing TCP socket.
+  // Returns OK on success, and the |spdy_session| will be provided.
+  // Returns an error on failure, and |spdy_session| will be NULL.
+  net::Error GetSpdySessionFromSocket(
+      const HostPortProxyPair& host_port_proxy_pair,
+      ClientSocketHandle* connection,
+      const BoundNetLog& net_log,
+      int certificate_error_code,
+      scoped_refptr<SpdySession>* spdy_session,
+      bool is_secure);
+
+  // TODO(willchan): Consider renaming to HasReusableSession, since perhaps we
+  // should be creating a new session. WARNING: Because of IP connection pooling
+  // using the HostCache, if HasSession() returns true at one point, it does not
+  // imply the SpdySessionPool will still have a matching session in the near
+  // future, since the HostCache's entry may have expired.
+  bool HasSession(const HostPortProxyPair& host_port_proxy_pair) const;
+
+  // Close all SpdySessions, including any new ones created in the process of
+  // closing the current ones.
+  void CloseAllSessions();
+  // Close only the currently existing SpdySessions with |error|.
+  // Let any new ones created continue to live.
+  void CloseCurrentSessions(net::Error error);
+  // Close only the idle SpdySessions.
+  void CloseIdleSessions();
+
+  // Removes a SpdySession from the SpdySessionPool. This should only be called
+  // by SpdySession, because otherwise session->state_ is not set to CLOSED.
+  void Remove(const scoped_refptr<SpdySession>& session);
+
+  // Creates a Value summary of the state of the spdy session pool. The caller
+  // responsible for deleting the returned value.
+  base::Value* SpdySessionPoolInfoToValue() const;
+
+  HttpServerProperties* http_server_properties() {
+    return http_server_properties_;
+  }
+
+  // NetworkChangeNotifier::IPAddressObserver methods:
+
+  // We flush all idle sessions and release references to the active ones so
+  // they won't get re-used.  The active ones will either complete successfully
+  // or error out due to the IP address change.
+  virtual void OnIPAddressChanged() OVERRIDE;
+
+  // SSLConfigService::Observer methods:
+
+  // We perform the same flushing as described above when SSL settings change.
+  virtual void OnSSLConfigChanged() OVERRIDE;
+
+  // CertDatabase::Observer methods:
+  virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE;
+  virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE;
+
+ private:
+  friend class test_spdy2::SpdySessionPoolPeer;  // For testing.
+  friend class test_spdy3::SpdySessionPoolPeer;  // For testing.
+  friend class SpdyNetworkTransactionSpdy2Test;  // For testing.
+  friend class SpdyNetworkTransactionSpdy3Test;  // For testing.
+  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy2Test,
+                           WindowUpdateOverflow);
+  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy3Test,
+                           WindowUpdateOverflow);
+
+  typedef std::list<scoped_refptr<SpdySession> > SpdySessionList;
+  typedef std::map<HostPortProxyPair, SpdySessionList*> SpdySessionsMap;
+  typedef std::map<IPEndPoint, HostPortProxyPair> SpdyAliasMap;
+
+
+  scoped_refptr<SpdySession> GetInternal(
+      const HostPortProxyPair& host_port_proxy_pair,
+      const BoundNetLog& net_log,
+      bool only_use_existing_sessions);
+  scoped_refptr<SpdySession> GetExistingSession(
+      SpdySessionList* list,
+      const BoundNetLog& net_log) const;
+  scoped_refptr<SpdySession> GetFromAlias(
+      const HostPortProxyPair& host_port_proxy_pair,
+      const BoundNetLog& net_log,
+      bool record_histograms) const;
+
+  // Helper functions for manipulating the lists.
+  const HostPortProxyPair& NormalizeListPair(
+      const HostPortProxyPair& host_port_proxy_pair) const;
+  SpdySessionList* AddSessionList(
+      const HostPortProxyPair& host_port_proxy_pair);
+  SpdySessionList* GetSessionList(
+      const HostPortProxyPair& host_port_proxy_pair) const;
+  void RemoveSessionList(const HostPortProxyPair& host_port_proxy_pair);
+
+  // Does a DNS cache lookup for |pair|, and returns the |addresses| found.
+  // Returns true if addresses found, false otherwise.
+  bool LookupAddresses(const HostPortProxyPair& pair,
+                       const BoundNetLog& net_log,
+                       AddressList* addresses) const;
+
+  // Add |address| as an IP-equivalent address for |pair|.
+  void AddAlias(const IPEndPoint& address, const HostPortProxyPair& pair);
+
+  // Remove all aliases for |pair| from the aliases table.
+  void RemoveAliases(const HostPortProxyPair& pair);
+
+  // Removes |session| from the session list associated with |pair|.
+  // Returns true if the session was removed, false otherwise.
+  bool RemoveFromSessionList(const scoped_refptr<SpdySession>& session,
+                             const HostPortProxyPair& pair);
+
+  HttpServerProperties* const http_server_properties_;
+
+  // This is our weak session pool - one session per domain.
+  SpdySessionsMap sessions_;
+  // A map of IPEndPoint aliases for sessions.
+  SpdyAliasMap aliases_;
+
+  static bool g_force_single_domain;
+
+  const scoped_refptr<SSLConfigService> ssl_config_service_;
+  HostResolver* const resolver_;
+
+  // Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
+  bool verify_domain_authentication_;
+  bool enable_sending_initial_settings_;
+  size_t max_sessions_per_domain_;
+  bool force_single_domain_;
+  bool enable_ip_pooling_;
+  bool enable_credential_frames_;
+  bool enable_compression_;
+  bool enable_ping_based_connection_checking_;
+  NextProto default_protocol_;
+  size_t initial_recv_window_size_;
+  size_t initial_max_concurrent_streams_;
+  size_t max_concurrent_streams_limit_;
+  TimeFunc time_func_;
+
+  // This SPDY proxy is allowed to push resources from origins that are
+  // different from those of their associated streams.
+  HostPortPair trusted_spdy_proxy_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdySessionPool);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_SESSION_POOL_H_
diff --git a/src/net/spdy/spdy_session_spdy2_unittest.cc b/src/net/spdy/spdy_session_spdy2_unittest.cc
new file mode 100644
index 0000000..655676d
--- /dev/null
+++ b/src/net/spdy/spdy_session_spdy2_unittest.cc
@@ -0,0 +1,1871 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_session.h"
+
+#include "net/base/host_cache.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_log_unittest.h"
+#include "net/spdy/spdy_io_buffer.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_stream.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy2;
+
+namespace net {
+
+namespace {
+
+static int g_delta_seconds = 0;
+base::TimeTicks TheNearFuture() {
+  return base::TimeTicks::Now() + base::TimeDelta::FromSeconds(g_delta_seconds);
+}
+
+class ClosingDelegate : public SpdyStream::Delegate {
+ public:
+  ClosingDelegate(SpdyStream* stream) : stream_(stream) {}
+
+  // SpdyStream::Delegate implementation:
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE {
+    return true;
+  }
+  virtual int OnSendBody() OVERRIDE {
+    return OK;
+  }
+  virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE {
+    return OK;
+  }
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE {
+    return OK;
+  }
+  virtual void OnHeadersSent() OVERRIDE {}
+  virtual int OnDataReceived(const char* data, int length) OVERRIDE {
+    return OK;
+  }
+  virtual void OnDataSent(int length) OVERRIDE {}
+  virtual void OnClose(int status) OVERRIDE {
+    stream_->Close();
+  }
+ private:
+  SpdyStream* stream_;
+};
+
+} // namespace
+
+class SpdySessionSpdy2Test : public PlatformTest {
+ protected:
+  void SetUp() {
+    g_delta_seconds = 0;
+  }
+};
+
+class TestSpdyStreamDelegate : public net::SpdyStream::Delegate {
+ public:
+  explicit TestSpdyStreamDelegate(const CompletionCallback& callback)
+      : callback_(callback) {}
+  virtual ~TestSpdyStreamDelegate() {}
+
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE { return true; }
+
+  virtual int OnSendBody() OVERRIDE {
+    return ERR_UNEXPECTED;
+  }
+
+  virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) OVERRIDE {
+    return ERR_UNEXPECTED;
+  }
+
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE {
+    return status;
+  }
+
+  virtual void OnHeadersSent() OVERRIDE {}
+
+  virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE {
+    return OK;
+  }
+
+  virtual void OnDataSent(int length) OVERRIDE {}
+
+  virtual void OnClose(int status) OVERRIDE {
+    CompletionCallback callback = callback_;
+    callback_.Reset();
+    callback.Run(OK);
+  }
+
+ private:
+  CompletionCallback callback_;
+};
+
+// Test the SpdyIOBuffer class.
+TEST_F(SpdySessionSpdy2Test, SpdyIOBuffer) {
+  std::priority_queue<SpdyIOBuffer> queue_;
+  const size_t kQueueSize = 100;
+
+  // Insert items with random priority and increasing buffer size.
+  for (size_t index = 0; index < kQueueSize; ++index) {
+    queue_.push(SpdyIOBuffer(
+        new IOBufferWithSize(index + 1),
+        index + 1,
+        static_cast<RequestPriority>(rand() % NUM_PRIORITIES),
+        NULL));
+  }
+
+  EXPECT_EQ(kQueueSize, queue_.size());
+
+  // Verify items come out with decreasing priority or FIFO order.
+  RequestPriority last_priority = NUM_PRIORITIES;
+  size_t last_size = 0;
+  for (size_t index = 0; index < kQueueSize; ++index) {
+    SpdyIOBuffer buffer = queue_.top();
+    EXPECT_LE(buffer.priority(), last_priority);
+    if (buffer.priority() < last_priority)
+      last_size = 0;
+    EXPECT_LT(last_size, buffer.size());
+    last_priority = buffer.priority();
+    last_size = buffer.size();
+    queue_.pop();
+  }
+
+  EXPECT_EQ(0u, queue_.size());
+}
+
+TEST_F(SpdySessionSpdy2Test, GoAway) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
+  MockRead reads[] = {
+    CreateMockRead(*goaway),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.SetNextProto(kProtoSPDY2);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  EXPECT_EQ(2, session->GetProtocolVersion());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<SpdySession> session2 =
+      spdy_session_pool->Get(pair, BoundNetLog());
+
+  // Delete the first session.
+  session = NULL;
+
+  // Delete the second session.
+  spdy_session_pool->Remove(session2);
+  session2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, ClientPing) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(1));
+  MockRead reads[] = {
+    CreateMockRead(*read_ping),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(1));
+  MockWrite writes[] = {
+    CreateMockWrite(*write_ping),
+  };
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  EXPECT_EQ(OK, session->CreateStream(url,
+                                      MEDIUM,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(callback1.callback()));
+  spdy_stream1->SetDelegate(delegate.get());
+
+  base::TimeTicks before_ping_time = base::TimeTicks::Now();
+
+  session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
+  session->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
+
+  session->SendPrefacePingIfNoneInFlight();
+
+  EXPECT_EQ(OK, callback1.WaitForResult());
+
+  session->CheckPingStatus(before_ping_time);
+
+  EXPECT_EQ(0, session->pings_in_flight());
+  EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
+  EXPECT_FALSE(session->check_ping_status_pending());
+  EXPECT_GE(session->last_activity_time(), before_ping_time);
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Delete the first session.
+  session = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, ServerPing) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(2));
+  MockRead reads[] = {
+    CreateMockRead(*read_ping),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(2));
+  MockWrite writes[] = {
+    CreateMockWrite(*write_ping),
+  };
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  EXPECT_EQ(OK, session->CreateStream(url,
+                                      MEDIUM,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(callback1.callback()));
+  spdy_stream1->SetDelegate(delegate.get());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Delete the session.
+  session = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, DeleteExpiredPushStreams) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+  session_deps.time_func = TheNearFuture;
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  // Give the session a SPDY2 framer.
+  session->buffered_spdy_framer_.reset(new BufferedSpdyFramer(2, false));
+
+  // Create the associated stream and add to active streams.
+  scoped_ptr<SpdyHeaderBlock> request_headers(new SpdyHeaderBlock);
+  (*request_headers)["scheme"] = "http";
+  (*request_headers)["host"] = "www.google.com";
+  (*request_headers)["url"] = "/";
+
+  scoped_refptr<SpdyStream> stream(
+      new SpdyStream(session, false, session->net_log_));
+  stream->set_spdy_headers(request_headers.Pass());
+  session->ActivateStream(stream);
+
+  SpdyHeaderBlock headers;
+  headers["url"] = "http://www.google.com/a.dat";
+  session->OnSynStream(2, 1, 0, 0, true, false, headers);
+
+  // Verify that there is one unclaimed push stream.
+  EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
+  SpdySession::PushedStreamMap::iterator  iter  =
+      session->unclaimed_pushed_streams_.find("http://www.google.com/a.dat");
+  EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
+
+  // Shift time.
+  g_delta_seconds = 301;
+
+  headers["url"] = "http://www.google.com/b.dat";
+  session->OnSynStream(4, 1, 0, 0, true, false, headers);
+
+  // Verify that the second pushed stream evicted the first pushed stream.
+  EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
+  iter = session->unclaimed_pushed_streams_.find("http://www.google.com/b.dat");
+  EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
+
+  // Delete the session.
+  session = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, FailedPing) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(1));
+  MockRead reads[] = {
+    CreateMockRead(*read_ping),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(1));
+  MockWrite writes[] = {
+    CreateMockWrite(*write_ping),
+  };
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.gmail.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.gmail.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  EXPECT_EQ(OK, session->CreateStream(url,
+                                      MEDIUM,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(callback1.callback()));
+  spdy_stream1->SetDelegate(delegate.get());
+
+  session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
+  session->set_hung_interval(base::TimeDelta::FromSeconds(0));
+
+  // Send a PING frame.
+  session->WritePingFrame(1);
+  EXPECT_LT(0, session->pings_in_flight());
+  EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
+  EXPECT_TRUE(session->check_ping_status_pending());
+
+  // Assert session is not closed.
+  EXPECT_FALSE(session->IsClosed());
+  EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  // We set last time we have received any data in 1 sec less than now.
+  // CheckPingStatus will trigger timeout because hung interval is zero.
+  base::TimeTicks now = base::TimeTicks::Now();
+  session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
+  session->CheckPingStatus(now);
+
+  EXPECT_TRUE(session->IsClosed());
+  EXPECT_EQ(0u, session->num_active_streams());
+  EXPECT_EQ(0u, session->num_unclaimed_pushed_streams());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Delete the first session.
+  session = NULL;
+}
+
+class StreamReleaserCallback : public TestCompletionCallbackBase {
+ public:
+  StreamReleaserCallback(SpdySession* session,
+                         SpdyStream* first_stream)
+      : session_(session),
+        first_stream_(first_stream),
+        ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+            base::Bind(&StreamReleaserCallback::OnComplete,
+                       base::Unretained(this)))) {
+  }
+
+  virtual ~StreamReleaserCallback() {}
+
+  scoped_refptr<SpdyStream>* stream() { return &stream_; }
+
+  const CompletionCallback& callback() const { return callback_; }
+
+ private:
+  void OnComplete(int result) {
+    session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
+    session_ = NULL;
+    first_stream_->Cancel();
+    first_stream_ = NULL;
+    stream_->Cancel();
+    stream_ = NULL;
+    SetResult(result);
+  }
+
+  scoped_refptr<SpdySession> session_;
+  scoped_refptr<SpdyStream> first_stream_;
+  scoped_refptr<SpdyStream> stream_;
+  CompletionCallback callback_;
+};
+
+// TODO(kristianm): Could also test with more sessions where some are idle,
+// and more than one session to a HostPortPair.
+TEST_F(SpdySessionSpdy2Test, CloseIdleSessions) {
+  SpdySessionDependencies session_deps;
+  scoped_refptr<HttpNetworkSession> http_session(
+  SpdySessionDependencies::SpdyCreateSession(&session_deps));
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Set up session 1
+  const std::string kTestHost1("http://www.a.com");
+  HostPortPair test_host_port_pair1(kTestHost1, 80);
+  HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
+  scoped_refptr<SpdySession> session1 =
+      spdy_session_pool->Get(pair1, BoundNetLog());
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1(kTestHost1);
+  EXPECT_EQ(OK, session1->CreateStream(url1,
+                                      MEDIUM, /* priority, not important */
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+
+  // Set up session 2
+  const std::string kTestHost2("http://www.b.com");
+  HostPortPair test_host_port_pair2(kTestHost2, 80);
+  HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
+  scoped_refptr<SpdySession> session2 =
+      spdy_session_pool->Get(pair2, BoundNetLog());
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2(kTestHost2);
+  EXPECT_EQ(OK, session2->CreateStream(
+      url2, MEDIUM, /* priority, not important */
+      &spdy_stream2, BoundNetLog(), callback2.callback()));
+
+  // Set up session 3
+  const std::string kTestHost3("http://www.c.com");
+  HostPortPair test_host_port_pair3(kTestHost3, 80);
+  HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
+  scoped_refptr<SpdySession> session3 =
+      spdy_session_pool->Get(pair3, BoundNetLog());
+  scoped_refptr<SpdyStream> spdy_stream3;
+  TestCompletionCallback callback3;
+  GURL url3(kTestHost3);
+  EXPECT_EQ(OK, session3->CreateStream(
+      url3, MEDIUM, /* priority, not important */
+      &spdy_stream3, BoundNetLog(), callback3.callback()));
+
+  // All sessions are active and not closed
+  EXPECT_TRUE(session1->is_active());
+  EXPECT_FALSE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_TRUE(session3->is_active());
+  EXPECT_FALSE(session3->IsClosed());
+
+  // Should not do anything, all are active
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_TRUE(session1->is_active());
+  EXPECT_FALSE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_TRUE(session3->is_active());
+  EXPECT_FALSE(session3->IsClosed());
+
+  // Make sessions 1 and 3 inactive, but keep them open.
+  // Session 2 still open and active
+  session1->CloseCreatedStream(spdy_stream1, OK);
+  session3->CloseCreatedStream(spdy_stream3, OK);
+  EXPECT_FALSE(session1->is_active());
+  EXPECT_FALSE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_FALSE(session3->is_active());
+  EXPECT_FALSE(session3->IsClosed());
+
+  // Should close session 1 and 3, 2 should be left open
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_FALSE(session1->is_active());
+  EXPECT_TRUE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_FALSE(session3->is_active());
+  EXPECT_TRUE(session3->IsClosed());
+
+  // Should not do anything
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+
+  // Make 2 not active
+  session2->CloseCreatedStream(spdy_stream2, OK);
+  EXPECT_FALSE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+
+  // This should close session 2
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_FALSE(session2->is_active());
+  EXPECT_TRUE(session2->IsClosed());
+}
+
+// Start with max concurrent streams set to 1.  Request two streams.  Receive a
+// settings frame setting max concurrent streams to 2.  Have the callback
+// release the stream, which releases its reference (the last) to the session.
+// Make sure nothing blows up.
+// http://crbug.com/57331
+TEST_F(SpdySessionSpdy2Test, OnSettings) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  SettingsMap new_settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
+  const size_t max_concurrent_streams = 2;
+  new_settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+
+  // Set up the socket so we read a SETTINGS frame that raises max concurrent
+  // streams to 2.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  // Initialize the SpdySetting with 1 max concurrent streams.
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      kSpdySettingsIds1,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      1);
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Create 2 streams.  First will succeed.  Second will be pending.
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url("http://www.google.com");
+  EXPECT_EQ(OK,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback1.callback()));
+
+  StreamReleaserCallback stream_releaser(session, spdy_stream1);
+
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  stream_releaser.stream(),
+                                  BoundNetLog(),
+                                  stream_releaser.callback()));
+
+  // Make sure |stream_releaser| holds the last refs.
+  session = NULL;
+  spdy_stream1 = NULL;
+
+  EXPECT_EQ(OK, stream_releaser.WaitForResult());
+}
+
+// Start with max concurrent streams set to 1.  Request two streams.  When the
+// first completes, have the callback close itself, which should trigger the
+// second stream creation.  Then cancel that one immediately.  Don't crash.
+// http://crbug.com/63532
+TEST_F(SpdySessionSpdy2Test, CancelPendingCreateStream) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  // Initialize the SpdySetting with 1 max concurrent streams.
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      SETTINGS_MAX_CONCURRENT_STREAMS,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      1);
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
+  // a valgrind error if the callback is invoked when it's not supposed to be.
+  scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
+
+  // Create 2 streams.  First will succeed.  Second will be pending.
+  scoped_refptr<SpdyStream> spdy_stream1;
+  GURL url("http://www.google.com");
+  ASSERT_EQ(OK,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback->callback()));
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback->callback()));
+
+  // Release the first one, this will allow the second to be created.
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+
+  session->CancelPendingCreateStreams(&spdy_stream2);
+  callback.reset();
+
+  // Should not crash when running the pending callback.
+  MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpdySessionSpdy2Test, SendInitialSettingsOnNewSession) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  SettingsMap settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
+  settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+  };
+
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  SpdySessionPoolPeer pool_peer(spdy_session_pool);
+  pool_peer.EnableSendingInitialSettings(true);
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  MessageLoop::current()->RunUntilIdle();
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_F(SpdySessionSpdy2Test, SendSettingsOnNewSession) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  // Create the bogus setting that we want to verify is sent out.
+  // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
+  // to persist it into the HttpServerProperties, we need to mark as
+  // SETTINGS_FLAG_PLEASE_PERSIST.
+  SettingsMap settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_UPLOAD_BANDWIDTH;
+  const uint32 kBogusSettingValue = 0xCDCD;
+  settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, kBogusSettingValue);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+  };
+
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      kSpdySettingsIds1,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      kBogusSettingValue);
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  MessageLoop::current()->RunUntilIdle();
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+namespace {
+// This test has two variants, one for each style of closing the connection.
+// If |clean_via_close_current_sessions| is false, the sessions are closed
+// manually, calling SpdySessionPool::Remove() directly.  If it is true,
+// sessions are closed with SpdySessionPool::CloseCurrentSessions().
+void IPPoolingTest(bool clean_via_close_current_sessions) {
+  const int kTestPort = 80;
+  struct TestHosts {
+    std::string name;
+    std::string iplist;
+    HostPortProxyPair pair;
+    AddressList addresses;
+  } test_hosts[] = {
+    { "www.foo.com",    "192.0.2.33,192.168.0.1,192.168.0.5" },
+    { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33" },
+    { "js.foo.com",     "192.168.0.4,192.168.0.3" },
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
+    session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
+        test_hosts[i].iplist, "");
+
+    // This test requires that the HostResolver cache be populated.  Normal
+    // code would have done this already, but we do it manually.
+    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
+    session_deps.host_resolver->Resolve(
+        info, &test_hosts[i].addresses, CompletionCallback(), NULL,
+        BoundNetLog());
+
+    // Setup a HostPortProxyPair
+    test_hosts[i].pair = HostPortProxyPair(
+        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
+  }
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  // Setup the first session to the first host.
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
+
+  HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // TODO(rtenneti): MockClientSocket::GetPeerAddress return's 0 as the port
+  // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
+  SpdySessionPoolPeer pool_peer(spdy_session_pool);
+  pool_peer.AddAlias(test_hosts[0].addresses.front(), test_hosts[0].pair);
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  // The third host has no overlap with the first, so it can't pool IPs.
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
+
+  // The second host overlaps with the first, and should IP pool.
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+
+  // Verify that the second host, through a proxy, won't share the IP.
+  HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
+      ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
+  EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
+
+  // Overlap between 2 and 3 does is not transitive to 1.
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
+
+  // Create a new session to host 2.
+  scoped_refptr<SpdySession> session2 =
+      spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
+
+  // Verify that we have sessions for everything.
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
+
+  // Grab the session to host 1 and verify that it is the same session
+  // we got with host 0, and that is a different than host 2's session.
+  scoped_refptr<SpdySession> session1 =
+      spdy_session_pool->Get(test_hosts[1].pair, BoundNetLog());
+  EXPECT_EQ(session.get(), session1.get());
+  EXPECT_NE(session2.get(), session1.get());
+
+  // Remove the aliases and observe that we still have a session for host1.
+  pool_peer.RemoveAliases(test_hosts[0].pair);
+  pool_peer.RemoveAliases(test_hosts[1].pair);
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+
+  // Expire the host cache
+  session_deps.host_resolver->GetHostCache()->clear();
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+
+  // Cleanup the sessions.
+  if (!clean_via_close_current_sessions) {
+    spdy_session_pool->Remove(session);
+    session = NULL;
+    spdy_session_pool->Remove(session2);
+    session2 = NULL;
+  } else {
+    spdy_session_pool->CloseCurrentSessions(net::ERR_ABORTED);
+  }
+
+  // Verify that the map is all cleaned up.
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
+}
+
+}  // namespace
+
+TEST_F(SpdySessionSpdy2Test, IPPooling) {
+  IPPoolingTest(false);
+}
+
+TEST_F(SpdySessionSpdy2Test, IPPoolingCloseCurrentSessions) {
+  IPPoolingTest(true);
+}
+
+TEST_F(SpdySessionSpdy2Test, ClearSettingsStorageOnIPAddressChanged) {
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+
+  SpdySessionDependencies session_deps;
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  HttpServerProperties* test_http_server_properties =
+      spdy_session_pool->http_server_properties();
+  SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2);
+  test_http_server_properties->SetSpdySetting(
+      test_host_port_pair,
+      SETTINGS_MAX_CONCURRENT_STREAMS,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      2);
+  EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
+      test_host_port_pair).size());
+  spdy_session_pool->OnIPAddressChanged();
+  EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
+      test_host_port_pair).size());
+}
+
+TEST_F(SpdySessionSpdy2Test, NeedsCredentials) {
+  SpdySessionDependencies session_deps;
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.channel_id_sent = true;
+  ssl.protocol_negotiated = kProtoSPDY2;
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  SSLConfig ssl_config;
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_refptr<SOCKSSocketParams> socks_params;
+  scoped_refptr<HttpProxySocketParams> http_proxy_params;
+  scoped_refptr<SSLSocketParams> ssl_params(
+      new SSLSocketParams(transport_params,
+                          socks_params,
+                          http_proxy_params,
+                          ProxyServer::SCHEME_DIRECT,
+                          test_host_port_pair,
+                          ssl_config,
+                          0,
+                          false,
+                          false));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 ssl_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetSSLSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
+
+  EXPECT_FALSE(session->NeedsCredentials());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  spdy_session_pool->Remove(session);
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+}
+
+TEST_F(SpdySessionSpdy2Test, CloseSessionOnError) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
+  MockRead reads[] = {
+    CreateMockRead(*goaway),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+
+  CapturingBoundNetLog log;
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, log.bound());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 log.bound()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Check that the NetLog was filled reasonably.
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+  EXPECT_LT(0u, entries.size());
+
+  // Check that we logged SPDY_SESSION_CLOSE correctly.
+  int pos = net::ExpectLogContainsSomewhere(
+      entries, 0,
+      net::NetLog::TYPE_SPDY_SESSION_CLOSE,
+      net::NetLog::PHASE_NONE);
+
+  CapturingNetLog::CapturedEntry entry = entries[pos];
+  int error_code = 0;
+  ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
+  EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
+}
+
+TEST_F(SpdySessionSpdy2Test, OutOfOrderSynStreams) {
+  // Construct the request.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, HIGHEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req1, 2),
+    CreateMockWrite(*req2, 1),
+  };
+
+  scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp1, 3),
+    CreateMockRead(*body1, 4),
+    CreateMockRead(*resp2, 5),
+    CreateMockRead(*body2, 6),
+    MockRead(ASYNC, 0, 7)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  StaticSocketDataProvider data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1, LOWEST, &spdy_stream1,
+                                      BoundNetLog(), callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url2, HIGHEST, &spdy_stream2,
+                                      BoundNetLog(), callback2.callback()));
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url1.scheme();
+  (*headers)["host"] = url1.host();
+  (*headers)["url"] = url1.path();
+  (*headers)["version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+
+  spdy_stream1->SendRequest(false);
+  spdy_stream2->SendRequest(false);
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_EQ(3u, spdy_stream1->stream_id());
+  EXPECT_EQ(1u, spdy_stream2->stream_id());
+
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, CancelStream) {
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  // Request 1, at HIGHEST priority, will be cancelled before it writes data.
+  // Request 2, at LOWEST priority, will be a full request and will be id 1.
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req2, 0),
+  };
+
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp2, 1),
+    CreateMockRead(*body2, 2),
+    MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
+                                      BoundNetLog(), callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
+                                      BoundNetLog(), callback2.callback()));
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url1.scheme();
+  (*headers)["host"] = url1.host();
+  (*headers)["url"] = url1.path();
+  (*headers)["version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+
+  spdy_stream1->SendRequest(false);
+  spdy_stream2->SendRequest(false);
+
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  spdy_stream1->Cancel();
+
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  data.RunFor(1);
+
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+  EXPECT_EQ(1u, spdy_stream2->stream_id());
+
+  spdy_stream1 = NULL;
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, CloseSessionWithTwoCreatedStreams) {
+  // Test that if a sesion is closed with two created streams pending,
+  // it does not crash.  http://crbug.com/139518
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  // No actual data will be sent.
+  MockWrite writes[] = {
+    MockWrite(ASYNC, 0, 1)  // EOF
+  };
+
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
+                                      BoundNetLog(), callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
+                                      BoundNetLog(), callback2.callback()));
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url1.scheme();
+  (*headers)["host"] = url1.host();
+  (*headers)["url"] = url1.path();
+  (*headers)["version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+  ClosingDelegate delegate1(spdy_stream1.get());
+  spdy_stream1->SetDelegate(&delegate1);
+
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+  ClosingDelegate delegate2(spdy_stream2.get());
+  spdy_stream2->SetDelegate(&delegate2);
+
+  spdy_stream1->SendRequest(false);
+  spdy_stream2->SendRequest(false);
+
+  // Ensure that the streams have not yet been activated and assigned an id.
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  // Ensure we don't crash while closing the session.
+  session->CloseSessionOnError(ERR_ABORTED, true, "");
+
+  EXPECT_TRUE(spdy_stream1->closed());
+  EXPECT_TRUE(spdy_stream2->closed());
+
+  spdy_stream1 = NULL;
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy2Test, CloseTwoStalledCreateStream) {
+  // TODO(rtenneti): Define a helper class/methods and move the common code in
+  // this file.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+
+  SettingsMap new_settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
+  const uint32 max_concurrent_streams = 1;
+  new_settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+
+  scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req1, 1),
+    CreateMockWrite(*req2, 4),
+    CreateMockWrite(*req3, 7),
+  };
+
+  // Set up the socket so we read a SETTINGS frame that sets max concurrent
+  // streams to 1.
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
+
+  scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, true));
+
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame),
+    CreateMockRead(*resp1, 2),
+    CreateMockRead(*body1, 3),
+    CreateMockRead(*resp2, 5),
+    CreateMockRead(*body2, 6),
+    CreateMockRead(*resp3, 8),
+    CreateMockRead(*body3, 9),
+    MockRead(ASYNC, 0, 10)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                LOWEST,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, LOWEST, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Read the settings frame.
+  data.RunFor(1);
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1,
+                                      LOWEST,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url2,
+                                  LOWEST,
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback2.callback()));
+
+  scoped_refptr<SpdyStream> spdy_stream3;
+  TestCompletionCallback callback3;
+  GURL url3("http://www.google.com");
+  EXPECT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url3,
+                                  LOWEST,
+                                  &spdy_stream3,
+                                  BoundNetLog(),
+                                  callback3.callback()));
+
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url1.scheme();
+  (*headers)["host"] = url1.host();
+  (*headers)["url"] = url1.path();
+  (*headers)["version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+  scoped_ptr<SpdyHeaderBlock> headers3(new SpdyHeaderBlock);
+  *headers3 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+  spdy_stream1->SendRequest(false);
+
+  // Run until 1st stream is closed.
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+  data.RunFor(3);
+  EXPECT_EQ(1u, spdy_stream1->stream_id());
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+
+  EXPECT_TRUE(spdy_stream2.get() != NULL);
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+  spdy_stream2->SendRequest(false);
+
+  // Run until 2nd stream is closed.
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+  data.RunFor(3);
+  EXPECT_EQ(3u, spdy_stream2->stream_id());
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+
+  EXPECT_TRUE(spdy_stream3.get() != NULL);
+  spdy_stream3->set_spdy_headers(headers3.Pass());
+  EXPECT_TRUE(spdy_stream3->HasUrl());
+  spdy_stream3->SendRequest(false);
+
+  EXPECT_EQ(0u, spdy_stream3->stream_id());
+  data.RunFor(4);
+  EXPECT_EQ(5u, spdy_stream3->stream_id());
+  EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+}
+
+TEST_F(SpdySessionSpdy2Test, CancelTwoStalledCreateStream) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Initialize the SpdySetting with 1 max concurrent streams.
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      SETTINGS_MAX_CONCURRENT_STREAMS,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      1);
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                LOWEST,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params,
+                                 LOWEST,
+                                 CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  ASSERT_EQ(OK,
+            session->CreateStream(url1,
+                                  LOWEST,
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url2,
+                                  LOWEST,
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback2.callback()));
+
+  scoped_refptr<SpdyStream> spdy_stream3;
+  TestCompletionCallback callback3;
+  GURL url3("http://www.google.com");
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url3,
+                                  LOWEST,
+                                  &spdy_stream3,
+                                  BoundNetLog(),
+                                  callback3.callback()));
+
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
+
+  // Cancel the first stream, this will allow the second stream to be created.
+  EXPECT_TRUE(spdy_stream1.get() != NULL);
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+  session->CancelPendingCreateStreams(&spdy_stream1);
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+
+  // Cancel the second stream, this will allow the third stream to be created.
+  EXPECT_TRUE(spdy_stream2.get() != NULL);
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+  session->CancelPendingCreateStreams(&spdy_stream2);
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+
+  // Cancel the third stream.
+  EXPECT_TRUE(spdy_stream3.get() != NULL);
+  spdy_stream3->Cancel();
+  spdy_stream3 = NULL;
+  session->CancelPendingCreateStreams(&spdy_stream3);
+  EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_session_spdy3_unittest.cc b/src/net/spdy/spdy_session_spdy3_unittest.cc
new file mode 100644
index 0000000..3065e64
--- /dev/null
+++ b/src/net/spdy/spdy_session_spdy3_unittest.cc
@@ -0,0 +1,2205 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_session.h"
+
+#include "net/base/cert_test_util.h"
+#include "net/base/host_cache.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/test_data_directory.h"
+#include "net/spdy/spdy_io_buffer.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_stream.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "testing/platform_test.h"
+
+using namespace net::test_spdy3;
+
+namespace net {
+
+namespace {
+
+static int g_delta_seconds = 0;
+base::TimeTicks TheNearFuture() {
+  return base::TimeTicks::Now() + base::TimeDelta::FromSeconds(g_delta_seconds);
+}
+
+class ClosingDelegate : public SpdyStream::Delegate {
+ public:
+  ClosingDelegate(SpdyStream* stream) : stream_(stream) {}
+
+  // SpdyStream::Delegate implementation:
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE {
+    return true;
+  }
+  virtual int OnSendBody() OVERRIDE {
+    return OK;
+  }
+  virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE {
+    return OK;
+  }
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE {
+    return OK;
+  }
+  virtual void OnHeadersSent() OVERRIDE {}
+  virtual int OnDataReceived(const char* data, int length) OVERRIDE {
+    return OK;
+  }
+  virtual void OnDataSent(int length) OVERRIDE {}
+  virtual void OnClose(int status) OVERRIDE {
+    stream_->Close();
+  }
+ private:
+  SpdyStream* stream_;
+};
+
+
+class TestSpdyStreamDelegate : public SpdyStream::Delegate {
+ public:
+  explicit TestSpdyStreamDelegate(const CompletionCallback& callback)
+      : callback_(callback) {}
+  virtual ~TestSpdyStreamDelegate() {}
+
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE { return true; }
+
+  virtual int OnSendBody() OVERRIDE {
+    return ERR_UNEXPECTED;
+  }
+
+  virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) OVERRIDE {
+    return ERR_UNEXPECTED;
+  }
+
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE {
+    return status;
+  }
+
+  virtual void OnHeadersSent() OVERRIDE {}
+  virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE {
+    return OK;
+  }
+
+  virtual void OnDataSent(int length) OVERRIDE {}
+
+  virtual void OnClose(int status) OVERRIDE {
+    CompletionCallback callback = callback_;
+    callback_.Reset();
+    callback.Run(OK);
+  }
+
+ private:
+  CompletionCallback callback_;
+};
+
+} // namespace
+
+class SpdySessionSpdy3Test : public PlatformTest {
+ protected:
+  void SetUp() {
+    g_delta_seconds = 0;
+  }
+};
+
+// Test the SpdyIOBuffer class.
+TEST_F(SpdySessionSpdy3Test, SpdyIOBuffer) {
+  std::priority_queue<SpdyIOBuffer> queue_;
+  const size_t kQueueSize = 100;
+
+  // Insert items with random priority and increasing buffer size
+  for (size_t index = 0; index < kQueueSize; ++index) {
+    queue_.push(SpdyIOBuffer(
+        new IOBufferWithSize(index + 1),
+        index + 1,
+        static_cast<RequestPriority>(rand() % NUM_PRIORITIES),
+        NULL));
+  }
+
+  EXPECT_EQ(kQueueSize, queue_.size());
+
+  // Verify items come out with decreasing priority or FIFO order.
+  RequestPriority last_priority = NUM_PRIORITIES;
+  size_t last_size = 0;
+  for (size_t index = 0; index < kQueueSize; ++index) {
+    SpdyIOBuffer buffer = queue_.top();
+    EXPECT_LE(buffer.priority(), last_priority);
+    if (buffer.priority() < last_priority)
+      last_size = 0;
+    EXPECT_LT(last_size, buffer.size());
+    last_priority = buffer.priority();
+    last_size = buffer.size();
+    queue_.pop();
+  }
+
+  EXPECT_EQ(0u, queue_.size());
+}
+
+TEST_F(SpdySessionSpdy3Test, GoAway) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
+  MockRead reads[] = {
+    CreateMockRead(*goaway),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.SetNextProto(kProtoSPDY3);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  EXPECT_EQ(3, session->GetProtocolVersion());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<SpdySession> session2 =
+      spdy_session_pool->Get(pair, BoundNetLog());
+
+  // Delete the first session.
+  session = NULL;
+
+  // Delete the second session.
+  spdy_session_pool->Remove(session2);
+  session2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, ClientPing) {
+  SpdySessionDependencies session_deps;
+  session_deps.enable_ping = true;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(1));
+  MockRead reads[] = {
+    CreateMockRead(*read_ping),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(1));
+  MockWrite writes[] = {
+    CreateMockWrite(*write_ping),
+  };
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  EXPECT_EQ(OK, session->CreateStream(url,
+                                      MEDIUM,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(callback1.callback()));
+  spdy_stream1->SetDelegate(delegate.get());
+
+  base::TimeTicks before_ping_time = base::TimeTicks::Now();
+
+  session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
+  session->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
+
+  session->SendPrefacePingIfNoneInFlight();
+
+  EXPECT_EQ(OK, callback1.WaitForResult());
+
+  session->CheckPingStatus(before_ping_time);
+
+  EXPECT_EQ(0, session->pings_in_flight());
+  EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
+  EXPECT_FALSE(session->check_ping_status_pending());
+  EXPECT_GE(session->last_activity_time(), before_ping_time);
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Delete the first session.
+  session = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, ServerPing) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(2));
+  MockRead reads[] = {
+    CreateMockRead(*read_ping),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(2));
+  MockWrite writes[] = {
+    CreateMockWrite(*write_ping),
+  };
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  EXPECT_EQ(OK, session->CreateStream(url,
+                                      MEDIUM,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(callback1.callback()));
+  spdy_stream1->SetDelegate(delegate.get());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Delete the session.
+  session = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, DeleteExpiredPushStreams) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+  session_deps.time_func = TheNearFuture;
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  // Give the session a SPDY3 framer.
+  session->buffered_spdy_framer_.reset(new BufferedSpdyFramer(3, false));
+
+  // Create the associated stream and add to active streams.
+  scoped_ptr<SpdyHeaderBlock> request_headers(new SpdyHeaderBlock);
+  (*request_headers)[":scheme"] = "http";
+  (*request_headers)[":host"] = "www.google.com";
+  (*request_headers)[":path"] = "/";
+
+  scoped_refptr<SpdyStream> stream(
+      new SpdyStream(session, false, session->net_log_));
+  stream->set_spdy_headers(request_headers.Pass());
+  session->ActivateStream(stream);
+
+  SpdyHeaderBlock headers;
+  headers[":scheme"] = "http";
+  headers[":host"] = "www.google.com";
+  headers[":path"] = "/a.dat";
+  session->OnSynStream(2, 1, 0, 0, true, false, headers);
+
+  // Verify that there is one unclaimed push stream.
+  EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
+  SpdySession::PushedStreamMap::iterator  iter  =
+      session->unclaimed_pushed_streams_.find("http://www.google.com/a.dat");
+  EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
+
+  // Shift time.
+  g_delta_seconds = 301;
+
+  headers[":scheme"] = "http";
+  headers[":host"] = "www.google.com";
+  headers[":path"] = "/b.dat";
+  session->OnSynStream(4, 1, 0, 0, true, false, headers);
+
+  // Verify that the second pushed stream evicted the first pushed stream.
+  EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
+  iter = session->unclaimed_pushed_streams_.find("http://www.google.com/b.dat");
+  EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
+
+  // Delete the session.
+  session = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, FailedPing) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(1));
+  MockRead reads[] = {
+    CreateMockRead(*read_ping),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+  scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(1));
+  MockWrite writes[] = {
+    CreateMockWrite(*write_ping),
+  };
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.gmail.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.gmail.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  EXPECT_EQ(OK, session->CreateStream(url,
+                                      MEDIUM,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(callback1.callback()));
+  spdy_stream1->SetDelegate(delegate.get());
+
+  session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
+  session->set_hung_interval(base::TimeDelta::FromSeconds(0));
+
+  // Send a PING frame.
+  session->WritePingFrame(1);
+  EXPECT_LT(0, session->pings_in_flight());
+  EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
+  EXPECT_TRUE(session->check_ping_status_pending());
+
+  // Assert session is not closed.
+  EXPECT_FALSE(session->IsClosed());
+  EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  // We set last time we have received any data in 1 sec less than now.
+  // CheckPingStatus will trigger timeout because hung interval is zero.
+  base::TimeTicks now = base::TimeTicks::Now();
+  session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
+  session->CheckPingStatus(now);
+
+  EXPECT_TRUE(session->IsClosed());
+  EXPECT_EQ(0u, session->num_active_streams());
+  EXPECT_EQ(0u, session->num_unclaimed_pushed_streams());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Delete the first session.
+  session = NULL;
+}
+
+class StreamReleaserCallback : public TestCompletionCallbackBase {
+ public:
+  StreamReleaserCallback(SpdySession* session,
+                         SpdyStream* first_stream)
+      : session_(session),
+        first_stream_(first_stream),
+        ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+            base::Bind(&StreamReleaserCallback::OnComplete,
+                       base::Unretained(this)))) {
+  }
+
+  virtual ~StreamReleaserCallback() {}
+
+  scoped_refptr<SpdyStream>* stream() { return &stream_; }
+
+  const CompletionCallback& callback() const { return callback_; }
+
+ private:
+  void OnComplete(int result) {
+    session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
+    session_ = NULL;
+    first_stream_->Cancel();
+    first_stream_ = NULL;
+    stream_->Cancel();
+    stream_ = NULL;
+    SetResult(result);
+  }
+
+  scoped_refptr<SpdySession> session_;
+  scoped_refptr<SpdyStream> first_stream_;
+  scoped_refptr<SpdyStream> stream_;
+  CompletionCallback callback_;
+};
+
+// TODO(kristianm): Could also test with more sessions where some are idle,
+// and more than one session to a HostPortPair.
+TEST_F(SpdySessionSpdy3Test, CloseIdleSessions) {
+  SpdySessionDependencies session_deps;
+  scoped_refptr<HttpNetworkSession> http_session(
+  SpdySessionDependencies::SpdyCreateSession(&session_deps));
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Set up session 1
+  const std::string kTestHost1("http://www.a.com");
+  HostPortPair test_host_port_pair1(kTestHost1, 80);
+  HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
+  scoped_refptr<SpdySession> session1 =
+      spdy_session_pool->Get(pair1, BoundNetLog());
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1(kTestHost1);
+  EXPECT_EQ(OK, session1->CreateStream(url1,
+                                      MEDIUM, /* priority, not important */
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+
+  // Set up session 2
+  const std::string kTestHost2("http://www.b.com");
+  HostPortPair test_host_port_pair2(kTestHost2, 80);
+  HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
+  scoped_refptr<SpdySession> session2 =
+      spdy_session_pool->Get(pair2, BoundNetLog());
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2(kTestHost2);
+  EXPECT_EQ(OK, session2->CreateStream(
+      url2, MEDIUM, /* priority, not important */
+      &spdy_stream2, BoundNetLog(), callback2.callback()));
+
+  // Set up session 3
+  const std::string kTestHost3("http://www.c.com");
+  HostPortPair test_host_port_pair3(kTestHost3, 80);
+  HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
+  scoped_refptr<SpdySession> session3 =
+      spdy_session_pool->Get(pair3, BoundNetLog());
+  scoped_refptr<SpdyStream> spdy_stream3;
+  TestCompletionCallback callback3;
+  GURL url3(kTestHost3);
+  EXPECT_EQ(OK, session3->CreateStream(
+      url3, MEDIUM, /* priority, not important */
+      &spdy_stream3, BoundNetLog(), callback3.callback()));
+
+  // All sessions are active and not closed
+  EXPECT_TRUE(session1->is_active());
+  EXPECT_FALSE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_TRUE(session3->is_active());
+  EXPECT_FALSE(session3->IsClosed());
+
+  // Should not do anything, all are active
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_TRUE(session1->is_active());
+  EXPECT_FALSE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_TRUE(session3->is_active());
+  EXPECT_FALSE(session3->IsClosed());
+
+  // Make sessions 1 and 3 inactive, but keep them open.
+  // Session 2 still open and active
+  session1->CloseCreatedStream(spdy_stream1, OK);
+  session3->CloseCreatedStream(spdy_stream3, OK);
+  EXPECT_FALSE(session1->is_active());
+  EXPECT_FALSE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_FALSE(session3->is_active());
+  EXPECT_FALSE(session3->IsClosed());
+
+  // Should close session 1 and 3, 2 should be left open
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_FALSE(session1->is_active());
+  EXPECT_TRUE(session1->IsClosed());
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+  EXPECT_FALSE(session3->is_active());
+  EXPECT_TRUE(session3->IsClosed());
+
+  // Should not do anything
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_TRUE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+
+  // Make 2 not active
+  session2->CloseCreatedStream(spdy_stream2, OK);
+  EXPECT_FALSE(session2->is_active());
+  EXPECT_FALSE(session2->IsClosed());
+
+  // This should close session 2
+  spdy_session_pool->CloseIdleSessions();
+  EXPECT_FALSE(session2->is_active());
+  EXPECT_TRUE(session2->IsClosed());
+}
+
+// Start with max concurrent streams set to 1.  Request two streams.  Receive a
+// settings frame setting max concurrent streams to 2.  Have the callback
+// release the stream, which releases its reference (the last) to the session.
+// Make sure nothing blows up.
+// http://crbug.com/57331
+TEST_F(SpdySessionSpdy3Test, OnSettings) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  SettingsMap new_settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
+  const size_t max_concurrent_streams = 2;
+  new_settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+
+  // Set up the socket so we read a SETTINGS frame that raises max concurrent
+  // streams to 2.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  // Initialize the SpdySetting with 1 max concurrent streams.
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      kSpdySettingsIds1,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      1);
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Create 2 streams.  First will succeed.  Second will be pending.
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url("http://www.google.com");
+  EXPECT_EQ(OK,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback1.callback()));
+
+  StreamReleaserCallback stream_releaser(session, spdy_stream1);
+
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  stream_releaser.stream(),
+                                  BoundNetLog(),
+                                  stream_releaser.callback()));
+
+  // Make sure |stream_releaser| holds the last refs.
+  session = NULL;
+  spdy_stream1 = NULL;
+
+  EXPECT_EQ(OK, stream_releaser.WaitForResult());
+}
+
+// Start with max concurrent streams set to 1.  Request two streams.  When the
+// first completes, have the callback close itself, which should trigger the
+// second stream creation.  Then cancel that one immediately.  Don't crash.
+// http://crbug.com/63532
+TEST_F(SpdySessionSpdy3Test, CancelPendingCreateStream) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  // Initialize the SpdySetting with 1 max concurrent streams.
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      SETTINGS_MAX_CONCURRENT_STREAMS,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      1);
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
+  // a valgrind error if the callback is invoked when it's not supposed to be.
+  scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
+
+  // Create 2 streams.  First will succeed.  Second will be pending.
+  scoped_refptr<SpdyStream> spdy_stream1;
+  GURL url("http://www.google.com");
+  ASSERT_EQ(OK,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback->callback()));
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url,
+                                  MEDIUM, /* priority, not important */
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback->callback()));
+
+  // Release the first one, this will allow the second to be created.
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+
+  session->CancelPendingCreateStreams(&spdy_stream2);
+  callback.reset();
+
+  // Should not crash when running the pending callback.
+  MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpdySessionSpdy3Test, SendInitialSettingsOnNewSession) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  SettingsMap settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
+  const SpdySettingsIds kSpdySettingsIds2 = SETTINGS_INITIAL_WINDOW_SIZE;
+  const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024;
+  settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
+  settings[kSpdySettingsIds2] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+  };
+  session_deps.initial_recv_window_size = kInitialRecvWindowSize;
+
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  static const char kStreamUrl[] = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  const std::string kTestHost("www.google.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  SpdySessionPoolPeer pool_peer(spdy_session_pool);
+  pool_peer.EnableSendingInitialSettings(true);
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  MessageLoop::current()->RunUntilIdle();
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+TEST_F(SpdySessionSpdy3Test, SendSettingsOnNewSession) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  // Create the bogus setting that we want to verify is sent out.
+  // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
+  // to persist it into the HttpServerProperties, we need to mark as
+  // SETTINGS_FLAG_PLEASE_PERSIST.
+  SettingsMap settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_UPLOAD_BANDWIDTH;
+  const uint32 kBogusSettingValue = 0xCDCD;
+  settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, kBogusSettingValue);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+  };
+
+  StaticSocketDataProvider data(
+      reads, arraysize(reads), writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      kSpdySettingsIds1,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      kBogusSettingValue);
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  MessageLoop::current()->RunUntilIdle();
+  EXPECT_TRUE(data.at_write_eof());
+}
+
+namespace {
+// This test has two variants, one for each style of closing the connection.
+// If |clean_via_close_current_sessions| is false, the sessions are closed
+// manually, calling SpdySessionPool::Remove() directly.  If it is true,
+// sessions are closed with SpdySessionPool::CloseCurrentSessions().
+void IPPoolingTest(bool clean_via_close_current_sessions) {
+  const int kTestPort = 80;
+  struct TestHosts {
+    std::string name;
+    std::string iplist;
+    HostPortProxyPair pair;
+    AddressList addresses;
+  } test_hosts[] = {
+    { "www.foo.com",    "192.0.2.33,192.168.0.1,192.168.0.5" },
+    { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33" },
+    { "js.foo.com",     "192.168.0.4,192.168.0.3" },
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
+    session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
+        test_hosts[i].iplist, "");
+
+    // This test requires that the HostResolver cache be populated.  Normal
+    // code would have done this already, but we do it manually.
+    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
+    session_deps.host_resolver->Resolve(
+        info, &test_hosts[i].addresses, CompletionCallback(), NULL,
+        BoundNetLog());
+
+    // Setup a HostPortProxyPair
+    test_hosts[i].pair = HostPortProxyPair(
+        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
+  }
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  // Setup the first session to the first host.
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
+
+  HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // TODO(rtenneti): MockClientSocket::GetPeerAddress return's 0 as the port
+  // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
+  SpdySessionPoolPeer pool_peer(spdy_session_pool);
+  pool_peer.AddAlias(test_hosts[0].addresses.front(), test_hosts[0].pair);
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  // The third host has no overlap with the first, so it can't pool IPs.
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
+
+  // The second host overlaps with the first, and should IP pool.
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+
+  // Verify that the second host, through a proxy, won't share the IP.
+  HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
+      ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
+  EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
+
+  // Overlap between 2 and 3 does is not transitive to 1.
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
+
+  // Create a new session to host 2.
+  scoped_refptr<SpdySession> session2 =
+      spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
+
+  // Verify that we have sessions for everything.
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
+
+  // Grab the session to host 1 and verify that it is the same session
+  // we got with host 0, and that is a different than host 2's session.
+  scoped_refptr<SpdySession> session1 =
+      spdy_session_pool->Get(test_hosts[1].pair, BoundNetLog());
+  EXPECT_EQ(session.get(), session1.get());
+  EXPECT_NE(session2.get(), session1.get());
+
+  // Remove the aliases and observe that we still have a session for host1.
+  pool_peer.RemoveAliases(test_hosts[0].pair);
+  pool_peer.RemoveAliases(test_hosts[1].pair);
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+
+  // Expire the host cache
+  session_deps.host_resolver->GetHostCache()->clear();
+  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
+
+  // Cleanup the sessions.
+  if (!clean_via_close_current_sessions) {
+    spdy_session_pool->Remove(session);
+    session = NULL;
+    spdy_session_pool->Remove(session2);
+    session2 = NULL;
+  } else {
+    spdy_session_pool->CloseCurrentSessions(net::ERR_ABORTED);
+  }
+
+  // Verify that the map is all cleaned up.
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
+  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
+}
+
+}  // namespace
+
+TEST_F(SpdySessionSpdy3Test, IPPooling) {
+  IPPoolingTest(false);
+}
+
+TEST_F(SpdySessionSpdy3Test, IPPoolingCloseCurrentSessions) {
+  IPPoolingTest(true);
+}
+
+TEST_F(SpdySessionSpdy3Test, ClearSettingsStorageOnIPAddressChanged) {
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+
+  SpdySessionDependencies session_deps;
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  HttpServerProperties* test_http_server_properties =
+      spdy_session_pool->http_server_properties();
+  SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2);
+  test_http_server_properties->SetSpdySetting(
+      test_host_port_pair,
+      SETTINGS_MAX_CONCURRENT_STREAMS,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      2);
+  EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
+      test_host_port_pair).size());
+  spdy_session_pool->OnIPAddressChanged();
+  EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
+      test_host_port_pair).size());
+}
+
+TEST_F(SpdySessionSpdy3Test, NeedsCredentials) {
+  SpdySessionDependencies session_deps;
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.channel_id_sent = true;
+  ssl.protocol_negotiated = kProtoSPDY3;
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const GURL url("https:/www.foo.com");
+  HostPortPair test_host_port_pair(url.host(), 443);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  SSLConfig ssl_config;
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_refptr<SOCKSSocketParams> socks_params;
+  scoped_refptr<HttpProxySocketParams> http_proxy_params;
+  scoped_refptr<SSLSocketParams> ssl_params(
+      new SSLSocketParams(transport_params,
+                          socks_params,
+                          http_proxy_params,
+                          ProxyServer::SCHEME_DIRECT,
+                          test_host_port_pair,
+                          ssl_config,
+                          0,
+                          false,
+                          false));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 ssl_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetSSLSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
+
+  EXPECT_TRUE(session->NeedsCredentials());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  spdy_session_pool->Remove(session);
+}
+
+TEST_F(SpdySessionSpdy3Test, SendCredentials) {
+  SpdySessionDependencies session_deps;
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+  SettingsMap settings;
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
+  MockWrite writes[] = {
+    CreateMockWrite(*settings_frame),
+  };
+  StaticSocketDataProvider data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.channel_id_sent = true;
+  ssl.protocol_negotiated = kProtoSPDY3;
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const GURL kTestUrl("https://www.foo.com");
+  HostPortPair test_host_port_pair(kTestUrl.host(), 443);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  SSLConfig ssl_config;
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_refptr<SOCKSSocketParams> socks_params;
+  scoped_refptr<HttpProxySocketParams> http_proxy_params;
+  scoped_refptr<SSLSocketParams> ssl_params(
+      new SSLSocketParams(transport_params,
+                          socks_params,
+                          http_proxy_params,
+                          ProxyServer::SCHEME_DIRECT,
+                          test_host_port_pair,
+                          ssl_config,
+                          0,
+                          false,
+                          false));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 ssl_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetSSLSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
+  EXPECT_TRUE(session->NeedsCredentials());
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  spdy_session_pool->Remove(session);
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+}
+
+TEST_F(SpdySessionSpdy3Test, CloseSessionOnError) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
+  MockRead reads[] = {
+    CreateMockRead(*goaway),
+    MockRead(SYNCHRONOUS, 0, 0)  // EOF
+  };
+
+  CapturingBoundNetLog log;
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, log.bound());
+  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 log.bound()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Flush the SpdySession::OnReadComplete() task.
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+
+  // Check that the NetLog was filled reasonably.
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+  EXPECT_LT(0u, entries.size());
+
+  // Check that we logged SPDY_SESSION_CLOSE correctly.
+  int pos = net::ExpectLogContainsSomewhere(
+      entries, 0,
+      net::NetLog::TYPE_SPDY_SESSION_CLOSE,
+      net::NetLog::PHASE_NONE);
+
+  CapturingNetLog::CapturedEntry entry = entries[pos];
+  int error_code = 0;
+  ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
+  EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
+}
+
+TEST_F(SpdySessionSpdy3Test, UpdateStreamsSendWindowSize) {
+  // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
+  // gets sent.
+  SettingsMap new_settings;
+  int32 window_size = 1;
+  new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
+
+  // Set up the socket so we read a SETTINGS frame that sets
+  // INITIAL_WINDOW_SIZE.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame, 0),
+    MockRead(ASYNC, 0, 1)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  scoped_ptr<DeterministicSocketData> data(
+      new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
+  data->set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(data.get());
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url("http://www.google.com");
+  EXPECT_EQ(OK,
+            session->CreateStream(url,
+                                  MEDIUM,  /* priority, not important */
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback1.callback()));
+  EXPECT_NE(spdy_stream1->send_window_size(), window_size);
+
+  data->RunFor(1);  // Process the SETTINGS frame, but not the EOF
+  MessageLoop::current()->RunUntilIdle();
+  EXPECT_EQ(session->initial_send_window_size(), window_size);
+  EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
+
+  // Release the first one, this will allow the second to be created.
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  EXPECT_EQ(OK,
+            session->CreateStream(url,
+                                  MEDIUM,  /* priority, not important */
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback1.callback()));
+
+  EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, OutOfOrderSynStreams) {
+  // Construct the request.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, HIGHEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req1, 2),
+    CreateMockWrite(*req2, 1),
+  };
+
+  scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(5, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp1, 3),
+    CreateMockRead(*body1, 4),
+    CreateMockRead(*resp2, 5),
+    CreateMockRead(*body2, 6),
+    MockRead(ASYNC, 0, 7)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  StaticSocketDataProvider data(reads, arraysize(reads),
+                                writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1, LOWEST, &spdy_stream1,
+                                      BoundNetLog(), callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url2, HIGHEST, &spdy_stream2,
+                                      BoundNetLog(), callback2.callback()));
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)[":method"] = "GET";
+  (*headers)[":scheme"] = url1.scheme();
+  (*headers)[":host"] = url1.host();
+  (*headers)[":path"] = url1.path();
+  (*headers)[":version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+
+  spdy_stream1->SendRequest(false);
+  spdy_stream2->SendRequest(false);
+  MessageLoop::current()->RunUntilIdle();
+
+  EXPECT_EQ(3u, spdy_stream1->stream_id());
+  EXPECT_EQ(1u, spdy_stream2->stream_id());
+
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, CancelStream) {
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  // Request 1, at HIGHEST priority, will be cancelled before it writes data.
+  // Request 2, at LOWEST priority, will be a full request and will be id 1.
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req2, 0),
+  };
+
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
+  MockRead reads[] = {
+    CreateMockRead(*resp2, 1),
+    CreateMockRead(*body2, 2),
+    MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
+                                      BoundNetLog(), callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
+                                      BoundNetLog(), callback2.callback()));
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)[":method"] = "GET";
+  (*headers)[":scheme"] = url1.scheme();
+  (*headers)[":host"] = url1.host();
+  (*headers)[":path"] = url1.path();
+  (*headers)[":version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+
+  spdy_stream1->SendRequest(false);
+  spdy_stream2->SendRequest(false);
+
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  spdy_stream1->Cancel();
+
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  data.RunFor(1);
+
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+  EXPECT_EQ(1u, spdy_stream2->stream_id());
+
+  spdy_stream1 = NULL;
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, CloseSessionWithTwoCreatedStreams) {
+  // Test that if a sesion is closed with two created streams pending,
+  // it does not crash.  http://crbug.com/139518
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  // No actual data will be sent.
+  MockWrite writes[] = {
+    MockWrite(ASYNC, 0, 1)  // EOF
+  };
+
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
+                                      BoundNetLog(), callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
+                                      BoundNetLog(), callback2.callback()));
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url1.scheme();
+  (*headers)["host"] = url1.host();
+  (*headers)["url"] = url1.path();
+  (*headers)["version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+  ClosingDelegate delegate1(spdy_stream1.get());
+  spdy_stream1->SetDelegate(&delegate1);
+
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+  ClosingDelegate delegate2(spdy_stream2.get());
+  spdy_stream2->SetDelegate(&delegate2);
+
+  spdy_stream1->SendRequest(false);
+  spdy_stream2->SendRequest(false);
+
+  // Ensure that the streams have not yet been activated and assigned an id.
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+  // Ensure we don't crash while closing the session.
+  session->CloseSessionOnError(ERR_ABORTED, true, "");
+
+  EXPECT_TRUE(spdy_stream1->closed());
+  EXPECT_TRUE(spdy_stream2->closed());
+
+  spdy_stream1 = NULL;
+  spdy_stream2 = NULL;
+}
+
+TEST_F(SpdySessionSpdy3Test, VerifyDomainAuthentication) {
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  // No actual data will be sent.
+  MockWrite writes[] = {
+    MockWrite(ASYNC, 0, 1)  // EOF
+  };
+
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  // Load a cert that is valid for:
+  //   www.example.org
+  //   mail.example.org
+  //   www.example.com
+  FilePath certs_dir = GetTestCertsDirectory();
+  scoped_refptr<X509Certificate> test_cert(
+      ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
+  ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.cert = test_cert;
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.example.org");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  SSLConfig ssl_config;
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_refptr<SOCKSSocketParams> socks_params;
+  scoped_refptr<HttpProxySocketParams> http_proxy_params;
+  scoped_refptr<SSLSocketParams> ssl_params(
+      new SSLSocketParams(transport_params,
+                          socks_params,
+                          http_proxy_params,
+                          ProxyServer::SCHEME_DIRECT,
+                          test_host_port_pair,
+                          ssl_config,
+                          0,
+                          false,
+                          false));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 ssl_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetSSLSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
+  EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
+  EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com"));
+  EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
+}
+
+TEST_F(SpdySessionSpdy3Test, ConnectionPooledWithTlsChannelId) {
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  // No actual data will be sent.
+  MockWrite writes[] = {
+    MockWrite(ASYNC, 0, 1)  // EOF
+  };
+
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 0)  // EOF
+  };
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  // Load a cert that is valid for:
+  //   www.example.org
+  //   mail.example.org
+  //   www.example.com
+  FilePath certs_dir = GetTestCertsDirectory();
+  scoped_refptr<X509Certificate> test_cert(
+      ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
+  ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  ssl.channel_id_sent = true;
+  ssl.cert = test_cert;
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.example.org");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  SSLConfig ssl_config;
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                MEDIUM,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_refptr<SOCKSSocketParams> socks_params;
+  scoped_refptr<HttpProxySocketParams> http_proxy_params;
+  scoped_refptr<SSLSocketParams> ssl_params(
+      new SSLSocketParams(transport_params,
+                          socks_params,
+                          http_proxy_params,
+                          ProxyServer::SCHEME_DIRECT,
+                          test_host_port_pair,
+                          ssl_config,
+                          0,
+                          false,
+                          false));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 ssl_params, MEDIUM, CompletionCallback(),
+                                 http_session->GetSSLSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+  EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
+  EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
+  EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com"));
+  EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
+}
+
+TEST_F(SpdySessionSpdy3Test, CloseTwoStalledCreateStream) {
+  // TODO(rtenneti): Define a helper class/methods and move the common code in
+  // this file.
+  MockConnect connect_data(SYNCHRONOUS, OK);
+
+  SettingsMap new_settings;
+  const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
+  const uint32 max_concurrent_streams = 1;
+  new_settings[kSpdySettingsIds1] =
+      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
+
+  scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+  scoped_ptr<SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+  scoped_ptr<SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
+  MockWrite writes[] = {
+    CreateMockWrite(*req1, 1),
+    CreateMockWrite(*req2, 4),
+    CreateMockWrite(*req3, 7),
+  };
+
+  // Set up the socket so we read a SETTINGS frame that sets max concurrent
+  // streams to 1.
+  scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
+
+  scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
+
+  scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, true));
+
+  scoped_ptr<SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdyFrame> body3(ConstructSpdyBodyFrame(5, true));
+
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame),
+    CreateMockRead(*resp1, 2),
+    CreateMockRead(*body1, 3),
+    CreateMockRead(*resp2, 5),
+    CreateMockRead(*body2, 6),
+    CreateMockRead(*resp3, 8),
+    CreateMockRead(*body3, 9),
+    MockRead(ASYNC, 0, 10)  // EOF
+  };
+
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  DeterministicSocketData data(reads, arraysize(reads),
+                               writes, arraysize(writes));
+  data.set_connect_data(connect_data);
+  session_deps.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                LOWEST,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params, LOWEST, CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  // Read the settings frame.
+  data.RunFor(1);
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  EXPECT_EQ(OK, session->CreateStream(url1,
+                                      LOWEST,
+                                      &spdy_stream1,
+                                      BoundNetLog(),
+                                      callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  EXPECT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url2,
+                                  LOWEST,
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback2.callback()));
+
+  scoped_refptr<SpdyStream> spdy_stream3;
+  TestCompletionCallback callback3;
+  GURL url3("http://www.google.com");
+  EXPECT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url3,
+                                  LOWEST,
+                                  &spdy_stream3,
+                                  BoundNetLog(),
+                                  callback3.callback()));
+
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)[":method"] = "GET";
+  (*headers)[":scheme"] = url1.scheme();
+  (*headers)[":host"] = url1.host();
+  (*headers)[":path"] = url1.path();
+  (*headers)[":version"] = "HTTP/1.1";
+  scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock);
+  *headers2 = *headers;
+  scoped_ptr<SpdyHeaderBlock> headers3(new SpdyHeaderBlock);
+  *headers3 = *headers;
+
+  spdy_stream1->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(spdy_stream1->HasUrl());
+  spdy_stream1->SendRequest(false);
+
+  // Run until 1st stream is closed.
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+  data.RunFor(3);
+  EXPECT_EQ(1u, spdy_stream1->stream_id());
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+
+  EXPECT_TRUE(spdy_stream2.get() != NULL);
+  spdy_stream2->set_spdy_headers(headers2.Pass());
+  EXPECT_TRUE(spdy_stream2->HasUrl());
+  spdy_stream2->SendRequest(false);
+
+  // Run until 2nd stream is closed.
+  EXPECT_EQ(0u, spdy_stream2->stream_id());
+  data.RunFor(3);
+  EXPECT_EQ(3u, spdy_stream2->stream_id());
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+
+  EXPECT_TRUE(spdy_stream3.get() != NULL);
+  spdy_stream3->set_spdy_headers(headers3.Pass());
+  EXPECT_TRUE(spdy_stream3->HasUrl());
+  spdy_stream3->SendRequest(false);
+
+  EXPECT_EQ(0u, spdy_stream3->stream_id());
+  data.RunFor(4);
+  EXPECT_EQ(5u, spdy_stream3->stream_id());
+  EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+}
+
+TEST_F(SpdySessionSpdy3Test, CancelTwoStalledCreateStream) {
+  SpdySessionDependencies session_deps;
+  session_deps.host_resolver->set_synchronous_mode(true);
+
+  MockRead reads[] = {
+    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
+  };
+
+  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+
+  data.set_connect_data(connect_data);
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  scoped_refptr<HttpNetworkSession> http_session(
+      SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+  const std::string kTestHost("www.foo.com");
+  const int kTestPort = 80;
+  HostPortPair test_host_port_pair(kTestHost, kTestPort);
+  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
+
+  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
+
+  // Initialize the SpdySetting with 1 max concurrent streams.
+  spdy_session_pool->http_server_properties()->SetSpdySetting(
+      test_host_port_pair,
+      SETTINGS_MAX_CONCURRENT_STREAMS,
+      SETTINGS_FLAG_PLEASE_PERSIST,
+      1);
+
+  // Create a session.
+  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
+  scoped_refptr<SpdySession> session =
+      spdy_session_pool->Get(pair, BoundNetLog());
+  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
+
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(test_host_port_pair,
+                                LOWEST,
+                                false,
+                                false,
+                                OnHostResolutionCallback()));
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+                                 transport_params,
+                                 LOWEST,
+                                 CompletionCallback(),
+                                 http_session->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
+
+  scoped_refptr<SpdyStream> spdy_stream1;
+  TestCompletionCallback callback1;
+  GURL url1("http://www.google.com");
+  ASSERT_EQ(OK,
+            session->CreateStream(url1,
+                                  LOWEST,
+                                  &spdy_stream1,
+                                  BoundNetLog(),
+                                  callback1.callback()));
+  EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+  scoped_refptr<SpdyStream> spdy_stream2;
+  TestCompletionCallback callback2;
+  GURL url2("http://www.google.com");
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url2,
+                                  LOWEST,
+                                  &spdy_stream2,
+                                  BoundNetLog(),
+                                  callback2.callback()));
+
+  scoped_refptr<SpdyStream> spdy_stream3;
+  TestCompletionCallback callback3;
+  GURL url3("http://www.google.com");
+  ASSERT_EQ(ERR_IO_PENDING,
+            session->CreateStream(url3,
+                                  LOWEST,
+                                  &spdy_stream3,
+                                  BoundNetLog(),
+                                  callback3.callback()));
+
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
+
+  // Cancel the first stream, this will allow the second stream to be created.
+  EXPECT_TRUE(spdy_stream1.get() != NULL);
+  spdy_stream1->Cancel();
+  spdy_stream1 = NULL;
+  session->CancelPendingCreateStreams(&spdy_stream1);
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+
+  // Cancel the second stream, this will allow the third stream to be created.
+  EXPECT_TRUE(spdy_stream2.get() != NULL);
+  spdy_stream2->Cancel();
+  spdy_stream2 = NULL;
+  session->CancelPendingCreateStreams(&spdy_stream2);
+  EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+
+  // Cancel the third stream.
+  EXPECT_TRUE(spdy_stream3.get() != NULL);
+  spdy_stream3->Cancel();
+  spdy_stream3 = NULL;
+  session->CancelPendingCreateStreams(&spdy_stream3);
+  EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
+  EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_stream.cc b/src/net/spdy/spdy_stream.cc
new file mode 100644
index 0000000..aeb370e
--- /dev/null
+++ b/src/net/spdy/spdy_stream.cc
@@ -0,0 +1,867 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_stream.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/stringprintf.h"
+#include "base/values.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+
+namespace net {
+
+namespace {
+
+Value* NetLogSpdyStreamErrorCallback(SpdyStreamId stream_id,
+                                     int status,
+                                     const std::string* description,
+                                     NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("stream_id", static_cast<int>(stream_id));
+  dict->SetInteger("status", status);
+  dict->SetString("description", *description);
+  return dict;
+}
+
+Value* NetLogSpdyStreamWindowUpdateCallback(SpdyStreamId stream_id,
+                                            int32 delta,
+                                            int32 window_size,
+                                            NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("stream_id", stream_id);
+  dict->SetInteger("delta", delta);
+  dict->SetInteger("window_size", window_size);
+  return dict;
+}
+
+bool ContainsUpperAscii(const std::string& str) {
+  for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) {
+    if (*i >= 'A' && *i <= 'Z') {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace
+
+SpdyStream::SpdyStream(SpdySession* session,
+                       bool pushed,
+                       const BoundNetLog& net_log)
+    : continue_buffering_data_(true),
+      stream_id_(0),
+      priority_(HIGHEST),
+      slot_(0),
+      stalled_by_flow_control_(false),
+      send_window_size_(kSpdyStreamInitialWindowSize),
+      recv_window_size_(kSpdyStreamInitialWindowSize),
+      unacked_recv_window_bytes_(0),
+      pushed_(pushed),
+      response_received_(false),
+      session_(session),
+      delegate_(NULL),
+      request_time_(base::Time::Now()),
+      response_(new SpdyHeaderBlock),
+      io_state_(STATE_NONE),
+      response_status_(OK),
+      cancelled_(false),
+      has_upload_data_(false),
+      net_log_(net_log),
+      send_bytes_(0),
+      recv_bytes_(0),
+      domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE),
+      domain_bound_cert_request_handle_(NULL) {
+}
+
+class SpdyStream::SpdyStreamIOBufferProducer
+    : public SpdySession::SpdyIOBufferProducer {
+ public:
+  SpdyStreamIOBufferProducer(SpdyStream* stream) : stream_(stream) {}
+
+  // SpdyFrameProducer
+  virtual RequestPriority GetPriority() const OVERRIDE {
+    return stream_->priority();
+  }
+
+  virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) OVERRIDE {
+    if (stream_->cancelled())
+      return NULL;
+    if (stream_->stream_id() == 0)
+      SpdySession::SpdyIOBufferProducer::ActivateStream(session, stream_);
+    frame_.reset(stream_->ProduceNextFrame());
+    return frame_ == NULL ? NULL :
+        SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
+            frame_.get(), GetPriority(), stream_);
+  }
+
+ private:
+  scoped_refptr<SpdyStream> stream_;
+  scoped_ptr<SpdyFrame> frame_;
+};
+
+void SpdyStream::SetHasWriteAvailable() {
+  session_->SetStreamHasWriteAvailable(this,
+                                       new SpdyStreamIOBufferProducer(this));
+}
+
+SpdyFrame* SpdyStream::ProduceNextFrame() {
+  if (io_state_ == STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE) {
+    CHECK(request_.get());
+    CHECK_GT(stream_id_, 0u);
+
+    std::string origin = GetUrl().GetOrigin().spec();
+    DCHECK(origin[origin.length() - 1] == '/');
+    origin.erase(origin.length() - 1);  // Trim trailing slash.
+    SpdyCredentialControlFrame* frame = session_->CreateCredentialFrame(
+        origin, domain_bound_cert_type_, domain_bound_private_key_,
+        domain_bound_cert_, priority_);
+    return frame;
+  } else if (io_state_ == STATE_SEND_HEADERS_COMPLETE) {
+    CHECK(request_.get());
+    CHECK_GT(stream_id_, 0u);
+
+    SpdyControlFlags flags =
+        has_upload_data_ ? CONTROL_FLAG_NONE : CONTROL_FLAG_FIN;
+    SpdySynStreamControlFrame* frame = session_->CreateSynStream(
+        stream_id_, priority_, slot_, flags, *request_);
+    send_time_ = base::TimeTicks::Now();
+    return frame;
+  } else {
+    CHECK(!cancelled());
+    // We must need to write stream data.
+    // Until the headers have been completely sent, we can not be sure
+    // that our stream_id is correct.
+    DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
+    DCHECK_GT(stream_id_, 0u);
+    DCHECK(!pending_frames_.empty());
+
+    PendingFrame frame = pending_frames_.front();
+    pending_frames_.pop_front();
+
+    waiting_completions_.push_back(frame.type);
+
+    if (frame.type == TYPE_DATA) {
+      // Send queued data frame.
+      return frame.data_frame;
+    } else {
+      DCHECK(frame.type == TYPE_HEADERS);
+      // Create actual HEADERS frame just in time because it depends on
+      // compression context and should not be reordered after the creation.
+      SpdyFrame* header_frame = session_->CreateHeadersFrame(
+          stream_id_, *frame.header_block, SpdyControlFlags());
+      delete frame.header_block;
+      return header_frame;
+    }
+  }
+  NOTREACHED();
+}
+
+SpdyStream::~SpdyStream() {
+  UpdateHistograms();
+  while (!pending_frames_.empty()) {
+    PendingFrame frame = pending_frames_.back();
+    pending_frames_.pop_back();
+    if (frame.type == TYPE_DATA)
+      delete frame.data_frame;
+    else
+      delete frame.header_block;
+  }
+}
+
+void SpdyStream::SetDelegate(Delegate* delegate) {
+  CHECK(delegate);
+  delegate_ = delegate;
+
+  if (pushed_) {
+    CHECK(response_received());
+    MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(&SpdyStream::PushedStreamReplayData, this));
+  } else {
+    continue_buffering_data_ = false;
+  }
+}
+
+void SpdyStream::PushedStreamReplayData() {
+  if (cancelled_ || !delegate_)
+    return;
+
+  continue_buffering_data_ = false;
+
+  int rv = delegate_->OnResponseReceived(*response_, response_time_, OK);
+  if (rv == ERR_INCOMPLETE_SPDY_HEADERS) {
+    // We don't have complete headers.  Assume we're waiting for another
+    // HEADERS frame.  Since we don't have headers, we had better not have
+    // any pending data frames.
+    if (pending_buffers_.size() != 0U) {
+      LogStreamError(ERR_SPDY_PROTOCOL_ERROR,
+                     "HEADERS incomplete headers, but pending data frames.");
+      session_->CloseStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR);
+    }
+    return;
+  }
+
+  std::vector<scoped_refptr<IOBufferWithSize> > buffers;
+  buffers.swap(pending_buffers_);
+  for (size_t i = 0; i < buffers.size(); ++i) {
+    // It is always possible that a callback to the delegate results in
+    // the delegate no longer being available.
+    if (!delegate_)
+      break;
+    if (buffers[i]) {
+      delegate_->OnDataReceived(buffers[i]->data(), buffers[i]->size());
+    } else {
+      delegate_->OnDataReceived(NULL, 0);
+      session_->CloseStream(stream_id_, net::OK);
+      // Note: |this| may be deleted after calling CloseStream.
+      DCHECK_EQ(buffers.size() - 1, i);
+    }
+  }
+}
+
+void SpdyStream::DetachDelegate() {
+  delegate_ = NULL;
+  if (!closed())
+    Cancel();
+}
+
+const SpdyHeaderBlock& SpdyStream::spdy_headers() const {
+  DCHECK(request_ != NULL);
+  return *request_.get();
+}
+
+void SpdyStream::set_spdy_headers(scoped_ptr<SpdyHeaderBlock> headers) {
+  request_.reset(headers.release());
+}
+
+void SpdyStream::set_initial_recv_window_size(int32 window_size) {
+  session_->set_initial_recv_window_size(window_size);
+}
+
+void SpdyStream::PossiblyResumeIfStalled() {
+  if (send_window_size_ > 0 && stalled_by_flow_control_) {
+    stalled_by_flow_control_ = false;
+    io_state_ = STATE_SEND_BODY;
+    DoLoop(OK);
+  }
+}
+
+void SpdyStream::AdjustSendWindowSize(int32 delta_window_size) {
+  send_window_size_ += delta_window_size;
+  PossiblyResumeIfStalled();
+}
+
+void SpdyStream::IncreaseSendWindowSize(int32 delta_window_size) {
+  DCHECK(session_->is_flow_control_enabled());
+  DCHECK_GE(delta_window_size, 1);
+
+  // Ignore late WINDOW_UPDATEs.
+  if (closed())
+    return;
+
+  int32 new_window_size = send_window_size_ + delta_window_size;
+
+  // It's valid for send_window_size_ to become negative (via an incoming
+  // SETTINGS), in which case incoming WINDOW_UPDATEs will eventually make
+  // it positive; however, if send_window_size_ is positive and incoming
+  // WINDOW_UPDATE makes it negative, we have an overflow.
+  if (send_window_size_ > 0 && new_window_size < 0) {
+    std::string desc = base::StringPrintf(
+        "Received WINDOW_UPDATE [delta: %d] for stream %d overflows "
+        "send_window_size_ [current: %d]", delta_window_size, stream_id_,
+        send_window_size_);
+    session_->ResetStream(stream_id_, FLOW_CONTROL_ERROR, desc);
+    return;
+  }
+
+  send_window_size_ = new_window_size;
+
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW,
+      base::Bind(&NetLogSpdyStreamWindowUpdateCallback,
+                 stream_id_, delta_window_size, send_window_size_));
+
+  PossiblyResumeIfStalled();
+}
+
+void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) {
+  // we only call this method when sending a frame, therefore
+  // |delta_window_size| should be within the valid frame size range.
+  DCHECK(session_->is_flow_control_enabled());
+  DCHECK_GE(delta_window_size, 1);
+  DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize);
+
+  // |send_window_size_| should have been at least |delta_window_size| for
+  // this call to happen.
+  DCHECK_GE(send_window_size_, delta_window_size);
+
+  send_window_size_ -= delta_window_size;
+
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW,
+      base::Bind(&NetLogSpdyStreamWindowUpdateCallback,
+                 stream_id_, -delta_window_size, send_window_size_));
+}
+
+void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) {
+  DCHECK_GE(delta_window_size, 1);
+  // By the time a read is isued, stream may become inactive.
+  if (!session_->IsStreamActive(stream_id_))
+    return;
+
+  if (!session_->is_flow_control_enabled())
+    return;
+
+  int32 new_window_size = recv_window_size_ + delta_window_size;
+  if (recv_window_size_ > 0)
+    DCHECK(new_window_size > 0);
+
+  recv_window_size_ = new_window_size;
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW,
+      base::Bind(&NetLogSpdyStreamWindowUpdateCallback,
+                 stream_id_, delta_window_size, recv_window_size_));
+
+  unacked_recv_window_bytes_ += delta_window_size;
+  if (unacked_recv_window_bytes_ > session_->initial_recv_window_size() / 2) {
+    session_->SendWindowUpdate(stream_id_, unacked_recv_window_bytes_);
+    unacked_recv_window_bytes_ = 0;
+  }
+}
+
+void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) {
+  DCHECK_GE(delta_window_size, 1);
+
+  if (!session_->is_flow_control_enabled())
+    return;
+
+  recv_window_size_ -= delta_window_size;
+  net_log_.AddEvent(
+      NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW,
+      base::Bind(&NetLogSpdyStreamWindowUpdateCallback,
+                 stream_id_, -delta_window_size, recv_window_size_));
+
+  // Since we never decrease the initial window size, we should never hit
+  // a negative |recv_window_size_|, if we do, it's a client side bug, so we use
+  // PROTOCOL_ERROR for lack of a better error code.
+  if (recv_window_size_ < 0) {
+    session_->ResetStream(stream_id_, PROTOCOL_ERROR,
+                          "Negative recv window size");
+    NOTREACHED();
+  }
+}
+
+int SpdyStream::GetPeerAddress(IPEndPoint* address) const {
+  return session_->GetPeerAddress(address);
+}
+
+int SpdyStream::GetLocalAddress(IPEndPoint* address) const {
+  return session_->GetLocalAddress(address);
+}
+
+bool SpdyStream::WasEverUsed() const {
+  return session_->WasEverUsed();
+}
+
+base::Time SpdyStream::GetRequestTime() const {
+  return request_time_;
+}
+
+void SpdyStream::SetRequestTime(base::Time t) {
+  request_time_ = t;
+}
+
+int SpdyStream::OnResponseReceived(const SpdyHeaderBlock& response) {
+  int rv = OK;
+
+  metrics_.StartStream();
+
+  DCHECK(response_->empty());
+  *response_ = response;  // TODO(ukai): avoid copy.
+
+  recv_first_byte_time_ = base::TimeTicks::Now();
+  response_time_ = base::Time::Now();
+
+  // If we receive a response before we are in STATE_WAITING_FOR_RESPONSE, then
+  // the server has sent the SYN_REPLY too early.
+  if (!pushed_ && io_state_ != STATE_WAITING_FOR_RESPONSE)
+    return ERR_SPDY_PROTOCOL_ERROR;
+  if (pushed_)
+    CHECK(io_state_ == STATE_NONE);
+  io_state_ = STATE_OPEN;
+
+  // Append all the headers into the response header block.
+  for (SpdyHeaderBlock::const_iterator it = response.begin();
+       it != response.end(); ++it) {
+    // Disallow uppercase headers.
+    if (ContainsUpperAscii(it->first)) {
+      session_->ResetStream(stream_id_, PROTOCOL_ERROR,
+                            "Upper case characters in header: " + it->first);
+      response_status_ = ERR_SPDY_PROTOCOL_ERROR;
+      return ERR_SPDY_PROTOCOL_ERROR;
+    }
+  }
+
+  if ((*response_).find("transfer-encoding") != (*response_).end()) {
+    session_->ResetStream(stream_id_, PROTOCOL_ERROR,
+                         "Received transfer-encoding header");
+    return ERR_SPDY_PROTOCOL_ERROR;
+  }
+
+  if (delegate_)
+    rv = delegate_->OnResponseReceived(*response_, response_time_, rv);
+  // If delegate_ is not yet attached, we'll call OnResponseReceived after the
+  // delegate gets attached to the stream.
+
+  return rv;
+}
+
+int SpdyStream::OnHeaders(const SpdyHeaderBlock& headers) {
+  DCHECK(!response_->empty());
+
+  // Append all the headers into the response header block.
+  for (SpdyHeaderBlock::const_iterator it = headers.begin();
+      it != headers.end(); ++it) {
+    // Disallow duplicate headers.  This is just to be conservative.
+    if ((*response_).find(it->first) != (*response_).end()) {
+      LogStreamError(ERR_SPDY_PROTOCOL_ERROR, "HEADERS duplicate header");
+      response_status_ = ERR_SPDY_PROTOCOL_ERROR;
+      return ERR_SPDY_PROTOCOL_ERROR;
+    }
+
+    // Disallow uppercase headers.
+    if (ContainsUpperAscii(it->first)) {
+      session_->ResetStream(stream_id_, PROTOCOL_ERROR,
+                            "Upper case characters in header: " + it->first);
+      response_status_ = ERR_SPDY_PROTOCOL_ERROR;
+      return ERR_SPDY_PROTOCOL_ERROR;
+    }
+
+    (*response_)[it->first] = it->second;
+  }
+
+  if ((*response_).find("transfer-encoding") != (*response_).end()) {
+    session_->ResetStream(stream_id_, PROTOCOL_ERROR,
+                         "Received transfer-encoding header");
+    return ERR_SPDY_PROTOCOL_ERROR;
+  }
+
+  int rv = OK;
+  if (delegate_) {
+    rv = delegate_->OnResponseReceived(*response_, response_time_, rv);
+    // ERR_INCOMPLETE_SPDY_HEADERS means that we are waiting for more
+    // headers before the response header block is complete.
+    if (rv == ERR_INCOMPLETE_SPDY_HEADERS)
+      rv = OK;
+  }
+  return rv;
+}
+
+void SpdyStream::OnDataReceived(const char* data, int length) {
+  DCHECK_GE(length, 0);
+
+  // If we don't have a response, then the SYN_REPLY did not come through.
+  // We cannot pass data up to the caller unless the reply headers have been
+  // received.
+  if (!response_received()) {
+    LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED, "Didn't receive a response.");
+    session_->CloseStream(stream_id_, ERR_SYN_REPLY_NOT_RECEIVED);
+    return;
+  }
+
+  if (!delegate_ || continue_buffering_data_) {
+    // It should be valid for this to happen in the server push case.
+    // We'll return received data when delegate gets attached to the stream.
+    if (length > 0) {
+      IOBufferWithSize* buf = new IOBufferWithSize(length);
+      memcpy(buf->data(), data, length);
+      pending_buffers_.push_back(make_scoped_refptr(buf));
+    } else {
+      pending_buffers_.push_back(NULL);
+      metrics_.StopStream();
+      // Note: we leave the stream open in the session until the stream
+      //       is claimed.
+    }
+    return;
+  }
+
+  CHECK(!closed());
+
+  // A zero-length read means that the stream is being closed.
+  if (!length) {
+    metrics_.StopStream();
+    session_->CloseStream(stream_id_, net::OK);
+    // Note: |this| may be deleted after calling CloseStream.
+    return;
+  }
+
+  DecreaseRecvWindowSize(length);
+
+  // Track our bandwidth.
+  metrics_.RecordBytes(length);
+  recv_bytes_ += length;
+  recv_last_byte_time_ = base::TimeTicks::Now();
+
+  if (!delegate_) {
+    // It should be valid for this to happen in the server push case.
+    // We'll return received data when delegate gets attached to the stream.
+    IOBufferWithSize* buf = new IOBufferWithSize(length);
+    memcpy(buf->data(), data, length);
+    pending_buffers_.push_back(make_scoped_refptr(buf));
+    return;
+  }
+
+  if (delegate_->OnDataReceived(data, length) != net::OK) {
+    // |delegate_| rejected the data.
+    LogStreamError(ERR_SPDY_PROTOCOL_ERROR, "Delegate rejected the data");
+    session_->CloseStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR);
+    return;
+  }
+}
+
+// This function is only called when an entire frame is written.
+void SpdyStream::OnWriteComplete(int bytes) {
+  DCHECK_LE(0, bytes);
+  send_bytes_ += bytes;
+  if (cancelled() || closed())
+    return;
+  DoLoop(bytes);
+}
+
+int SpdyStream::GetProtocolVersion() const {
+  return session_->GetProtocolVersion();
+}
+
+void SpdyStream::LogStreamError(int status, const std::string& description) {
+  net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ERROR,
+                    base::Bind(&NetLogSpdyStreamErrorCallback,
+                               stream_id_, status, &description));
+}
+
+void SpdyStream::OnClose(int status) {
+  io_state_ = STATE_DONE;
+  response_status_ = status;
+  Delegate* delegate = delegate_;
+  delegate_ = NULL;
+  if (delegate)
+    delegate->OnClose(status);
+}
+
+void SpdyStream::Cancel() {
+  if (cancelled())
+    return;
+
+  cancelled_ = true;
+  if (session_->IsStreamActive(stream_id_))
+    session_->ResetStream(stream_id_, CANCEL, "");
+  else if (stream_id_ == 0)
+    session_->CloseCreatedStream(this, CANCEL);
+}
+
+void SpdyStream::Close() {
+  if (stream_id_ != 0)
+    session_->CloseStream(stream_id_, net::OK);
+  else
+    session_->CloseCreatedStream(this, OK);
+}
+
+int SpdyStream::SendRequest(bool has_upload_data) {
+  // Pushed streams do not send any data, and should always be in STATE_OPEN or
+  // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push
+  // behavior.
+  has_upload_data_ = has_upload_data;
+  if (pushed_) {
+    send_time_ = base::TimeTicks::Now();
+    DCHECK(!has_upload_data_);
+    DCHECK(response_received());
+    return ERR_IO_PENDING;
+  }
+  CHECK_EQ(STATE_NONE, io_state_);
+  io_state_ = STATE_GET_DOMAIN_BOUND_CERT;
+  return DoLoop(OK);
+}
+
+int SpdyStream::WriteHeaders(SpdyHeaderBlock* headers) {
+  // Until the first headers by SYN_STREAM have been completely sent, we can
+  // not be sure that our stream_id is correct.
+  DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
+  CHECK_GT(stream_id_, 0u);
+
+  PendingFrame frame;
+  frame.type = TYPE_HEADERS;
+  frame.header_block = headers;
+  pending_frames_.push_back(frame);
+
+  SetHasWriteAvailable();
+  return ERR_IO_PENDING;
+}
+
+int SpdyStream::WriteStreamData(IOBuffer* data,
+                                int length,
+                                SpdyDataFlags flags) {
+  // Until the headers have been completely sent, we can not be sure
+  // that our stream_id is correct.
+  DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
+  CHECK_GT(stream_id_, 0u);
+
+  SpdyDataFrame* data_frame = session_->CreateDataFrame(
+      stream_id_, data, length, flags);
+  if (!data_frame)
+    return ERR_IO_PENDING;
+
+  PendingFrame frame;
+  frame.type = TYPE_DATA;
+  frame.data_frame = data_frame;
+  pending_frames_.push_back(frame);
+
+  SetHasWriteAvailable();
+  return ERR_IO_PENDING;
+}
+
+bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info,
+                            bool* was_npn_negotiated,
+                            NextProto* protocol_negotiated) {
+  return session_->GetSSLInfo(
+      ssl_info, was_npn_negotiated, protocol_negotiated);
+}
+
+bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {
+  return session_->GetSSLCertRequestInfo(cert_request_info);
+}
+
+bool SpdyStream::HasUrl() const {
+  if (pushed_)
+    return response_received();
+  return request_.get() != NULL;
+}
+
+GURL SpdyStream::GetUrl() const {
+  DCHECK(HasUrl());
+
+  const SpdyHeaderBlock& headers = (pushed_) ? *response_ : *request_;
+  return GetUrlFromHeaderBlock(headers, GetProtocolVersion(), pushed_);
+}
+
+void SpdyStream::OnGetDomainBoundCertComplete(int result) {
+  DCHECK_EQ(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE, io_state_);
+  DoLoop(result);
+}
+
+int SpdyStream::DoLoop(int result) {
+  do {
+    State state = io_state_;
+    io_state_ = STATE_NONE;
+    switch (state) {
+      // State machine 1: Send headers and body.
+      case STATE_GET_DOMAIN_BOUND_CERT:
+        CHECK_EQ(OK, result);
+        result = DoGetDomainBoundCert();
+        break;
+      case STATE_GET_DOMAIN_BOUND_CERT_COMPLETE:
+        result = DoGetDomainBoundCertComplete(result);
+        break;
+      case STATE_SEND_DOMAIN_BOUND_CERT:
+        CHECK_EQ(OK, result);
+        result = DoSendDomainBoundCert();
+        break;
+      case STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE:
+        result = DoSendDomainBoundCertComplete(result);
+        break;
+      case STATE_SEND_HEADERS:
+        CHECK_EQ(OK, result);
+        result = DoSendHeaders();
+        break;
+      case STATE_SEND_HEADERS_COMPLETE:
+        result = DoSendHeadersComplete(result);
+        break;
+      case STATE_SEND_BODY:
+        CHECK_EQ(OK, result);
+        result = DoSendBody();
+        break;
+      case STATE_SEND_BODY_COMPLETE:
+        result = DoSendBodyComplete(result);
+        break;
+      // This is an intermediary waiting state. This state is reached when all
+      // data has been sent, but no data has been received.
+      case STATE_WAITING_FOR_RESPONSE:
+        io_state_ = STATE_WAITING_FOR_RESPONSE;
+        result = ERR_IO_PENDING;
+        break;
+      // State machine 2: connection is established.
+      // In STATE_OPEN, OnResponseReceived has already been called.
+      // OnDataReceived, OnClose and OnWriteCompelte can be called.
+      // Only OnWriteComplete calls DoLoop(().
+      //
+      // For HTTP streams, no data is sent from the client while in the OPEN
+      // state, so OnWriteComplete is never called here.  The HTTP body is
+      // handled in the OnDataReceived callback, which does not call into
+      // DoLoop.
+      //
+      // For WebSocket streams, which are bi-directional, we'll send and
+      // receive data once the connection is established.  Received data is
+      // handled in OnDataReceived.  Sent data is handled in OnWriteComplete,
+      // which calls DoOpen().
+      case STATE_OPEN:
+        result = DoOpen(result);
+        break;
+
+      case STATE_DONE:
+        DCHECK(result != ERR_IO_PENDING);
+        break;
+      default:
+        NOTREACHED() << io_state_;
+        break;
+    }
+  } while (result != ERR_IO_PENDING && io_state_ != STATE_NONE &&
+           io_state_ != STATE_OPEN);
+
+  return result;
+}
+
+int SpdyStream::DoGetDomainBoundCert() {
+  CHECK(request_.get());
+  if (!session_->NeedsCredentials()) {
+    // Proceed directly to sending headers
+    io_state_ = STATE_SEND_HEADERS;
+    return OK;
+  }
+
+  slot_ = session_->credential_state()->FindCredentialSlot(GetUrl());
+  if (slot_ != SpdyCredentialState::kNoEntry) {
+    // Proceed directly to sending headers
+    io_state_ = STATE_SEND_HEADERS;
+    return OK;
+  }
+
+  io_state_ = STATE_GET_DOMAIN_BOUND_CERT_COMPLETE;
+  ServerBoundCertService* sbc_service = session_->GetServerBoundCertService();
+  DCHECK(sbc_service != NULL);
+  std::vector<uint8> requested_cert_types;
+  requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN);
+  int rv = sbc_service->GetDomainBoundCert(
+      GetUrl().GetOrigin().spec(), requested_cert_types,
+      &domain_bound_cert_type_, &domain_bound_private_key_, &domain_bound_cert_,
+      base::Bind(&SpdyStream::OnGetDomainBoundCertComplete,
+                 base::Unretained(this)),
+      &domain_bound_cert_request_handle_);
+  return rv;
+}
+
+int SpdyStream::DoGetDomainBoundCertComplete(int result) {
+  if (result != OK)
+    return result;
+
+  io_state_ = STATE_SEND_DOMAIN_BOUND_CERT;
+  slot_ =  session_->credential_state()->SetHasCredential(GetUrl());
+  return OK;
+}
+
+int SpdyStream::DoSendDomainBoundCert() {
+  io_state_ = STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE;
+  CHECK(request_.get());
+  SetHasWriteAvailable();
+  return ERR_IO_PENDING;
+}
+
+int SpdyStream::DoSendDomainBoundCertComplete(int result) {
+  if (result < 0)
+    return result;
+
+  io_state_ = STATE_SEND_HEADERS;
+  return OK;
+}
+
+int SpdyStream::DoSendHeaders() {
+  CHECK(!cancelled_);
+
+  SetHasWriteAvailable();
+  io_state_ = STATE_SEND_HEADERS_COMPLETE;
+  return ERR_IO_PENDING;
+}
+
+int SpdyStream::DoSendHeadersComplete(int result) {
+  if (result < 0)
+    return result;
+
+  CHECK_GT(result, 0);
+
+  if (!delegate_)
+    return ERR_UNEXPECTED;
+
+  // There is no body, skip that state.
+  if (delegate_->OnSendHeadersComplete(result)) {
+    io_state_ = STATE_WAITING_FOR_RESPONSE;
+    return OK;
+  }
+
+  io_state_ = STATE_SEND_BODY;
+  return OK;
+}
+
+// DoSendBody is called to send the optional body for the request.  This call
+// will also be called as each write of a chunk of the body completes.
+int SpdyStream::DoSendBody() {
+  // If we're already in the STATE_SEND_BODY state, then we've already
+  // sent a portion of the body.  In that case, we need to first consume
+  // the bytes written in the body stream.  Note that the bytes written is
+  // the number of bytes in the frame that were written, only consume the
+  // data portion, of course.
+  io_state_ = STATE_SEND_BODY_COMPLETE;
+  if (!delegate_)
+    return ERR_UNEXPECTED;
+  return delegate_->OnSendBody();
+}
+
+int SpdyStream::DoSendBodyComplete(int result) {
+  if (result < 0)
+    return result;
+
+  if (!delegate_)
+    return ERR_UNEXPECTED;
+
+  bool eof = false;
+  result = delegate_->OnSendBodyComplete(result, &eof);
+  if (!eof)
+    io_state_ = STATE_SEND_BODY;
+  else
+    io_state_ = STATE_WAITING_FOR_RESPONSE;
+
+  return result;
+}
+
+int SpdyStream::DoOpen(int result) {
+  if (delegate_) {
+    FrameType type = waiting_completions_.front();
+    waiting_completions_.pop_front();
+    if (type == TYPE_DATA) {
+      delegate_->OnDataSent(result);
+    } else {
+      DCHECK(type == TYPE_HEADERS);
+      delegate_->OnHeadersSent();
+    }
+  }
+  io_state_ = STATE_OPEN;
+  return result;
+}
+
+void SpdyStream::UpdateHistograms() {
+  // We need all timers to be filled in, otherwise metrics can be bogus.
+  if (send_time_.is_null() || recv_first_byte_time_.is_null() ||
+      recv_last_byte_time_.is_null())
+    return;
+
+  UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte",
+      recv_first_byte_time_ - send_time_);
+  UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime",
+      recv_last_byte_time_ - recv_first_byte_time_);
+  UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime",
+      recv_last_byte_time_ - send_time_);
+
+  UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_);
+  UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_stream.h b/src/net/spdy/spdy_stream.h
new file mode 100644
index 0000000..5621564
--- /dev/null
+++ b/src/net/spdy/spdy_stream.h
@@ -0,0 +1,410 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_STREAM_H_
+#define NET_SPDY_SPDY_STREAM_H_
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/bandwidth_metrics.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+#include "net/base/request_priority.h"
+#include "net/base/server_bound_cert_service.h"
+#include "net/base/ssl_client_cert_type.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/spdy/spdy_framer.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session.h"
+
+namespace net {
+
+class AddressList;
+class IPEndPoint;
+class SSLCertRequestInfo;
+class SSLInfo;
+
+// The SpdyStream is used by the SpdySession to represent each stream known
+// on the SpdySession.  This class provides interfaces for SpdySession to use.
+// Streams can be created either by the client or by the server.  When they
+// are initiated by the client, both the SpdySession and client object (such as
+// a SpdyNetworkTransaction) will maintain a reference to the stream.  When
+// initiated by the server, only the SpdySession will maintain any reference,
+// until such a time as a client object requests a stream for the path.
+class NET_EXPORT_PRIVATE SpdyStream
+    : public base::RefCounted<SpdyStream> {
+ public:
+  // Delegate handles protocol specific behavior of spdy stream.
+  class NET_EXPORT_PRIVATE Delegate {
+   public:
+    Delegate() {}
+
+    // Called when SYN frame has been sent.
+    // Returns true if no more data to be sent after SYN frame.
+    virtual bool OnSendHeadersComplete(int status) = 0;
+
+    // Called when stream is ready to send data.
+    // Returns network error code. OK when it successfully sent data.
+    // ERR_IO_PENDING when performing operation asynchronously.
+    virtual int OnSendBody() = 0;
+
+    // Called when data has been sent. |status| indicates network error
+    // or number of bytes that has been sent. On return, |eof| is set to true
+    // if no more data is available to send in the request body.
+    // Returns network error code. OK when it successfully sent data.
+    virtual int OnSendBodyComplete(int status, bool* eof) = 0;
+
+    // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received.
+    // Normal streams will receive a SYN_REPLY and optional HEADERS frames.
+    // Pushed streams will receive a SYN_STREAM and optional HEADERS frames.
+    // Because a stream may have a SYN_* frame and multiple HEADERS frames,
+    // this callback may be called multiple times.
+    // |status| indicates network error. Returns network error code.
+    virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                   base::Time response_time,
+                                   int status) = 0;
+
+    // Called when a HEADERS frame is sent.
+    virtual void OnHeadersSent() = 0;
+
+    // Called when data is received.
+    // Returns network error code. OK when it successfully receives data.
+    virtual int OnDataReceived(const char* data, int length) = 0;
+
+    // Called when data is sent.
+    virtual void OnDataSent(int length) = 0;
+
+    // Called when SpdyStream is closed.
+    virtual void OnClose(int status) = 0;
+
+   protected:
+    virtual ~Delegate() {}
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(Delegate);
+  };
+
+  // Indicates pending frame type.
+  enum FrameType {
+    TYPE_HEADERS,
+    TYPE_DATA
+  };
+
+  // Structure to contains pending frame information.
+  typedef struct {
+    FrameType type;
+    union {
+      SpdyHeaderBlock* header_block;
+      SpdyDataFrame* data_frame;
+    };
+  } PendingFrame;
+
+  // SpdyStream constructor
+  SpdyStream(SpdySession* session,
+             bool pushed,
+             const BoundNetLog& net_log);
+
+  // Set new |delegate|. |delegate| must not be NULL.
+  // If it already received SYN_REPLY or data, OnResponseReceived() or
+  // OnDataReceived() will be called.
+  void SetDelegate(Delegate* delegate);
+  Delegate* GetDelegate() { return delegate_; }
+
+  // Detach delegate from the stream. It will cancel the stream if it was not
+  // cancelled yet.  It is safe to call multiple times.
+  void DetachDelegate();
+
+  // Is this stream a pushed stream from the server.
+  bool pushed() const { return pushed_; }
+
+  SpdyStreamId stream_id() const { return stream_id_; }
+  void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; }
+
+  bool response_received() const { return response_received_; }
+  void set_response_received() { response_received_ = true; }
+
+  // For pushed streams, we track a path to identify them.
+  const std::string& path() const { return path_; }
+  void set_path(const std::string& path) { path_ = path; }
+
+  RequestPriority priority() const { return priority_; }
+  void set_priority(RequestPriority priority) { priority_ = priority; }
+
+  int32 send_window_size() const { return send_window_size_; }
+  void set_send_window_size(int32 window_size) {
+    send_window_size_ = window_size;
+  }
+
+  int32 recv_window_size() const { return recv_window_size_; }
+  void set_recv_window_size(int32 window_size) {
+    recv_window_size_ = window_size;
+  }
+
+  // Set session_'s initial_recv_window_size. Used by unittests.
+  void set_initial_recv_window_size(int32 window_size);
+
+  bool stalled_by_flow_control() { return stalled_by_flow_control_; }
+
+  void set_stalled_by_flow_control(bool stalled) {
+    stalled_by_flow_control_ = stalled;
+  }
+
+  // Adjusts the |send_window_size_| by |delta_window_size|. |delta_window_size|
+  // is the difference between the SETTINGS_INITIAL_WINDOW_SIZE in SETTINGS
+  // frame and the previous initial_send_window_size.
+  void AdjustSendWindowSize(int32 delta_window_size);
+
+  // Increases |send_window_size_| with delta extracted from a WINDOW_UPDATE
+  // frame; sends a RST_STREAM if delta overflows |send_window_size_| and
+  // removes the stream from the session.
+  void IncreaseSendWindowSize(int32 delta_window_size);
+
+  // Decreases |send_window_size_| by the given number of bytes.
+  void DecreaseSendWindowSize(int32 delta_window_size);
+
+  int GetPeerAddress(IPEndPoint* address) const;
+  int GetLocalAddress(IPEndPoint* address) const;
+
+  // Returns true if the underlying transport socket ever had any reads or
+  // writes.
+  bool WasEverUsed() const;
+
+  // Increases |recv_window_size_| by the given number of bytes, also sends
+  // a WINDOW_UPDATE frame.
+  void IncreaseRecvWindowSize(int32 delta_window_size);
+
+  // Decreases |recv_window_size_| by the given number of bytes, called
+  // whenever data is read.  May also send a RST_STREAM and remove the
+  // stream from the session if the resultant |recv_window_size_| is
+  // negative, since that would be a flow control violation.
+  void DecreaseRecvWindowSize(int32 delta_window_size);
+
+  const BoundNetLog& net_log() const { return net_log_; }
+
+  const SpdyHeaderBlock& spdy_headers() const;
+  void set_spdy_headers(scoped_ptr<SpdyHeaderBlock> headers);
+  base::Time GetRequestTime() const;
+  void SetRequestTime(base::Time t);
+
+  // Called by the SpdySession when a response (e.g. a SYN_STREAM or SYN_REPLY)
+  // has been received for this stream. Returns a status code.
+  int OnResponseReceived(const SpdyHeaderBlock& response);
+
+  // Called by the SpdySession when late-bound headers are received for a
+  // stream. Returns a status code.
+  int OnHeaders(const SpdyHeaderBlock& headers);
+
+  // Called by the SpdySession when response data has been received for this
+  // stream.  This callback may be called multiple times as data arrives
+  // from the network, and will never be called prior to OnResponseReceived.
+  // |buffer| contains the data received.  The stream must copy any data
+  //          from this buffer before returning from this callback.
+  // |length| is the number of bytes received or an error.
+  //         A zero-length count does not indicate end-of-stream.
+  void OnDataReceived(const char* buffer, int bytes);
+
+  // Called by the SpdySession when a write has completed.  This callback
+  // will be called multiple times for each write which completes.  Writes
+  // include the SYN_STREAM write and also DATA frame writes.
+  // |result| is the number of bytes written or a net error code.
+  void OnWriteComplete(int bytes);
+
+  // Called by the SpdySession when the request is finished.  This callback
+  // will always be called at the end of the request and signals to the
+  // stream that the stream has no more network events.  No further callbacks
+  // to the stream will be made after this call.
+  // |status| is an error code or OK.
+  void OnClose(int status);
+
+  // Called by the SpdySession to log stream related errors.
+  void LogStreamError(int status, const std::string& description);
+
+  void Cancel();
+  void Close();
+  bool cancelled() const { return cancelled_; }
+  bool closed() const { return io_state_ == STATE_DONE; }
+  // TODO(satorux): This is only for testing. We should be able to remove
+  // this once crbug.com/113107 is addressed.
+  bool body_sent() const { return io_state_ > STATE_SEND_BODY_COMPLETE; }
+
+  // Interface for Spdy[Http|WebSocket]Stream to use.
+
+  // Sends the request.
+  // For non push stream, it will send SYN_STREAM frame.
+  int SendRequest(bool has_upload_data);
+
+  // Sends a HEADERS frame. SpdyStream owns |headers| and will release it after
+  // the HEADERS frame is actually sent.
+  int WriteHeaders(SpdyHeaderBlock* headers);
+
+  // Sends DATA frame.
+  int WriteStreamData(IOBuffer* data, int length,
+                      SpdyDataFlags flags);
+
+  // Fills SSL info in |ssl_info| and returns true when SSL is in use.
+  bool GetSSLInfo(SSLInfo* ssl_info,
+                  bool* was_npn_negotiated,
+                  NextProto* protocol_negotiated);
+
+  // Fills SSL Certificate Request info |cert_request_info| and returns
+  // true when SSL is in use.
+  bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+
+  bool is_idle() const {
+    return io_state_ == STATE_OPEN || io_state_ == STATE_DONE;
+  }
+
+  int response_status() const { return response_status_; }
+
+  // Returns true if the URL for this stream is known.
+  bool HasUrl() const;
+
+  // Get the URL associated with this stream.  Only valid when has_url() is
+  // true.
+  GURL GetUrl() const;
+
+  int GetProtocolVersion() const;
+
+ private:
+  class SpdyStreamIOBufferProducer;
+
+  enum State {
+    STATE_NONE,
+    STATE_GET_DOMAIN_BOUND_CERT,
+    STATE_GET_DOMAIN_BOUND_CERT_COMPLETE,
+    STATE_SEND_DOMAIN_BOUND_CERT,
+    STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE,
+    STATE_SEND_HEADERS,
+    STATE_SEND_HEADERS_COMPLETE,
+    STATE_SEND_BODY,
+    STATE_SEND_BODY_COMPLETE,
+    STATE_WAITING_FOR_RESPONSE,
+    STATE_OPEN,
+    STATE_DONE
+  };
+
+  friend class base::RefCounted<SpdyStream>;
+
+  virtual ~SpdyStream();
+
+  // If the stream is stalled and if |send_window_size_| is positive, then set
+  // |stalled_by_flow_control_| to false and unstall the stream.
+  void PossiblyResumeIfStalled();
+
+  void OnGetDomainBoundCertComplete(int result);
+
+  // Try to make progress sending/receiving the request/response.
+  int DoLoop(int result);
+
+  // The implementations of each state of the state machine.
+  int DoGetDomainBoundCert();
+  int DoGetDomainBoundCertComplete(int result);
+  int DoSendDomainBoundCert();
+  int DoSendDomainBoundCertComplete(int result);
+  int DoSendHeaders();
+  int DoSendHeadersComplete(int result);
+  int DoSendBody();
+  int DoSendBodyComplete(int result);
+  int DoReadHeaders();
+  int DoReadHeadersComplete(int result);
+  int DoOpen(int result);
+
+  // Update the histograms.  Can safely be called repeatedly, but should only
+  // be called after the stream has completed.
+  void UpdateHistograms();
+
+  // When a server pushed stream is first created, this function is posted on
+  // the MessageLoop to replay all the data that the server has already sent.
+  void PushedStreamReplayData();
+
+  // Informs the SpdySession that this stream has a write available.
+  void SetHasWriteAvailable();
+
+  // Returns a newly created SPDY frame owned by the called that contains
+  // the next frame to be sent by this frame.  May return NULL if this
+  // stream has become stalled on flow control.
+  SpdyFrame* ProduceNextFrame();
+
+  // There is a small period of time between when a server pushed stream is
+  // first created, and the pushed data is replayed. Any data received during
+  // this time should continue to be buffered.
+  bool continue_buffering_data_;
+
+  SpdyStreamId stream_id_;
+  std::string path_;
+  RequestPriority priority_;
+  size_t slot_;
+
+  // Flow control variables.
+  bool stalled_by_flow_control_;
+  int32 send_window_size_;
+  int32 recv_window_size_;
+  int32 unacked_recv_window_bytes_;
+
+  const bool pushed_;
+  ScopedBandwidthMetrics metrics_;
+  bool response_received_;
+
+  scoped_refptr<SpdySession> session_;
+
+  // The transaction should own the delegate.
+  SpdyStream::Delegate* delegate_;
+
+  // The request to send.
+  scoped_ptr<SpdyHeaderBlock> request_;
+
+  // The time at which the request was made that resulted in this response.
+  // For cached responses, this time could be "far" in the past.
+  base::Time request_time_;
+
+  scoped_ptr<SpdyHeaderBlock> response_;
+  base::Time response_time_;
+
+  // An in order list of pending frame data that are going to be sent. HEADERS
+  // frames are queued as SpdyHeaderBlock structures because these must be
+  // compressed just before sending. Data frames are queued as SpdyDataFrame.
+  std::list<PendingFrame> pending_frames_;
+
+  // An in order list of sending frame types. It will be used to know which type
+  // of frame is sent and which callback should be invoked in OnOpen().
+  std::list<FrameType> waiting_completions_;
+
+  State io_state_;
+
+  // Since we buffer the response, we also buffer the response status.
+  // Not valid until the stream is closed.
+  int response_status_;
+
+  bool cancelled_;
+  bool has_upload_data_;
+
+  BoundNetLog net_log_;
+
+  base::TimeTicks send_time_;
+  base::TimeTicks recv_first_byte_time_;
+  base::TimeTicks recv_last_byte_time_;
+  int send_bytes_;
+  int recv_bytes_;
+  // Data received before delegate is attached.
+  std::vector<scoped_refptr<IOBufferWithSize> > pending_buffers_;
+
+  SSLClientCertType domain_bound_cert_type_;
+  std::string domain_bound_private_key_;
+  std::string domain_bound_cert_;
+  ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyStream);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_STREAM_H_
diff --git a/src/net/spdy/spdy_stream_spdy2_unittest.cc b/src/net/spdy/spdy_stream_spdy2_unittest.cc
new file mode 100644
index 0000000..602ff31
--- /dev/null
+++ b/src/net/spdy/spdy_stream_spdy2_unittest.cc
@@ -0,0 +1,462 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/ref_counted.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_log_unittest.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_stream.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_stream_test_util.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "net/spdy/spdy_websocket_test_util_spdy2.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy2;
+
+// TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
+//
+namespace net {
+
+namespace {
+
+SpdyFrame* ConstructSpdyBodyFrame(const char* data, int length) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateDataFrame(1, data, length, DATA_FLAG_NONE);
+}
+
+}  // anonymous namespace
+
+namespace test {
+
+class SpdyStreamSpdy2Test : public testing::Test {
+ protected:
+  SpdyStreamSpdy2Test() {
+  }
+
+  scoped_refptr<SpdySession> CreateSpdySession() {
+    HostPortPair host_port_pair("www.google.com", 80);
+    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+    scoped_refptr<SpdySession> session(
+        session_->spdy_session_pool()->Get(pair, BoundNetLog()));
+    return session;
+  }
+
+  virtual void TearDown() {
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  scoped_refptr<HttpNetworkSession> session_;
+};
+
+TEST_F(SpdyStreamSpdy2Test, SendDataAfterOpen) {
+  SpdySessionDependencies session_deps;
+
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    1,
+    0,
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  static const char* const kGetHeaders[] = {
+    "method",
+    "GET",
+    "scheme",
+    "http",
+    "host",
+    "www.google.com",
+    "url",
+    "/",
+    "version",
+    "HTTP/1.1",
+  };
+  scoped_ptr<SpdyFrame> req(
+      ConstructSpdyPacket(
+          kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> msg(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*msg),
+  };
+  writes[0].sequence_number = 0;
+  writes[1].sequence_number = 2;
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> echo(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*echo),
+    MockRead(ASYNC, 0, 0), // EOF
+  };
+  reads[0].sequence_number = 1;
+  reads[1].sequence_number = 3;
+  reads[2].sequence_number = 4;
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  scoped_refptr<SpdySession> session(CreateSpdySession());
+  const char* kStreamUrl = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  session->InitializeWithSocket(connection.release(), false, OK);
+
+  scoped_refptr<SpdyStream> stream;
+  ASSERT_EQ(
+      OK,
+      session->CreateStream(url, LOWEST, &stream, BoundNetLog(),
+                            CompletionCallback()));
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
+  memcpy(buf->data(), "\0hello!\xff", 8);
+  TestCompletionCallback callback;
+
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(
+          stream.get(), NULL, buf.get(), callback.callback()));
+  stream->SetDelegate(delegate.get());
+
+  EXPECT_FALSE(stream->HasUrl());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url.scheme();
+  (*headers)["host"] = url.host();
+  (*headers)["url"] = url.path();
+  (*headers)["version"] = "HTTP/1.1";
+  stream->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(stream->HasUrl());
+  EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
+
+  EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  EXPECT_TRUE(delegate->send_headers_completed());
+  EXPECT_EQ("200", (*delegate->response())["status"]);
+  EXPECT_EQ("HTTP/1.1", (*delegate->response())["version"]);
+  EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
+  EXPECT_EQ(8, delegate->data_sent());
+  EXPECT_TRUE(delegate->closed());
+}
+
+TEST_F(SpdyStreamSpdy2Test, SendHeaderAndDataAfterOpen) {
+  SpdySessionDependencies session_deps;
+
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+
+  scoped_ptr<SpdyFrame> expected_request(ConstructSpdyWebSocketSynStream(
+      1,
+      "/chat",
+      "server.example.com",
+      "http://example.com"));
+  scoped_ptr<SpdyFrame> expected_headers(ConstructSpdyWebSocketHeadersFrame(
+      1, "6", true));
+  scoped_ptr<SpdyFrame> expected_message(ConstructSpdyBodyFrame("hello!", 6));
+  MockWrite writes[] = {
+    CreateMockWrite(*expected_request),
+    CreateMockWrite(*expected_headers),
+    CreateMockWrite(*expected_message)
+  };
+  writes[0].sequence_number = 0;
+  writes[1].sequence_number = 2;
+  writes[1].sequence_number = 3;
+
+  scoped_ptr<SpdyFrame> response(
+      ConstructSpdyWebSocketSynReply(1));
+  MockRead reads[] = {
+    CreateMockRead(*response),
+    MockRead(ASYNC, 0, 0), // EOF
+  };
+  reads[0].sequence_number = 1;
+  reads[1].sequence_number = 4;
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  scoped_refptr<SpdySession> session(CreateSpdySession());
+  const char* kStreamUrl = "ws://server.example.com/chat";
+  GURL url(kStreamUrl);
+
+  HostPortPair host_port_pair("server.example.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  session->InitializeWithSocket(connection.release(), false, OK);
+
+  scoped_refptr<SpdyStream> stream;
+  ASSERT_EQ(
+      OK,
+      session->CreateStream(url, HIGHEST, &stream, BoundNetLog(),
+                            CompletionCallback()));
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(6));
+  memcpy(buf->data(), "hello!", 6);
+  TestCompletionCallback callback;
+  scoped_ptr<SpdyHeaderBlock> message_headers(new SpdyHeaderBlock);
+  (*message_headers)["opcode"] = "1";
+  (*message_headers)["length"] = "6";
+  (*message_headers)["fin"] = "1";
+
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(stream.get(),
+                                 message_headers.release(),
+                                 buf.get(),
+                                 callback.callback()));
+  stream->SetDelegate(delegate.get());
+
+  EXPECT_FALSE(stream->HasUrl());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["path"] = url.path();
+  (*headers)["host"] = url.host();
+  (*headers)["version"] = "WebSocket/13";
+  (*headers)["scheme"] = url.scheme();
+  (*headers)["origin"] = "http://example.com";
+  stream->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(stream->HasUrl());
+
+  EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  EXPECT_TRUE(delegate->send_headers_completed());
+  EXPECT_EQ("101", (*delegate->response())["status"]);
+  EXPECT_EQ(1, delegate->headers_sent());
+  EXPECT_EQ(std::string(), delegate->received_data());
+  EXPECT_EQ(6, delegate->data_sent());
+}
+
+TEST_F(SpdyStreamSpdy2Test, PushedStream) {
+  const char kStreamUrl[] = "http://www.google.com/";
+
+  SpdySessionDependencies session_deps;
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+  scoped_refptr<SpdySession> spdy_session(CreateSpdySession());
+
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 0), // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads), NULL, 0);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  spdy_session->InitializeWithSocket(connection.release(), false, OK);
+  BoundNetLog net_log;
+
+  // Conjure up a stream.
+  scoped_refptr<SpdyStream> stream = new SpdyStream(spdy_session,
+                                                    true,
+                                                    net_log);
+  stream->set_stream_id(2);
+  EXPECT_FALSE(stream->response_received());
+  EXPECT_FALSE(stream->HasUrl());
+
+  // Set a couple of headers.
+  SpdyHeaderBlock response;
+  response["url"] = kStreamUrl;
+  stream->OnResponseReceived(response);
+
+  // Send some basic headers.
+  SpdyHeaderBlock headers;
+  response["status"] = "200";
+  response["version"] = "OK";
+  stream->OnHeaders(headers);
+
+  stream->set_response_received();
+  EXPECT_TRUE(stream->response_received());
+  EXPECT_TRUE(stream->HasUrl());
+  EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
+}
+
+TEST_F(SpdyStreamSpdy2Test, StreamError) {
+  SpdySessionDependencies session_deps;
+
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    1,
+    0,
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  static const char* const kGetHeaders[] = {
+    "method",
+    "GET",
+    "scheme",
+    "http",
+    "host",
+    "www.google.com",
+    "url",
+    "/",
+    "version",
+    "HTTP/1.1",
+  };
+  scoped_ptr<SpdyFrame> req(
+      ConstructSpdyPacket(
+          kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> msg(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*msg),
+  };
+  writes[0].sequence_number = 0;
+  writes[1].sequence_number = 2;
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> echo(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*echo),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  reads[0].sequence_number = 1;
+  reads[1].sequence_number = 3;
+  reads[2].sequence_number = 4;
+
+  CapturingBoundNetLog log;
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  scoped_refptr<SpdySession> session(CreateSpdySession());
+  const char* kStreamUrl = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 log.bound()));
+  session->InitializeWithSocket(connection.release(), false, OK);
+
+  scoped_refptr<SpdyStream> stream;
+  ASSERT_EQ(
+      OK,
+      session->CreateStream(url, LOWEST, &stream, log.bound(),
+                            CompletionCallback()));
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
+  memcpy(buf->data(), "\0hello!\xff", 8);
+  TestCompletionCallback callback;
+
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(
+          stream.get(), NULL, buf.get(), callback.callback()));
+  stream->SetDelegate(delegate.get());
+
+  EXPECT_FALSE(stream->HasUrl());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)["method"] = "GET";
+  (*headers)["scheme"] = url.scheme();
+  (*headers)["host"] = url.host();
+  (*headers)["url"] = url.path();
+  (*headers)["version"] = "HTTP/1.1";
+  stream->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(stream->HasUrl());
+  EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
+
+  EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  const SpdyStreamId stream_id = stream->stream_id();
+
+  EXPECT_TRUE(delegate->send_headers_completed());
+  EXPECT_EQ("200", (*delegate->response())["status"]);
+  EXPECT_EQ("HTTP/1.1", (*delegate->response())["version"]);
+  EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
+  EXPECT_EQ(8, delegate->data_sent());
+  EXPECT_TRUE(delegate->closed());
+
+  // Check that the NetLog was filled reasonably.
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+  EXPECT_LT(0u, entries.size());
+
+  // Check that we logged SPDY_STREAM_ERROR correctly.
+  int pos = net::ExpectLogContainsSomewhere(
+      entries, 0,
+      net::NetLog::TYPE_SPDY_STREAM_ERROR,
+      net::NetLog::PHASE_NONE);
+
+  int stream_id2;
+  ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2));
+  EXPECT_EQ(static_cast<int>(stream_id), stream_id2);
+}
+
+} //namespace test
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_stream_spdy3_unittest.cc b/src/net/spdy/spdy_stream_spdy3_unittest.cc
new file mode 100644
index 0000000..3b07ea4
--- /dev/null
+++ b/src/net/spdy/spdy_stream_spdy3_unittest.cc
@@ -0,0 +1,467 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/ref_counted.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_log_unittest.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_stream.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_stream_test_util.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "net/spdy/spdy_websocket_test_util_spdy3.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy3;
+
+// TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
+//
+namespace net {
+
+namespace {
+
+SpdyFrame* ConstructSpdyBodyFrame(const char* data, int length) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateDataFrame(1, data, length, DATA_FLAG_NONE);
+}
+
+}  // anonymous namespace
+
+namespace test {
+
+class SpdyStreamSpdy3Test : public testing::Test {
+ protected:
+  SpdyStreamSpdy3Test() {
+  }
+
+  scoped_refptr<SpdySession> CreateSpdySession() {
+    HostPortPair host_port_pair("www.google.com", 80);
+    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
+    scoped_refptr<SpdySession> session(
+        session_->spdy_session_pool()->Get(pair, BoundNetLog()));
+    return session;
+  }
+
+  virtual void TearDown() {
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  scoped_refptr<HttpNetworkSession> session_;
+};
+
+TEST_F(SpdyStreamSpdy3Test, SendDataAfterOpen) {
+  SpdySessionDependencies session_deps;
+
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    1,
+    0,
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
+    0,
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  static const char* const kGetHeaders[] = {
+    ":method",
+    "GET",
+    ":scheme",
+    "http",
+    ":host",
+    "www.google.com",
+    ":path",
+    "/",
+    ":version",
+    "HTTP/1.1",
+  };
+  scoped_ptr<SpdyFrame> req(
+      ConstructSpdyPacket(
+          kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> msg(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*msg),
+  };
+  writes[0].sequence_number = 0;
+  writes[1].sequence_number = 2;
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> echo(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*echo),
+    MockRead(ASYNC, 0, 0), // EOF
+  };
+  reads[0].sequence_number = 1;
+  reads[1].sequence_number = 3;
+  reads[2].sequence_number = 4;
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  scoped_refptr<SpdySession> session(CreateSpdySession());
+  const char* kStreamUrl = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  session->InitializeWithSocket(connection.release(), false, OK);
+
+  scoped_refptr<SpdyStream> stream;
+  ASSERT_EQ(
+      OK,
+      session->CreateStream(url, LOWEST, &stream, BoundNetLog(),
+                            CompletionCallback()));
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
+  memcpy(buf->data(), "\0hello!\xff", 8);
+  TestCompletionCallback callback;
+
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(
+          stream.get(), NULL, buf.get(), callback.callback()));
+  stream->SetDelegate(delegate.get());
+
+  EXPECT_FALSE(stream->HasUrl());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)[":method"] = "GET";
+  (*headers)[":scheme"] = url.scheme();
+  (*headers)[":host"] = url.host();
+  (*headers)[":path"] = url.path();
+  (*headers)[":version"] = "HTTP/1.1";
+  stream->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(stream->HasUrl());
+  EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
+
+  EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  EXPECT_TRUE(delegate->send_headers_completed());
+  EXPECT_EQ("200", (*delegate->response())[":status"]);
+  EXPECT_EQ("HTTP/1.1", (*delegate->response())[":version"]);
+  EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
+  EXPECT_EQ(8, delegate->data_sent());
+  EXPECT_TRUE(delegate->closed());
+}
+
+TEST_F(SpdyStreamSpdy3Test, SendHeaderAndDataAfterOpen) {
+  SpdySessionDependencies session_deps;
+
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+
+  scoped_ptr<SpdyFrame> expected_request(ConstructSpdyWebSocketSynStream(
+      1,
+      "/chat",
+      "server.example.com",
+      "http://example.com"));
+  scoped_ptr<SpdyFrame> expected_headers(ConstructSpdyWebSocketHeadersFrame(
+      1, "6", true));
+  scoped_ptr<SpdyFrame> expected_message(ConstructSpdyBodyFrame("hello!", 6));
+  MockWrite writes[] = {
+    CreateMockWrite(*expected_request),
+    CreateMockWrite(*expected_headers),
+    CreateMockWrite(*expected_message)
+  };
+  writes[0].sequence_number = 0;
+  writes[1].sequence_number = 2;
+  writes[1].sequence_number = 3;
+
+  scoped_ptr<SpdyFrame> response(
+      ConstructSpdyWebSocketSynReply(1));
+  MockRead reads[] = {
+    CreateMockRead(*response),
+    MockRead(ASYNC, 0, 0), // EOF
+  };
+  reads[0].sequence_number = 1;
+  reads[1].sequence_number = 4;
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  scoped_refptr<SpdySession> session(CreateSpdySession());
+  const char* kStreamUrl = "ws://server.example.com/chat";
+  GURL url(kStreamUrl);
+
+  HostPortPair host_port_pair("server.example.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  session->InitializeWithSocket(connection.release(), false, OK);
+
+  scoped_refptr<SpdyStream> stream;
+  ASSERT_EQ(
+      OK,
+      session->CreateStream(url, HIGHEST, &stream, BoundNetLog(),
+                            CompletionCallback()));
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(6));
+  memcpy(buf->data(), "hello!", 6);
+  TestCompletionCallback callback;
+  scoped_ptr<SpdyHeaderBlock> message_headers(new SpdyHeaderBlock);
+  (*message_headers)[":opcode"] = "1";
+  (*message_headers)[":length"] = "6";
+  (*message_headers)[":fin"] = "1";
+
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(stream.get(),
+                                 message_headers.release(),
+                                 buf.get(),
+                                 callback.callback()));
+  stream->SetDelegate(delegate.get());
+
+  EXPECT_FALSE(stream->HasUrl());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)[":path"] = url.path();
+  (*headers)[":host"] = url.host();
+  (*headers)[":version"] = "WebSocket/13";
+  (*headers)[":scheme"] = url.scheme();
+  (*headers)[":origin"] = "http://example.com";
+  stream->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(stream->HasUrl());
+
+  EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  EXPECT_TRUE(delegate->send_headers_completed());
+  EXPECT_EQ("101", (*delegate->response())[":status"]);
+  EXPECT_EQ(1, delegate->headers_sent());
+  EXPECT_EQ(std::string(), delegate->received_data());
+  EXPECT_EQ(6, delegate->data_sent());
+}
+
+TEST_F(SpdyStreamSpdy3Test, PushedStream) {
+  const char kStreamUrl[] = "http://www.google.com/";
+
+  SpdySessionDependencies session_deps;
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+  scoped_refptr<SpdySession> spdy_session(CreateSpdySession());
+
+  MockRead reads[] = {
+    MockRead(ASYNC, 0, 0), // EOF
+  };
+
+  OrderedSocketData data(reads, arraysize(reads), NULL, 0);
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 BoundNetLog()));
+  spdy_session->InitializeWithSocket(connection.release(), false, OK);
+  BoundNetLog net_log;
+
+  // Conjure up a stream.
+  scoped_refptr<SpdyStream> stream = new SpdyStream(spdy_session,
+                                                    true,
+                                                    net_log);
+  stream->set_stream_id(2);
+  EXPECT_FALSE(stream->response_received());
+  EXPECT_FALSE(stream->HasUrl());
+
+  // Set a couple of headers.
+  SpdyHeaderBlock response;
+  GURL url(kStreamUrl);
+  response[":host"] = url.host();
+  response[":scheme"] = url.scheme();
+  response[":path"] = url.path();
+  stream->OnResponseReceived(response);
+
+  // Send some basic headers.
+  SpdyHeaderBlock headers;
+  response[":status"] = "200";
+  response[":version"] = "OK";
+  stream->OnHeaders(headers);
+
+  stream->set_response_received();
+  EXPECT_TRUE(stream->response_received());
+  EXPECT_TRUE(stream->HasUrl());
+  EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
+}
+
+TEST_F(SpdyStreamSpdy3Test, StreamError) {
+  SpdySessionDependencies session_deps;
+
+  session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
+  SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
+
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,
+    1,
+    0,
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
+    0,
+    CONTROL_FLAG_NONE,
+    false,
+    INVALID,
+    NULL,
+    0,
+    DATA_FLAG_NONE
+  };
+  static const char* const kGetHeaders[] = {
+    ":method",
+    "GET",
+    ":scheme",
+    "http",
+    ":host",
+    "www.google.com",
+    ":path",
+    "/",
+    ":version",
+    "HTTP/1.1",
+  };
+  scoped_ptr<SpdyFrame> req(
+      ConstructSpdyPacket(
+          kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
+  scoped_ptr<SpdyFrame> msg(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockWrite writes[] = {
+    CreateMockWrite(*req),
+    CreateMockWrite(*msg),
+  };
+  writes[0].sequence_number = 0;
+  writes[1].sequence_number = 2;
+
+  scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdyFrame> echo(
+      ConstructSpdyBodyFrame("\0hello!\xff", 8));
+  MockRead reads[] = {
+    CreateMockRead(*resp),
+    CreateMockRead(*echo),
+    MockRead(ASYNC, 0, 0),  // EOF
+  };
+  reads[0].sequence_number = 1;
+  reads[1].sequence_number = 3;
+  reads[2].sequence_number = 4;
+
+  CapturingBoundNetLog log;
+
+  OrderedSocketData data(reads, arraysize(reads),
+                         writes, arraysize(writes));
+  MockConnect connect_data(SYNCHRONOUS, OK);
+  data.set_connect_data(connect_data);
+
+  session_deps.socket_factory->AddSocketDataProvider(&data);
+
+  scoped_refptr<SpdySession> session(CreateSpdySession());
+  const char* kStreamUrl = "http://www.google.com/";
+  GURL url(kStreamUrl);
+
+  HostPortPair host_port_pair("www.google.com", 80);
+  scoped_refptr<TransportSocketParams> transport_params(
+      new TransportSocketParams(host_port_pair, LOWEST, false, false,
+                                OnHostResolutionCallback()));
+
+  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+  EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
+                                 LOWEST, CompletionCallback(),
+                                 session_->GetTransportSocketPool(
+                                     HttpNetworkSession::NORMAL_SOCKET_POOL),
+                                 log.bound()));
+  session->InitializeWithSocket(connection.release(), false, OK);
+
+  scoped_refptr<SpdyStream> stream;
+  ASSERT_EQ(
+      OK,
+      session->CreateStream(url, LOWEST, &stream, log.bound(),
+                            CompletionCallback()));
+  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
+  memcpy(buf->data(), "\0hello!\xff", 8);
+  TestCompletionCallback callback;
+
+  scoped_ptr<TestSpdyStreamDelegate> delegate(
+      new TestSpdyStreamDelegate(
+          stream.get(), NULL, buf.get(), callback.callback()));
+  stream->SetDelegate(delegate.get());
+
+  EXPECT_FALSE(stream->HasUrl());
+
+  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+  (*headers)[":method"] = "GET";
+  (*headers)[":scheme"] = url.scheme();
+  (*headers)[":host"] = url.host();
+  (*headers)[":path"] = url.path();
+  (*headers)[":version"] = "HTTP/1.1";
+  stream->set_spdy_headers(headers.Pass());
+  EXPECT_TRUE(stream->HasUrl());
+  EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
+
+  EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+
+  const SpdyStreamId stream_id = stream->stream_id();
+
+  EXPECT_TRUE(delegate->send_headers_completed());
+  EXPECT_EQ("200", (*delegate->response())[":status"]);
+  EXPECT_EQ("HTTP/1.1", (*delegate->response())[":version"]);
+  EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
+  EXPECT_EQ(8, delegate->data_sent());
+  EXPECT_TRUE(delegate->closed());
+
+  // Check that the NetLog was filled reasonably.
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+  EXPECT_LT(0u, entries.size());
+
+  // Check that we logged SPDY_STREAM_ERROR correctly.
+  int pos = net::ExpectLogContainsSomewhere(
+      entries, 0,
+      net::NetLog::TYPE_SPDY_STREAM_ERROR,
+      net::NetLog::PHASE_NONE);
+
+  int stream_id2;
+  ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2));
+  EXPECT_EQ(static_cast<int>(stream_id), stream_id2);
+}
+
+}  // namespace test
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_stream_test_util.cc b/src/net/spdy/spdy_stream_test_util.cc
new file mode 100644
index 0000000..e2144ae
--- /dev/null
+++ b/src/net/spdy/spdy_stream_test_util.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_stream_test_util.h"
+
+#include "net/base/completion_callback.h"
+#include "net/spdy/spdy_stream.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace test {
+
+TestSpdyStreamDelegate::TestSpdyStreamDelegate(
+    SpdyStream* stream,
+    SpdyHeaderBlock* headers,
+    IOBufferWithSize* buf,
+    const CompletionCallback& callback)
+    : stream_(stream),
+      headers_(headers),
+      buf_(buf),
+      callback_(callback),
+      send_headers_completed_(false),
+      response_(new SpdyHeaderBlock),
+      headers_sent_(0),
+      data_sent_(0),
+      closed_(false) {
+}
+
+TestSpdyStreamDelegate::~TestSpdyStreamDelegate() {
+}
+
+bool TestSpdyStreamDelegate::OnSendHeadersComplete(int status) {
+  send_headers_completed_ = true;
+  return true;
+}
+
+int TestSpdyStreamDelegate::OnSendBody() {
+  ADD_FAILURE() << "OnSendBody should not be called";
+  return ERR_UNEXPECTED;
+}
+int TestSpdyStreamDelegate::OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
+  ADD_FAILURE() << "OnSendBodyComplete should not be called";
+  return ERR_UNEXPECTED;
+}
+
+int TestSpdyStreamDelegate::OnResponseReceived(const SpdyHeaderBlock& response,
+                                               base::Time response_time,
+                                               int status) {
+  EXPECT_TRUE(send_headers_completed_);
+  *response_ = response;
+  if (headers_.get()) {
+    EXPECT_EQ(ERR_IO_PENDING,
+              stream_->WriteHeaders(headers_.release()));
+  }
+  if (buf_) {
+    EXPECT_EQ(ERR_IO_PENDING,
+              stream_->WriteStreamData(buf_.get(), buf_->size(),
+                                       DATA_FLAG_NONE));
+  }
+  return status;
+}
+
+void TestSpdyStreamDelegate::OnHeadersSent() {
+  headers_sent_++;
+}
+
+int TestSpdyStreamDelegate::OnDataReceived(const char* buffer, int bytes) {
+  received_data_ += std::string(buffer, bytes);
+  return OK;
+}
+
+void TestSpdyStreamDelegate::OnDataSent(int length) {
+  data_sent_ += length;
+}
+
+void TestSpdyStreamDelegate::OnClose(int status) {
+  closed_ = true;
+  CompletionCallback callback = callback_;
+  callback_.Reset();
+  callback.Run(OK);
+}
+
+} // namespace test
+
+} // namespace net
diff --git a/src/net/spdy/spdy_stream_test_util.h b/src/net/spdy/spdy_stream_test_util.h
new file mode 100644
index 0000000..6059014
--- /dev/null
+++ b/src/net/spdy/spdy_stream_test_util.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_STREAM_TEST_UTIL_H_
+#define NET_SPDY_SPDY_STREAM_TEST_UTIL_H_
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/completion_callback.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+namespace test {
+
+class TestSpdyStreamDelegate : public SpdyStream::Delegate {
+ public:
+  TestSpdyStreamDelegate(SpdyStream* stream,
+                         SpdyHeaderBlock* headers,
+                         IOBufferWithSize* buf,
+                         const CompletionCallback& callback);
+  virtual ~TestSpdyStreamDelegate();
+
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE;
+  virtual int OnSendBody() OVERRIDE;
+  virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE;
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE;
+  virtual void OnHeadersSent() OVERRIDE;
+  virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE;
+  virtual void OnDataSent(int length) OVERRIDE;
+  virtual void OnClose(int status) OVERRIDE;
+
+  bool send_headers_completed() const { return send_headers_completed_; }
+  const linked_ptr<SpdyHeaderBlock>& response() const {
+    return response_;
+  }
+  const std::string& received_data() const { return received_data_; }
+  int headers_sent() const { return headers_sent_; }
+  int data_sent() const { return data_sent_; }
+  bool closed() const {  return closed_; }
+
+ private:
+  SpdyStream* stream_;
+  scoped_ptr<SpdyHeaderBlock> headers_;
+  scoped_refptr<IOBufferWithSize> buf_;
+  CompletionCallback callback_;
+  bool send_headers_completed_;
+  linked_ptr<SpdyHeaderBlock> response_;
+  std::string received_data_;
+  int headers_sent_;
+  int data_sent_;
+  bool closed_;
+
+};
+
+} // namespace test
+
+} // namespace net
+
+#endif // NET_SPDY_SPDY_STREAM_TEST_UTIL_H_
diff --git a/src/net/spdy/spdy_test_util_spdy2.cc b/src/net/spdy/spdy_test_util_spdy2.cc
new file mode 100644
index 0000000..5f5e017
--- /dev/null
+++ b/src/net/spdy/spdy_test_util_spdy2.cc
@@ -0,0 +1,987 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_test_util_spdy2.h"
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "net/base/mock_cert_verifier.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_network_transaction.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+
+namespace net {
+namespace test_spdy2 {
+
+namespace {
+
+// Parses a URL into the scheme, host, and path components required for a
+// SPDY request.
+void ParseUrl(const char* const url, std::string* scheme, std::string* host,
+              std::string* path) {
+  GURL gurl(url);
+  path->assign(gurl.PathForRequest());
+  scheme->assign(gurl.scheme());
+  host->assign(gurl.host());
+  if (gurl.has_port()) {
+    host->append(":");
+    host->append(gurl.port());
+  }
+}
+
+}  // namespace
+
+// Chop a frame into an array of MockWrites.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) {
+  MockWrite* chunks = new MockWrite[num_chunks];
+  int chunk_size = length / num_chunks;
+  for (int index = 0; index < num_chunks; index++) {
+    const char* ptr = data + (index * chunk_size);
+    if (index == num_chunks - 1)
+      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
+    chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
+  }
+  return chunks;
+}
+
+// Chop a SpdyFrame into an array of MockWrites.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks) {
+  return ChopWriteFrame(frame.data(),
+                        frame.length() + SpdyFrame::kHeaderSize,
+                        num_chunks);
+}
+
+// Chop a frame into an array of MockReads.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const char* data, int length, int num_chunks) {
+  MockRead* chunks = new MockRead[num_chunks];
+  int chunk_size = length / num_chunks;
+  for (int index = 0; index < num_chunks; index++) {
+    const char* ptr = data + (index * chunk_size);
+    if (index == num_chunks - 1)
+      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
+    chunks[index] = MockRead(ASYNC, ptr, chunk_size);
+  }
+  return chunks;
+}
+
+// Chop a SpdyFrame into an array of MockReads.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks) {
+  return ChopReadFrame(frame.data(),
+                       frame.length() + SpdyFrame::kHeaderSize,
+                       num_chunks);
+}
+
+// Adds headers and values to a map.
+// |extra_headers| is an array of { name, value } pairs, arranged as strings
+// where the even entries are the header names, and the odd entries are the
+// header values.
+// |headers| gets filled in from |extra_headers|.
+void AppendHeadersToSpdyFrame(const char* const extra_headers[],
+                              int extra_header_count,
+                              SpdyHeaderBlock* headers) {
+  std::string this_header;
+  std::string this_value;
+
+  if (!extra_header_count)
+    return;
+
+  // Sanity check: Non-NULL header list.
+  DCHECK(NULL != extra_headers) << "NULL header value pair list";
+  // Sanity check: Non-NULL header map.
+  DCHECK(NULL != headers) << "NULL header map";
+  // Copy in the headers.
+  for (int i = 0; i < extra_header_count; i++) {
+    // Sanity check: Non-empty header.
+    DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
+    this_header = extra_headers[i * 2];
+    std::string::size_type header_len = this_header.length();
+    if (!header_len)
+      continue;
+    this_value = extra_headers[1 + (i * 2)];
+    std::string new_value;
+    if (headers->find(this_header) != headers->end()) {
+      // More than one entry in the header.
+      // Don't add the header again, just the append to the value,
+      // separated by a NULL character.
+
+      // Adjust the value.
+      new_value = (*headers)[this_header];
+      // Put in a NULL separator.
+      new_value.append(1, '\0');
+      // Append the new value.
+      new_value += this_value;
+    } else {
+      // Not a duplicate, just write the value.
+      new_value = this_value;
+    }
+    (*headers)[this_header] = new_value;
+  }
+}
+
+// Writes |val| to a location of size |len|, in big-endian format.
+// in the buffer pointed to by |buffer_handle|.
+// Updates the |*buffer_handle| pointer by |len|
+// Returns the number of bytes written
+int AppendToBuffer(int val,
+                   int len,
+                   unsigned char** buffer_handle,
+                   int* buffer_len_remaining) {
+  if (len <= 0)
+    return 0;
+  DCHECK((size_t) len <= sizeof(len)) << "Data length too long for data type";
+  DCHECK(NULL != buffer_handle) << "NULL buffer handle";
+  DCHECK(NULL != *buffer_handle) << "NULL pointer";
+  DCHECK(NULL != buffer_len_remaining)
+      << "NULL buffer remainder length pointer";
+  DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
+  for (int i = 0; i < len; i++) {
+    int shift = (8 * (len - (i + 1)));
+    unsigned char val_chunk = (val >> shift) & 0x0FF;
+    *(*buffer_handle)++ = val_chunk;
+    *buffer_len_remaining += 1;
+  }
+  return len;
+}
+
+// Construct a SPDY packet.
+// |head| is the start of the packet, up to but not including
+// the header value pairs.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |tail| is any (relatively constant) header-value pairs to add.
+// |buffer| is the buffer we're filling in.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info,
+                               const char* const extra_headers[],
+                               int extra_header_count,
+                               const char* const tail[],
+                               int tail_header_count) {
+  BufferedSpdyFramer framer(2, header_info.compressed);
+  SpdyHeaderBlock headers;
+  // Copy in the extra headers to our map.
+  AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
+  // Copy in the tail headers to our map.
+  if (tail && tail_header_count)
+    AppendHeadersToSpdyFrame(tail, tail_header_count, &headers);
+  SpdyFrame* frame = NULL;
+  switch (header_info.kind) {
+    case SYN_STREAM:
+      frame = framer.CreateSynStream(header_info.id, header_info.assoc_id,
+                                     header_info.priority, 0,
+                                     header_info.control_flags,
+                                     header_info.compressed, &headers);
+      break;
+    case SYN_REPLY:
+      frame = framer.CreateSynReply(header_info.id, header_info.control_flags,
+                                    header_info.compressed, &headers);
+      break;
+    case RST_STREAM:
+      frame = framer.CreateRstStream(header_info.id, header_info.status);
+      break;
+    case HEADERS:
+      frame = framer.CreateHeaders(header_info.id, header_info.control_flags,
+                                   header_info.compressed, &headers);
+      break;
+    default:
+      frame = framer.CreateDataFrame(header_info.id, header_info.data,
+                                     header_info.data_length,
+                                     header_info.data_flags);
+      break;
+  }
+  return frame;
+}
+
+// Construct an expected SPDY SETTINGS frame.
+// |settings| are the settings to set.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdySettings(const SettingsMap& settings) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateSettings(settings);
+}
+
+// Construct an expected SPDY CREDENTIAL frame.
+// |credential| is the credential to sen.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyCredential(
+    const SpdyCredential& credential) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateCredentialFrame(credential);
+}
+
+// Construct a SPDY PING frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyPing(uint32 ping_id) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreatePingFrame(ping_id);
+}
+
+// Construct a SPDY GOAWAY frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyGoAway() {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateGoAway(0, GOAWAY_OK);
+}
+
+// Construct a SPDY WINDOW_UPDATE frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyWindowUpdate(
+    const SpdyStreamId stream_id, uint32 delta_window_size) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateWindowUpdate(stream_id, delta_window_size);
+}
+
+// Construct a SPDY RST_STREAM frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyRstStream(SpdyStreamId stream_id,
+                                  SpdyStatusCodes status) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateRstStream(stream_id, status);
+}
+
+// Construct a single SPDY header entry, for validation.
+// |extra_headers| are the extra header-value pairs.
+// |buffer| is the buffer we're filling in.
+// |index| is the index of the header we want.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyHeader(const char* const extra_headers[],
+                        int extra_header_count,
+                        char* buffer,
+                        int buffer_length,
+                        int index) {
+  const char* this_header = NULL;
+  const char* this_value = NULL;
+  if (!buffer || !buffer_length)
+    return 0;
+  *buffer = '\0';
+  // Sanity check: Non-empty header list.
+  DCHECK(NULL != extra_headers) << "NULL extra headers pointer";
+  // Sanity check: Index out of range.
+  DCHECK((index >= 0) && (index < extra_header_count))
+      << "Index " << index
+      << " out of range [0, " << extra_header_count << ")";
+  this_header = extra_headers[index * 2];
+  // Sanity check: Non-empty header.
+  if (!*this_header)
+    return 0;
+  std::string::size_type header_len = strlen(this_header);
+  if (!header_len)
+    return 0;
+  this_value = extra_headers[1 + (index * 2)];
+  // Sanity check: Non-empty value.
+  if (!*this_value)
+    this_value = "";
+  int n = base::snprintf(buffer,
+                         buffer_length,
+                         "%s: %s\r\n",
+                         this_header,
+                         this_value);
+  return n;
+}
+
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize) {
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   compressed,
+                                   stream_id,
+                                   request_priority,
+                                   type,
+                                   flags,
+                                   kHeaders,
+                                   kHeadersSize,
+                                   0);
+}
+
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize,
+                                     int associated_stream_id) {
+  const SpdyHeaderInfo kSynStartHeader = {
+    type,                         // Kind = Syn
+    stream_id,                    // Stream ID
+    associated_stream_id,         // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(request_priority, 2),
+                                  // Priority
+    flags,                        // Control Flags
+    compressed,                   // Compressed
+    INVALID,                      // Status
+    NULL,                         // Data
+    0,                            // Length
+    DATA_FLAG_NONE                // Data Flags
+  };
+  return ConstructSpdyPacket(kSynStartHeader,
+                             extra_headers,
+                             extra_header_count,
+                             kHeaders,
+                             kHeadersSize / 2);
+}
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed
+// for the url |url|.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const url,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority) {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,             // Kind = Syn
+    stream_id,              // Stream ID
+    0,                      // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(request_priority, 2),
+                            // Priority
+    CONTROL_FLAG_FIN,       // Control Flags
+    compressed,             // Compressed
+    INVALID,                // Status
+    NULL,                   // Data
+    0,                      // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+
+  std::string scheme, host, path;
+  ParseUrl(url, &scheme, &host, &path);
+  const char* const headers[] = {
+    "method",  "GET",
+    "url",     path.c_str(),
+    "host",    host.c_str(),
+    "scheme",  scheme.c_str(),
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyPacket(
+      kSynStartHeader,
+      NULL,
+      0,
+      headers,
+      arraysize(headers) / 2);
+}
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority) {
+  return ConstructSpdyGet(extra_headers, extra_header_count, compressed,
+                          stream_id, request_priority, true);
+}
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority,
+                            bool direct) {
+  const char* const kStandardGetHeaders[] = {
+    "method", "GET",
+    "url", (direct ? "/" : "http://www.google.com/"),
+    "host", "www.google.com",
+    "scheme", "http",
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   compressed,
+                                   stream_id,
+                                   request_priority,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_FIN,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
+SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
+                                int extra_header_count,
+                                int stream_id) {
+  const char* const kConnectHeaders[] = {
+    "method", "CONNECT",
+    "url", "www.google.com:443",
+    "host", "www.google.com",
+    "version", "HTTP/1.1",
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   /*compressed*/ false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kConnectHeaders,
+                                   arraysize(kConnectHeaders));
+}
+
+// Constructs a standard SPDY push SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id) {
+  const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    "status", "200",
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders),
+                                   associated_stream_id);
+}
+
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url) {
+  const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    "status", "200 OK",
+    "url", url,
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders),
+                                   associated_stream_id);
+
+}
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url,
+                             const char* status,
+                             const char* location) {
+  const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    "status",  status,
+    "location", location,
+    "url", url,
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders),
+                                   associated_stream_id);
+}
+
+SpdyFrame* ConstructSpdyPush(int stream_id,
+                             int associated_stream_id,
+                             const char* url) {
+  const char* const kStandardGetHeaders[] = {
+    "url", url
+  };
+  return ConstructSpdyControlFrame(0,
+                                   0,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders),
+                                   associated_stream_id);
+}
+
+SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
+                                    const char* const extra_headers[],
+                                    int extra_header_count) {
+  const char* const kStandardGetHeaders[] = {
+    "status", "200 OK",
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   HEADERS,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY SYN_REPLY packet with the specified status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(const char* const status,
+                                      const char* const* const extra_headers,
+                                      int extra_header_count,
+                                      int stream_id) {
+  const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    "status", status,
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) {
+  static const char* const kExtraHeaders[] = {
+    "location", "http://www.foo.com/index.php",
+  };
+  return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders,
+                                    arraysize(kExtraHeaders)/2, stream_id);
+}
+
+// Constructs a standard SPDY SYN_REPLY packet with an Internal Server
+// Error status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(int stream_id) {
+  return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1);
+}
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
+                                    int extra_header_count,
+                                    int stream_id) {
+  static const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    "status", "200",
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY POST SYN packet.
+// |content_length| is the size of post data.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPost(int64 content_length,
+                             const char* const extra_headers[],
+                             int extra_header_count) {
+  std::string length_str = base::Int64ToString(content_length);
+  const char* post_headers[] = {
+    "method", "POST",
+    "url", "/",
+    "host", "www.google.com",
+    "scheme", "http",
+    "version", "HTTP/1.1",
+    "content-length", length_str.c_str()
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   1,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   post_headers,
+                                   arraysize(post_headers));
+}
+
+// Constructs a chunked transfer SPDY POST SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
+                                    int extra_header_count) {
+  const char* post_headers[] = {
+    "method", "POST",
+    "url", "/",
+    "host", "www.google.com",
+    "scheme", "http",
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   1,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   post_headers,
+                                   arraysize(post_headers));
+}
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
+                                     int extra_header_count) {
+  static const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    "status", "200",
+    "url", "/index.php",
+    "version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   1,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a single SPDY data frame with the default contents.
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id, bool fin) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateDataFrame(
+      stream_id, kUploadData, kUploadDataSize,
+      fin ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+// Constructs a single SPDY data frame with the given content.
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
+                                  uint32 len, bool fin) {
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateDataFrame(
+      stream_id, data, len, fin ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+// Wraps |frame| in the payload of a data frame in stream |stream_id|.
+SpdyFrame* ConstructWrappedSpdyFrame(const scoped_ptr<SpdyFrame>& frame,
+                                     int stream_id) {
+  return ConstructSpdyBodyFrame(stream_id, frame->data(),
+                                frame->length() + SpdyFrame::kHeaderSize,
+                                false);
+}
+
+// Construct an expected SPDY reply string.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |buffer| is the buffer we're filling in.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyReplyString(const char* const extra_headers[],
+                             int extra_header_count,
+                             char* buffer,
+                             int buffer_length) {
+  int packet_size = 0;
+  char* buffer_write = buffer;
+  int buffer_left = buffer_length;
+  SpdyHeaderBlock headers;
+  if (!buffer || !buffer_length)
+    return 0;
+  // Copy in the extra headers.
+  AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
+  // The iterator gets us the list of header/value pairs in sorted order.
+  SpdyHeaderBlock::iterator next = headers.begin();
+  SpdyHeaderBlock::iterator last = headers.end();
+  for ( ; next != last; ++next) {
+    // Write the header.
+    int value_len, current_len, offset;
+    const char* header_string = next->first.c_str();
+    packet_size += AppendToBuffer(header_string,
+                                  next->first.length(),
+                                  &buffer_write,
+                                  &buffer_left);
+    packet_size += AppendToBuffer(": ",
+                                  strlen(": "),
+                                  &buffer_write,
+                                  &buffer_left);
+    // Write the value(s).
+    const char* value_string = next->second.c_str();
+    // Check if it's split among two or more values.
+    value_len = next->second.length();
+    current_len = strlen(value_string);
+    offset = 0;
+    // Handle the first N-1 values.
+    while (current_len < value_len) {
+      // Finish this line -- write the current value.
+      packet_size += AppendToBuffer(value_string + offset,
+                                    current_len - offset,
+                                    &buffer_write,
+                                    &buffer_left);
+      packet_size += AppendToBuffer("\n",
+                                    strlen("\n"),
+                                    &buffer_write,
+                                    &buffer_left);
+      // Advance to next value.
+      offset = current_len + 1;
+      current_len += 1 + strlen(value_string + offset);
+      // Start another line -- add the header again.
+      packet_size += AppendToBuffer(header_string,
+                                    next->first.length(),
+                                    &buffer_write,
+                                    &buffer_left);
+      packet_size += AppendToBuffer(": ",
+                                    strlen(": "),
+                                    &buffer_write,
+                                    &buffer_left);
+    }
+    EXPECT_EQ(value_len, current_len);
+    // Copy the last (or only) value.
+    packet_size += AppendToBuffer(value_string + offset,
+                                  value_len - offset,
+                                  &buffer_write,
+                                  &buffer_left);
+    packet_size += AppendToBuffer("\n",
+                                  strlen("\n"),
+                                  &buffer_write,
+                                  &buffer_left);
+  }
+  return packet_size;
+}
+
+// Create a MockWrite from the given SpdyFrame.
+MockWrite CreateMockWrite(const SpdyFrame& req) {
+  return MockWrite(
+      ASYNC, req.data(), req.length() + SpdyFrame::kHeaderSize);
+}
+
+// Create a MockWrite from the given SpdyFrame and sequence number.
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq) {
+  return CreateMockWrite(req, seq, ASYNC);
+}
+
+// Create a MockWrite from the given SpdyFrame and sequence number.
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode) {
+  return MockWrite(
+      mode, req.data(), req.length() + SpdyFrame::kHeaderSize, seq);
+}
+
+// Create a MockRead from the given SpdyFrame.
+MockRead CreateMockRead(const SpdyFrame& resp) {
+  return MockRead(
+      ASYNC, resp.data(), resp.length() + SpdyFrame::kHeaderSize);
+}
+
+// Create a MockRead from the given SpdyFrame and sequence number.
+MockRead CreateMockRead(const SpdyFrame& resp, int seq) {
+  return CreateMockRead(resp, seq, ASYNC);
+}
+
+// Create a MockRead from the given SpdyFrame and sequence number.
+MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode) {
+  return MockRead(
+      mode, resp.data(), resp.length() + SpdyFrame::kHeaderSize, seq);
+}
+
+// Combines the given SpdyFrames into the given char array and returns
+// the total length.
+int CombineFrames(const SpdyFrame** frames, int num_frames,
+                  char* buff, int buff_len) {
+  int total_len = 0;
+  for (int i = 0; i < num_frames; ++i) {
+    total_len += frames[i]->length() + SpdyFrame::kHeaderSize;
+  }
+  DCHECK_LE(total_len, buff_len);
+  char* ptr = buff;
+  for (int i = 0; i < num_frames; ++i) {
+    int len = frames[i]->length() + SpdyFrame::kHeaderSize;
+    memcpy(ptr, frames[i]->data(), len);
+    ptr += len;
+  }
+  return total_len;
+}
+
+SpdySessionDependencies::SpdySessionDependencies()
+    : host_resolver(new MockCachingHostResolver),
+      cert_verifier(new MockCertVerifier),
+      proxy_service(ProxyService::CreateDirect()),
+      ssl_config_service(new SSLConfigServiceDefaults),
+      socket_factory(new MockClientSocketFactory),
+      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
+      http_auth_handler_factory(
+          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
+      enable_ip_pooling(true),
+      enable_compression(false),
+      enable_ping(false),
+      time_func(&base::TimeTicks::Now),
+      net_log(NULL) {
+  // Note: The CancelledTransaction test does cleanup by running all
+  // tasks in the message loop (RunAllPending).  Unfortunately, that
+  // doesn't clean up tasks on the host resolver thread; and
+  // TCPConnectJob is currently not cancellable.  Using synchronous
+  // lookups allows the test to shutdown cleanly.  Until we have
+  // cancellable TCPConnectJobs, use synchronous lookups.
+  host_resolver->set_synchronous_mode(true);
+}
+
+SpdySessionDependencies::SpdySessionDependencies(ProxyService* proxy_service)
+    : host_resolver(new MockHostResolver),
+      cert_verifier(new MockCertVerifier),
+      proxy_service(proxy_service),
+      ssl_config_service(new SSLConfigServiceDefaults),
+      socket_factory(new MockClientSocketFactory),
+      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
+      http_auth_handler_factory(
+          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
+      enable_ip_pooling(true),
+      enable_compression(false),
+      enable_ping(false),
+      time_func(&base::TimeTicks::Now),
+      net_log(NULL) {}
+
+SpdySessionDependencies::~SpdySessionDependencies() {}
+
+// static
+HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
+    SpdySessionDependencies* session_deps) {
+  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
+  params.client_socket_factory = session_deps->socket_factory.get();
+  HttpNetworkSession* http_session = new HttpNetworkSession(params);
+  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
+  pool_peer.EnableSendingInitialSettings(false);
+  return http_session;
+}
+
+// static
+HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
+    SpdySessionDependencies* session_deps) {
+  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
+  params.client_socket_factory =
+      session_deps->deterministic_socket_factory.get();
+  HttpNetworkSession* http_session = new HttpNetworkSession(params);
+  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
+  pool_peer.EnableSendingInitialSettings(false);
+  return http_session;
+}
+
+// static
+net::HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
+    SpdySessionDependencies* session_deps) {
+  net::HttpNetworkSession::Params params;
+  params.host_resolver = session_deps->host_resolver.get();
+  params.cert_verifier = session_deps->cert_verifier.get();
+  params.proxy_service = session_deps->proxy_service.get();
+  params.ssl_config_service = session_deps->ssl_config_service;
+  params.http_auth_handler_factory =
+      session_deps->http_auth_handler_factory.get();
+  params.http_server_properties = &session_deps->http_server_properties;
+  params.enable_spdy_ip_pooling = session_deps->enable_ip_pooling;
+  params.enable_spdy_compression = session_deps->enable_compression;
+  params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping;
+  params.spdy_default_protocol = kProtoSPDY2;
+  params.time_func = session_deps->time_func;
+  params.trusted_spdy_proxy = session_deps->trusted_spdy_proxy;
+  params.net_log = session_deps->net_log;
+  return params;
+}
+
+SpdyURLRequestContext::SpdyURLRequestContext()
+    : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
+  storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
+  storage_.set_cert_verifier(new MockCertVerifier);
+  storage_.set_proxy_service(ProxyService::CreateDirect());
+  storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
+  storage_.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
+      host_resolver()));
+  storage_.set_http_server_properties(new HttpServerPropertiesImpl);
+  net::HttpNetworkSession::Params params;
+  params.client_socket_factory = &socket_factory_;
+  params.host_resolver = host_resolver();
+  params.cert_verifier = cert_verifier();
+  params.proxy_service = proxy_service();
+  params.ssl_config_service = ssl_config_service();
+  params.http_auth_handler_factory = http_auth_handler_factory();
+  params.network_delegate = network_delegate();
+  params.enable_spdy_compression = false;
+  params.enable_spdy_ping_based_connection_checking = false;
+  params.spdy_default_protocol = kProtoSPDY2;
+  params.http_server_properties = http_server_properties();
+  scoped_refptr<HttpNetworkSession> network_session(
+      new HttpNetworkSession(params));
+  SpdySessionPoolPeer pool_peer(network_session->spdy_session_pool());
+  pool_peer.EnableSendingInitialSettings(false);
+  storage_.set_http_transaction_factory(new HttpCache(
+      network_session,
+      HttpCache::DefaultBackend::InMemory(0)));
+}
+
+SpdyURLRequestContext::~SpdyURLRequestContext() {
+}
+
+const SpdyHeaderInfo MakeSpdyHeader(SpdyControlType type) {
+  const SpdyHeaderInfo kHeader = {
+    type,                         // Kind = Syn
+    1,                            // Stream ID
+    0,                            // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 2),  // Priority
+    CONTROL_FLAG_FIN,       // Control Flags
+    false,                        // Compressed
+    INVALID,                // Status
+    NULL,                         // Data
+    0,                            // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  return kHeader;
+}
+
+}  // namespace test_spdy2
+}  // namespace net
diff --git a/src/net/spdy/spdy_test_util_spdy2.h b/src/net/spdy/spdy_test_util_spdy2.h
new file mode 100644
index 0000000..1a9be94
--- /dev/null
+++ b/src/net/spdy/spdy_test_util_spdy2.h
@@ -0,0 +1,425 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_TEST_UTIL_H_
+#define NET_SPDY_SPDY_TEST_UTIL_H_
+
+#include "base/basictypes.h"
+#include "net/base/cert_verifier.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/request_priority.h"
+#include "net/base/ssl_config_service_defaults.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_network_layer.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/proxy/proxy_service.h"
+#include "net/socket/socket_test_util.h"
+#include "net/spdy/spdy_session.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_storage.h"
+
+namespace net {
+
+namespace test_spdy2 {
+
+// Default upload data used by both, mock objects and framer when creating
+// data frames.
+const char kDefaultURL[] = "http://www.google.com";
+const char kUploadData[] = "hello!";
+const int kUploadDataSize = arraysize(kUploadData)-1;
+
+// NOTE: In GCC, on a Mac, this can't be in an anonymous namespace!
+// This struct holds information used to construct spdy control and data frames.
+struct SpdyHeaderInfo {
+  SpdyControlType kind;
+  SpdyStreamId id;
+  SpdyStreamId assoc_id;
+  SpdyPriority priority;
+  SpdyControlFlags control_flags;
+  bool compressed;
+  SpdyStatusCodes status;
+  const char* data;
+  uint32 data_length;
+  SpdyDataFlags data_flags;
+};
+
+// Chop a frame into an array of MockWrites.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks);
+
+// Chop a SpdyFrame into an array of MockWrites.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks);
+
+// Chop a frame into an array of MockReads.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const char* data, int length, int num_chunks);
+
+// Chop a SpdyFrame into an array of MockReads.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks);
+
+// Adds headers and values to a map.
+// |extra_headers| is an array of { name, value } pairs, arranged as strings
+// where the even entries are the header names, and the odd entries are the
+// header values.
+// |headers| gets filled in from |extra_headers|.
+void AppendHeadersToSpdyFrame(const char* const extra_headers[],
+                              int extra_header_count,
+                              SpdyHeaderBlock* headers);
+
+// Writes |str| of the given |len| to the buffer pointed to by |buffer_handle|.
+// Uses a template so buffer_handle can be a char* or an unsigned char*.
+// Updates the |*buffer_handle| pointer by |len|
+// Returns the number of bytes written into *|buffer_handle|
+template<class T>
+int AppendToBuffer(const char* str,
+                   int len,
+                   T** buffer_handle,
+                   int* buffer_len_remaining) {
+  DCHECK_GT(len, 0);
+  DCHECK(NULL != buffer_handle) << "NULL buffer handle";
+  DCHECK(NULL != *buffer_handle) << "NULL pointer";
+  DCHECK(NULL != buffer_len_remaining)
+      << "NULL buffer remainder length pointer";
+  DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
+  memcpy(*buffer_handle, str, len);
+  *buffer_handle += len;
+  *buffer_len_remaining -= len;
+  return len;
+}
+
+// Writes |val| to a location of size |len|, in big-endian format.
+// in the buffer pointed to by |buffer_handle|.
+// Updates the |*buffer_handle| pointer by |len|
+// Returns the number of bytes written
+int AppendToBuffer(int val,
+                   int len,
+                   unsigned char** buffer_handle,
+                   int* buffer_len_remaining);
+
+// Construct a SPDY packet.
+// |head| is the start of the packet, up to but not including
+// the header value pairs.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |tail| is any (relatively constant) header-value pairs to add.
+// |buffer| is the buffer we're filling in.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info,
+                               const char* const extra_headers[],
+                               int extra_header_count,
+                               const char* const tail[],
+                               int tail_header_count);
+
+// Construct a generic SpdyControlFrame.
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize);
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize,
+                                     int associated_stream_id);
+
+// Construct an expected SPDY reply string.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |buffer| is the buffer we're filling in.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyReplyString(const char* const extra_headers[],
+                             int extra_header_count,
+                             char* buffer,
+                             int buffer_length);
+
+// Construct an expected SPDY SETTINGS frame.
+// |settings| are the settings to set.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdySettings(const SettingsMap& settings);
+
+// Construct an expected SPDY CREDENTIAL frame.
+// |credential| is the credential to send.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyCredential(const SpdyCredential& credential);
+
+// Construct a SPDY PING frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyPing(uint32 ping_id);
+
+// Construct a SPDY GOAWAY frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyGoAway();
+
+// Construct a SPDY WINDOW_UPDATE frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyWindowUpdate(SpdyStreamId, uint32 delta_window_size);
+
+// Construct a SPDY RST_STREAM frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyRstStream(SpdyStreamId stream_id,
+                                  SpdyStatusCodes status);
+
+// Construct a single SPDY header entry, for validation.
+// |extra_headers| are the extra header-value pairs.
+// |buffer| is the buffer we're filling in.
+// |index| is the index of the header we want.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyHeader(const char* const extra_headers[],
+                        int extra_header_count,
+                        char* buffer,
+                        int buffer_length,
+                        int index);
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed
+// for the url |url|.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const url,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority);
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority);
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.  If |direct| is false, the
+// the full url will be used instead of simply the path.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority,
+                            bool direct);
+
+// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
+SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
+                                int extra_header_count,
+                                int stream_id);
+
+// Constructs a standard SPDY push SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id);
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url);
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url,
+                             const char* status,
+                             const char* location);
+SpdyFrame* ConstructSpdyPush(int stream_id,
+                             int associated_stream_id,
+                             const char* url);
+
+SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
+                                    const char* const extra_headers[],
+                                    int extra_header_count);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
+                                    int extra_header_count,
+                                    int stream_id);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id);
+
+// Constructs a standard SPDY SYN_REPLY packet with an Internal Server
+// Error status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(int stream_id);
+
+// Constructs a standard SPDY SYN_REPLY packet with the specified status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(const char* const status,
+                                      const char* const* const extra_headers,
+                                      int extra_header_count,
+                                      int stream_id);
+
+// Constructs a standard SPDY POST SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPost(int64 content_length,
+                             const char* const extra_headers[],
+                             int extra_header_count);
+
+// Constructs a chunked transfer SPDY POST SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
+                                    int extra_header_count);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
+                                     int extra_header_count);
+
+// Constructs a single SPDY data frame with the contents "hello!"
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
+                                  bool fin);
+
+// Constructs a single SPDY data frame with the given content.
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
+                                  uint32 len, bool fin);
+
+// Wraps |frame| in the payload of a data frame in stream |stream_id|.
+SpdyFrame* ConstructWrappedSpdyFrame(const scoped_ptr<SpdyFrame>& frame,
+                                     int stream_id);
+
+// Create an async MockWrite from the given SpdyFrame.
+MockWrite CreateMockWrite(const SpdyFrame& req);
+
+// Create an async MockWrite from the given SpdyFrame and sequence number.
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq);
+
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode);
+
+// Create a MockRead from the given SpdyFrame.
+MockRead CreateMockRead(const SpdyFrame& resp);
+
+// Create a MockRead from the given SpdyFrame and sequence number.
+MockRead CreateMockRead(const SpdyFrame& resp, int seq);
+
+MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode);
+
+// Combines the given SpdyFrames into the given char array and returns
+// the total length.
+int CombineFrames(const SpdyFrame** frames, int num_frames,
+                  char* buff, int buff_len);
+
+// Helper to manage the lifetimes of the dependencies for a
+// HttpNetworkTransaction.
+struct SpdySessionDependencies {
+  // Default set of dependencies -- "null" proxy service.
+  SpdySessionDependencies();
+
+  // Custom proxy service dependency.
+  explicit SpdySessionDependencies(ProxyService* proxy_service);
+
+  ~SpdySessionDependencies();
+
+  static HttpNetworkSession* SpdyCreateSession(
+      SpdySessionDependencies* session_deps);
+  static HttpNetworkSession* SpdyCreateSessionDeterministic(
+      SpdySessionDependencies* session_deps);
+  static HttpNetworkSession::Params CreateSessionParams(
+      SpdySessionDependencies* session_deps);
+
+  // NOTE: host_resolver must be ordered before http_auth_handler_factory.
+  scoped_ptr<MockHostResolverBase> host_resolver;
+  scoped_ptr<CertVerifier> cert_verifier;
+  scoped_ptr<ProxyService> proxy_service;
+  scoped_refptr<SSLConfigService> ssl_config_service;
+  scoped_ptr<MockClientSocketFactory> socket_factory;
+  scoped_ptr<DeterministicMockClientSocketFactory> deterministic_socket_factory;
+  scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
+  HttpServerPropertiesImpl http_server_properties;
+  bool enable_ip_pooling;
+  bool enable_compression;
+  bool enable_ping;
+  SpdySession::TimeFunc time_func;
+  std::string trusted_spdy_proxy;
+  NetLog* net_log;
+};
+
+class SpdyURLRequestContext : public URLRequestContext {
+ public:
+  SpdyURLRequestContext();
+  virtual ~SpdyURLRequestContext();
+
+  MockClientSocketFactory& socket_factory() { return socket_factory_; }
+
+ private:
+  MockClientSocketFactory socket_factory_;
+  net::URLRequestContextStorage storage_;
+};
+
+const SpdyHeaderInfo MakeSpdyHeader(SpdyControlType type);
+
+class SpdySessionPoolPeer {
+ public:
+  explicit SpdySessionPoolPeer(SpdySessionPool* pool)
+      : pool_(pool) {}
+
+  void AddAlias(const IPEndPoint& address, const HostPortProxyPair& pair) {
+    pool_->AddAlias(address, pair);
+  }
+
+  void RemoveAliases(const HostPortProxyPair& pair) {
+    pool_->RemoveAliases(pair);
+  }
+
+  void RemoveSpdySession(const scoped_refptr<SpdySession>& session) {
+    pool_->Remove(session);
+  }
+
+  void DisableDomainAuthenticationVerification() {
+    pool_->verify_domain_authentication_ = false;
+  }
+
+  void EnableSendingInitialSettings(bool enabled) {
+    pool_->enable_sending_initial_settings_ = enabled;
+  }
+
+ private:
+  SpdySessionPool* const pool_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdySessionPoolPeer);
+};
+
+}  // namespace test_spdy2
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_TEST_UTIL_H_
diff --git a/src/net/spdy/spdy_test_util_spdy3.cc b/src/net/spdy/spdy_test_util_spdy3.cc
new file mode 100644
index 0000000..79d8100
--- /dev/null
+++ b/src/net/spdy/spdy_test_util_spdy3.cc
@@ -0,0 +1,1033 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_test_util_spdy3.h"
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "net/base/mock_cert_verifier.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_network_transaction.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_session.h"
+
+namespace net {
+
+namespace test_spdy3 {
+
+namespace {
+
+// Parses a URL into the scheme, host, and path components required for a
+// SPDY request.
+void ParseUrl(const char* const url, std::string* scheme, std::string* host,
+              std::string* path) {
+  GURL gurl(url);
+  path->assign(gurl.PathForRequest());
+  scheme->assign(gurl.scheme());
+  host->assign(gurl.host());
+  if (gurl.has_port()) {
+    host->append(":");
+    host->append(gurl.port());
+  }
+}
+
+}  // namespace
+
+
+MockECSignatureCreator::MockECSignatureCreator(crypto::ECPrivateKey* key)
+    : key_(key) {
+}
+
+bool MockECSignatureCreator::Sign(const uint8* data,
+                                  int data_len,
+                                  std::vector<uint8>* signature) {
+  std::vector<uint8> private_key_value;
+  key_->ExportValue(&private_key_value);
+  std::string head = "fakesignature";
+  std::string tail = "/fakesignature";
+
+  signature->clear();
+  signature->insert(signature->end(), head.begin(), head.end());
+  signature->insert(signature->end(), private_key_value.begin(),
+                    private_key_value.end());
+  signature->insert(signature->end(), '-');
+  signature->insert(signature->end(), data, data + data_len);
+  signature->insert(signature->end(), tail.begin(), tail.end());
+  return true;
+}
+
+bool MockECSignatureCreator::DecodeSignature(
+    const std::vector<uint8>& signature,
+    std::vector<uint8>* out_raw_sig) {
+  *out_raw_sig = signature;
+  return true;
+}
+
+MockECSignatureCreatorFactory::MockECSignatureCreatorFactory() {
+  crypto::ECSignatureCreator::SetFactoryForTesting(this);
+}
+
+MockECSignatureCreatorFactory::~MockECSignatureCreatorFactory() {
+  crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
+}
+
+crypto::ECSignatureCreator* MockECSignatureCreatorFactory::Create(
+    crypto::ECPrivateKey* key) {
+  return new MockECSignatureCreator(key);
+}
+
+// Chop a frame into an array of MockWrites.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) {
+  MockWrite* chunks = new MockWrite[num_chunks];
+  int chunk_size = length / num_chunks;
+  for (int index = 0; index < num_chunks; index++) {
+    const char* ptr = data + (index * chunk_size);
+    if (index == num_chunks - 1)
+      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
+    chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
+  }
+  return chunks;
+}
+
+// Chop a SpdyFrame into an array of MockWrites.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks) {
+  return ChopWriteFrame(frame.data(),
+                        frame.length() + SpdyFrame::kHeaderSize,
+                        num_chunks);
+}
+
+// Chop a frame into an array of MockReads.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const char* data, int length, int num_chunks) {
+  MockRead* chunks = new MockRead[num_chunks];
+  int chunk_size = length / num_chunks;
+  for (int index = 0; index < num_chunks; index++) {
+    const char* ptr = data + (index * chunk_size);
+    if (index == num_chunks - 1)
+      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
+    chunks[index] = MockRead(ASYNC, ptr, chunk_size);
+  }
+  return chunks;
+}
+
+// Chop a SpdyFrame into an array of MockReads.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks) {
+  return ChopReadFrame(frame.data(),
+                       frame.length() + SpdyFrame::kHeaderSize,
+                       num_chunks);
+}
+
+// Adds headers and values to a map.
+// |extra_headers| is an array of { name, value } pairs, arranged as strings
+// where the even entries are the header names, and the odd entries are the
+// header values.
+// |headers| gets filled in from |extra_headers|.
+void AppendHeadersToSpdyFrame(const char* const extra_headers[],
+                              int extra_header_count,
+                              SpdyHeaderBlock* headers) {
+  std::string this_header;
+  std::string this_value;
+
+  if (!extra_header_count)
+    return;
+
+  // Sanity check: Non-NULL header list.
+  DCHECK(NULL != extra_headers) << "NULL header value pair list";
+  // Sanity check: Non-NULL header map.
+  DCHECK(NULL != headers) << "NULL header map";
+  // Copy in the headers.
+  for (int i = 0; i < extra_header_count; i++) {
+    // Sanity check: Non-empty header.
+    DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
+    this_header = extra_headers[i * 2];
+    std::string::size_type header_len = this_header.length();
+    if (!header_len)
+      continue;
+    this_value = extra_headers[1 + (i * 2)];
+    std::string new_value;
+    if (headers->find(this_header) != headers->end()) {
+      // More than one entry in the header.
+      // Don't add the header again, just the append to the value,
+      // separated by a NULL character.
+
+      // Adjust the value.
+      new_value = (*headers)[this_header];
+      // Put in a NULL separator.
+      new_value.append(1, '\0');
+      // Append the new value.
+      new_value += this_value;
+    } else {
+      // Not a duplicate, just write the value.
+      new_value = this_value;
+    }
+    (*headers)[this_header] = new_value;
+  }
+}
+
+// Writes |val| to a location of size |len|, in big-endian format.
+// in the buffer pointed to by |buffer_handle|.
+// Updates the |*buffer_handle| pointer by |len|
+// Returns the number of bytes written
+int AppendToBuffer(int val,
+                   int len,
+                   unsigned char** buffer_handle,
+                   int* buffer_len_remaining) {
+  if (len <= 0)
+    return 0;
+  DCHECK((size_t) len <= sizeof(len)) << "Data length too long for data type";
+  DCHECK(NULL != buffer_handle) << "NULL buffer handle";
+  DCHECK(NULL != *buffer_handle) << "NULL pointer";
+  DCHECK(NULL != buffer_len_remaining)
+      << "NULL buffer remainder length pointer";
+  DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
+  for (int i = 0; i < len; i++) {
+    int shift = (8 * (len - (i + 1)));
+    unsigned char val_chunk = (val >> shift) & 0x0FF;
+    *(*buffer_handle)++ = val_chunk;
+    *buffer_len_remaining += 1;
+  }
+  return len;
+}
+
+// Construct a SPDY packet.
+// |head| is the start of the packet, up to but not including
+// the header value pairs.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |tail| is any (relatively constant) header-value pairs to add.
+// |buffer| is the buffer we're filling in.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info,
+                               const char* const extra_headers[],
+                               int extra_header_count,
+                               const char* const tail[],
+                               int tail_header_count) {
+  BufferedSpdyFramer framer(3, header_info.compressed);
+  SpdyHeaderBlock headers;
+  // Copy in the extra headers to our map.
+  AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
+  // Copy in the tail headers to our map.
+  if (tail && tail_header_count)
+    AppendHeadersToSpdyFrame(tail, tail_header_count, &headers);
+  SpdyFrame* frame = NULL;
+  switch (header_info.kind) {
+    case SYN_STREAM:
+      frame = framer.CreateSynStream(header_info.id, header_info.assoc_id,
+                                     header_info.priority,
+                                     header_info.credential_slot,
+                                     header_info.control_flags,
+                                     header_info.compressed, &headers);
+      break;
+    case SYN_REPLY:
+      frame = framer.CreateSynReply(header_info.id, header_info.control_flags,
+                                    header_info.compressed, &headers);
+      break;
+    case RST_STREAM:
+      frame = framer.CreateRstStream(header_info.id, header_info.status);
+      break;
+    case HEADERS:
+      frame = framer.CreateHeaders(header_info.id, header_info.control_flags,
+                                   header_info.compressed, &headers);
+      break;
+    default:
+      frame = framer.CreateDataFrame(header_info.id, header_info.data,
+                                     header_info.data_length,
+                                     header_info.data_flags);
+      break;
+  }
+  return frame;
+}
+
+// Construct an expected SPDY SETTINGS frame.
+// |settings| are the settings to set.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdySettings(const SettingsMap& settings) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateSettings(settings);
+}
+
+// Construct an expected SPDY CREDENTIAL frame.
+// |credential| is the credential to sen.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyCredential(
+    const SpdyCredential& credential) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateCredentialFrame(credential);
+}
+
+// Construct a SPDY PING frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyPing(uint32 ping_id) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreatePingFrame(ping_id);
+}
+
+// Construct a SPDY GOAWAY frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyGoAway() {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateGoAway(0, GOAWAY_OK);
+}
+
+// Construct a SPDY WINDOW_UPDATE frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyWindowUpdate(
+    const SpdyStreamId stream_id, uint32 delta_window_size) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateWindowUpdate(stream_id, delta_window_size);
+}
+
+// Construct a SPDY RST_STREAM frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyRstStream(SpdyStreamId stream_id,
+                                  SpdyStatusCodes status) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateRstStream(stream_id, status);
+}
+
+// Construct a single SPDY header entry, for validation.
+// |extra_headers| are the extra header-value pairs.
+// |buffer| is the buffer we're filling in.
+// |index| is the index of the header we want.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyHeader(const char* const extra_headers[],
+                        int extra_header_count,
+                        char* buffer,
+                        int buffer_length,
+                        int index) {
+  const char* this_header = NULL;
+  const char* this_value = NULL;
+  if (!buffer || !buffer_length)
+    return 0;
+  *buffer = '\0';
+  // Sanity check: Non-empty header list.
+  DCHECK(NULL != extra_headers) << "NULL extra headers pointer";
+  // Sanity check: Index out of range.
+  DCHECK((index >= 0) && (index < extra_header_count))
+      << "Index " << index
+      << " out of range [0, " << extra_header_count << ")";
+  this_header = extra_headers[index * 2];
+  // Sanity check: Non-empty header.
+  if (!*this_header)
+    return 0;
+  std::string::size_type header_len = strlen(this_header);
+  if (!header_len)
+    return 0;
+  this_value = extra_headers[1 + (index * 2)];
+  // Sanity check: Non-empty value.
+  if (!*this_value)
+    this_value = "";
+  int n = base::snprintf(buffer,
+                         buffer_length,
+                         "%s: %s\r\n",
+                         this_header,
+                         this_value);
+  return n;
+}
+
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize) {
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   compressed,
+                                   stream_id,
+                                   request_priority,
+                                   type,
+                                   flags,
+                                   kHeaders,
+                                   kHeadersSize,
+                                   0);
+}
+
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize,
+                                     int associated_stream_id) {
+  const SpdyHeaderInfo kSynStartHeader = {
+    type,                         // Kind = Syn
+    stream_id,                    // Stream ID
+    associated_stream_id,         // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(request_priority, 3),
+                                  // Priority
+    0,                            // Credential Slot
+    flags,                        // Control Flags
+    compressed,                   // Compressed
+    INVALID,                      // Status
+    NULL,                         // Data
+    0,                            // Length
+    DATA_FLAG_NONE                // Data Flags
+  };
+  return ConstructSpdyPacket(kSynStartHeader,
+                             extra_headers,
+                             extra_header_count,
+                             kHeaders,
+                             kHeadersSize / 2);
+}
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed
+// for the url |url|.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const url,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority) {
+  const SpdyHeaderInfo kSynStartHeader = {
+    SYN_STREAM,                   // Kind = Syn
+    stream_id,                    // Stream ID
+    0,                            // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(request_priority, 3),
+                                  // Priority
+    0,                            // Credential Slot
+    CONTROL_FLAG_FIN,             // Control Flags
+    compressed,                   // Compressed
+    INVALID,                      // Status
+    NULL,                         // Data
+    0,                            // Length
+    DATA_FLAG_NONE                // Data Flags
+  };
+
+  std::string scheme, host, path;
+  ParseUrl(url, &scheme, &host, &path);
+  const char* const headers[] = {
+    ":method", "GET",
+    ":path", path.c_str(),
+    ":host", host.c_str(),
+    ":scheme", scheme.c_str(),
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyPacket(
+      kSynStartHeader,
+      NULL,
+      0,
+      headers,
+      arraysize(headers) / 2);
+}
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority) {
+  return ConstructSpdyGet(extra_headers, extra_header_count, compressed,
+                          stream_id, request_priority, true);
+}
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority,
+                            bool direct) {
+  const char* const kStandardGetHeaders[] = {
+    ":method", "GET",
+    ":host", "www.google.com",
+    ":scheme", "http",
+    ":version", "HTTP/1.1",
+    ":path", (direct ? "/" : "/")
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   compressed,
+                                   stream_id,
+                                   request_priority,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_FIN,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
+SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
+                                int extra_header_count,
+                                int stream_id) {
+  const char* const kConnectHeaders[] = {
+    ":method", "CONNECT",
+    ":path", "www.google.com:443",
+    ":host", "www.google.com",
+    ":version", "HTTP/1.1",
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   /*compressed*/ false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kConnectHeaders,
+                                   arraysize(kConnectHeaders));
+}
+
+// Constructs a standard SPDY push SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id) {
+  const char* const kStandardPushHeaders[] = {
+    "hello", "bye",
+    ":status",  "200",
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardPushHeaders,
+                                   arraysize(kStandardPushHeaders),
+                                   associated_stream_id);
+}
+
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url) {
+  std::string scheme, host, path;
+  ParseUrl(url, &scheme, &host, &path);
+  const char* const headers[] = {
+    "hello",    "bye",
+    ":status",  "200 OK",
+    ":version", "HTTP/1.1",
+    ":path",    path.c_str(),
+    ":host",    host.c_str(),
+    ":scheme",  scheme.c_str(),
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   headers,
+                                   arraysize(headers),
+                                   associated_stream_id);
+
+}
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url,
+                             const char* status,
+                             const char* location) {
+  std::string scheme, host, path;
+  ParseUrl(url, &scheme, &host, &path);
+  const char* const headers[] = {
+    "hello",    "bye",
+    ":status",  status,
+    "location", location,
+    ":path",    path.c_str(),
+    ":host",    host.c_str(),
+    ":scheme",  scheme.c_str(),
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   headers,
+                                   arraysize(headers),
+                                   associated_stream_id);
+}
+
+SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
+                                    const char* const extra_headers[],
+                                    int extra_header_count) {
+  const char* const kStandardGetHeaders[] = {
+    ":status", "200 OK",
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   HEADERS,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY SYN_REPLY packet with the specified status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(const char* const status,
+                                      const char* const* const extra_headers,
+                                      int extra_header_count,
+                                      int stream_id) {
+  const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    ":status",  status,
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) {
+  static const char* const kExtraHeaders[] = {
+    "location", "http://www.foo.com/index.php",
+  };
+  return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders,
+                                    arraysize(kExtraHeaders)/2, stream_id);
+}
+
+// Constructs a standard SPDY SYN_REPLY packet with an Internal Server
+// Error status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(int stream_id) {
+  return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1);
+}
+
+
+
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
+                                    int extra_header_count,
+                                    int stream_id) {
+  static const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    ":status", "200",
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a standard SPDY POST SYN packet.
+// |content_length| is the size of post data.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPost(int64 content_length,
+                             const char* const extra_headers[],
+                             int extra_header_count) {
+  std::string length_str = base::Int64ToString(content_length);
+  const char* post_headers[] = {
+    ":method", "POST",
+    ":path", "/",
+    ":host", "www.google.com",
+    ":scheme", "http",
+    ":version", "HTTP/1.1",
+    "content-length",  length_str.c_str()
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   1,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   post_headers,
+                                   arraysize(post_headers));
+}
+
+// Constructs a chunked transfer SPDY POST SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
+                                    int extra_header_count) {
+  const char* post_headers[] = {
+    ":method", "POST",
+    ":path", "/",
+    ":host", "www.google.com",
+    ":scheme", "http",
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   1,
+                                   LOWEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   post_headers,
+                                   arraysize(post_headers));
+}
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
+                                     int extra_header_count) {
+  static const char* const kStandardGetHeaders[] = {
+    "hello", "bye",
+    ":status", "200",
+    "url", "/index.php",
+    ":version", "HTTP/1.1"
+  };
+  return ConstructSpdyControlFrame(extra_headers,
+                                   extra_header_count,
+                                   false,
+                                   1,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardGetHeaders,
+                                   arraysize(kStandardGetHeaders));
+}
+
+// Constructs a single SPDY data frame with the default contents.
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id, bool fin) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateDataFrame(
+      stream_id, kUploadData, kUploadDataSize,
+      fin ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+// Constructs a single SPDY data frame with the given content.
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
+                                  uint32 len, bool fin) {
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateDataFrame(
+      stream_id, data, len, fin ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+// Wraps |frame| in the payload of a data frame in stream |stream_id|.
+SpdyFrame* ConstructWrappedSpdyFrame(const scoped_ptr<SpdyFrame>& frame,
+                                     int stream_id) {
+  return ConstructSpdyBodyFrame(stream_id, frame->data(),
+                                frame->length() + SpdyFrame::kHeaderSize,
+                                false);
+}
+
+// Construct an expected SPDY reply string.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |buffer| is the buffer we're filling in.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyReplyString(const char* const extra_headers[],
+                             int extra_header_count,
+                             char* buffer,
+                             int buffer_length) {
+  int packet_size = 0;
+  char* buffer_write = buffer;
+  int buffer_left = buffer_length;
+  SpdyHeaderBlock headers;
+  if (!buffer || !buffer_length)
+    return 0;
+  // Copy in the extra headers.
+  AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
+  // The iterator gets us the list of header/value pairs in sorted order.
+  SpdyHeaderBlock::iterator next = headers.begin();
+  SpdyHeaderBlock::iterator last = headers.end();
+  for ( ; next != last; ++next) {
+    // Write the header.
+    int value_len, current_len, offset;
+    const char* header_string = next->first.c_str();
+    if (header_string && header_string[0] == ':')
+      header_string++;
+    packet_size += AppendToBuffer(header_string,
+                                  strlen(header_string),
+                                  &buffer_write,
+                                  &buffer_left);
+    packet_size += AppendToBuffer(": ",
+                                  strlen(": "),
+                                  &buffer_write,
+                                  &buffer_left);
+    // Write the value(s).
+    const char* value_string = next->second.c_str();
+    // Check if it's split among two or more values.
+    value_len = next->second.length();
+    current_len = strlen(value_string);
+    offset = 0;
+    // Handle the first N-1 values.
+    while (current_len < value_len) {
+      // Finish this line -- write the current value.
+      packet_size += AppendToBuffer(value_string + offset,
+                                    current_len - offset,
+                                    &buffer_write,
+                                    &buffer_left);
+      packet_size += AppendToBuffer("\n",
+                                    strlen("\n"),
+                                    &buffer_write,
+                                    &buffer_left);
+      // Advance to next value.
+      offset = current_len + 1;
+      current_len += 1 + strlen(value_string + offset);
+      // Start another line -- add the header again.
+      packet_size += AppendToBuffer(header_string,
+                                    next->first.length(),
+                                    &buffer_write,
+                                    &buffer_left);
+      packet_size += AppendToBuffer(": ",
+                                    strlen(": "),
+                                    &buffer_write,
+                                    &buffer_left);
+    }
+    EXPECT_EQ(value_len, current_len);
+    // Copy the last (or only) value.
+    packet_size += AppendToBuffer(value_string + offset,
+                                  value_len - offset,
+                                  &buffer_write,
+                                  &buffer_left);
+    packet_size += AppendToBuffer("\n",
+                                  strlen("\n"),
+                                  &buffer_write,
+                                  &buffer_left);
+  }
+  return packet_size;
+}
+
+// Create a MockWrite from the given SpdyFrame.
+MockWrite CreateMockWrite(const SpdyFrame& req) {
+  return MockWrite(
+      ASYNC, req.data(), req.length() + SpdyFrame::kHeaderSize);
+}
+
+// Create a MockWrite from the given SpdyFrame and sequence number.
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq) {
+  return CreateMockWrite(req, seq, ASYNC);
+}
+
+// Create a MockWrite from the given SpdyFrame and sequence number.
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode) {
+  return MockWrite(
+      mode, req.data(), req.length() + SpdyFrame::kHeaderSize, seq);
+}
+
+// Create a MockRead from the given SpdyFrame.
+MockRead CreateMockRead(const SpdyFrame& resp) {
+  return MockRead(
+      ASYNC, resp.data(), resp.length() + SpdyFrame::kHeaderSize);
+}
+
+// Create a MockRead from the given SpdyFrame and sequence number.
+MockRead CreateMockRead(const SpdyFrame& resp, int seq) {
+  return CreateMockRead(resp, seq, ASYNC);
+}
+
+// Create a MockRead from the given SpdyFrame and sequence number.
+MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode) {
+  return MockRead(
+      mode, resp.data(), resp.length() + SpdyFrame::kHeaderSize, seq);
+}
+
+// Combines the given SpdyFrames into the given char array and returns
+// the total length.
+int CombineFrames(const SpdyFrame** frames, int num_frames,
+                  char* buff, int buff_len) {
+  int total_len = 0;
+  for (int i = 0; i < num_frames; ++i) {
+    total_len += frames[i]->length() + SpdyFrame::kHeaderSize;
+  }
+  DCHECK_LE(total_len, buff_len);
+  char* ptr = buff;
+  for (int i = 0; i < num_frames; ++i) {
+    int len = frames[i]->length() + SpdyFrame::kHeaderSize;
+    memcpy(ptr, frames[i]->data(), len);
+    ptr += len;
+  }
+  return total_len;
+}
+
+SpdySessionDependencies::SpdySessionDependencies()
+    : host_resolver(new MockCachingHostResolver),
+      cert_verifier(new MockCertVerifier),
+      proxy_service(ProxyService::CreateDirect()),
+      ssl_config_service(new SSLConfigServiceDefaults),
+      socket_factory(new MockClientSocketFactory),
+      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
+      http_auth_handler_factory(
+          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
+      enable_ip_pooling(true),
+      enable_compression(false),
+      enable_ping(false),
+      initial_recv_window_size(kSpdyStreamInitialWindowSize),
+      time_func(&base::TimeTicks::Now),
+      net_log(NULL) {
+  // Note: The CancelledTransaction test does cleanup by running all
+  // tasks in the message loop (RunAllPending).  Unfortunately, that
+  // doesn't clean up tasks on the host resolver thread; and
+  // TCPConnectJob is currently not cancellable.  Using synchronous
+  // lookups allows the test to shutdown cleanly.  Until we have
+  // cancellable TCPConnectJobs, use synchronous lookups.
+  host_resolver->set_synchronous_mode(true);
+}
+
+SpdySessionDependencies::SpdySessionDependencies(ProxyService* proxy_service)
+    : host_resolver(new MockHostResolver),
+      cert_verifier(new MockCertVerifier),
+      proxy_service(proxy_service),
+      ssl_config_service(new SSLConfigServiceDefaults),
+      socket_factory(new MockClientSocketFactory),
+      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
+      http_auth_handler_factory(
+          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
+      enable_ip_pooling(true),
+      enable_compression(false),
+      enable_ping(false),
+      initial_recv_window_size(kSpdyStreamInitialWindowSize),
+      time_func(&base::TimeTicks::Now),
+      net_log(NULL) {}
+
+SpdySessionDependencies::~SpdySessionDependencies() {}
+
+// static
+HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
+    SpdySessionDependencies* session_deps) {
+  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
+  params.client_socket_factory = session_deps->socket_factory.get();
+  HttpNetworkSession* http_session = new HttpNetworkSession(params);
+  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
+  pool_peer.EnableSendingInitialSettings(false);
+  return http_session;
+}
+
+// static
+HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
+    SpdySessionDependencies* session_deps) {
+  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
+  params.client_socket_factory =
+      session_deps->deterministic_socket_factory.get();
+  HttpNetworkSession* http_session = new HttpNetworkSession(params);
+  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
+  pool_peer.EnableSendingInitialSettings(false);
+  return http_session;
+}
+
+// static
+net::HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
+    SpdySessionDependencies* session_deps) {
+  net::HttpNetworkSession::Params params;
+  params.host_resolver = session_deps->host_resolver.get();
+  params.cert_verifier = session_deps->cert_verifier.get();
+  params.proxy_service = session_deps->proxy_service.get();
+  params.ssl_config_service = session_deps->ssl_config_service;
+  params.http_auth_handler_factory =
+      session_deps->http_auth_handler_factory.get();
+  params.http_server_properties = &session_deps->http_server_properties;
+  params.enable_spdy_compression = session_deps->enable_compression;
+  params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping;
+  params.spdy_default_protocol = kProtoSPDY3;
+  params.spdy_initial_recv_window_size = session_deps->initial_recv_window_size;
+  params.time_func = session_deps->time_func;
+  params.trusted_spdy_proxy = session_deps->trusted_spdy_proxy;
+  params.net_log = session_deps->net_log;
+  return params;
+}
+
+SpdyURLRequestContext::SpdyURLRequestContext()
+    : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
+  storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
+  storage_.set_cert_verifier(new MockCertVerifier);
+  storage_.set_proxy_service(ProxyService::CreateDirect());
+  storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
+  storage_.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
+      host_resolver()));
+  storage_.set_http_server_properties(new HttpServerPropertiesImpl);
+  net::HttpNetworkSession::Params params;
+  params.client_socket_factory = &socket_factory_;
+  params.host_resolver = host_resolver();
+  params.cert_verifier = cert_verifier();
+  params.proxy_service = proxy_service();
+  params.ssl_config_service = ssl_config_service();
+  params.http_auth_handler_factory = http_auth_handler_factory();
+  params.network_delegate = network_delegate();
+  params.enable_spdy_compression = false;
+  params.enable_spdy_ping_based_connection_checking = false;
+  params.spdy_default_protocol = kProtoSPDY3;
+  params.http_server_properties = http_server_properties();
+  scoped_refptr<HttpNetworkSession> network_session(
+      new HttpNetworkSession(params));
+  SpdySessionPoolPeer pool_peer(network_session->spdy_session_pool());
+  pool_peer.EnableSendingInitialSettings(false);
+  storage_.set_http_transaction_factory(new HttpCache(
+      network_session,
+      HttpCache::DefaultBackend::InMemory(0)));
+}
+
+SpdyURLRequestContext::~SpdyURLRequestContext() {
+}
+
+const SpdyHeaderInfo MakeSpdyHeader(SpdyControlType type) {
+  const SpdyHeaderInfo kHeader = {
+    type,                         // Kind = Syn
+    1,                            // Stream ID
+    0,                            // Associated stream ID
+    ConvertRequestPriorityToSpdyPriority(LOWEST, 3),  // Priority
+    0,                            // Credential Slot
+    CONTROL_FLAG_FIN,       // Control Flags
+    false,                        // Compressed
+    INVALID,                // Status
+    NULL,                         // Data
+    0,                            // Length
+    DATA_FLAG_NONE          // Data Flags
+  };
+  return kHeader;
+}
+
+}  // namespace test_spdy3
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_test_util_spdy3.h b/src/net/spdy/spdy_test_util_spdy3.h
new file mode 100644
index 0000000..5103c89
--- /dev/null
+++ b/src/net/spdy/spdy_test_util_spdy3.h
@@ -0,0 +1,466 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_TEST_UTIL_H_
+#define NET_SPDY_SPDY_TEST_UTIL_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "crypto/ec_private_key.h"
+#include "crypto/ec_signature_creator.h"
+#include "net/base/cert_verifier.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/request_priority.h"
+#include "net/base/ssl_config_service_defaults.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_network_layer.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/proxy/proxy_service.h"
+#include "net/socket/socket_test_util.h"
+#include "net/spdy/spdy_session.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_storage.h"
+
+namespace crypto {
+class ECSignatureCreatorFactory;
+}
+
+namespace net {
+
+namespace test_spdy3 {
+
+// Default upload data used by both, mock objects and framer when creating
+// data frames.
+const char kDefaultURL[] = "http://www.google.com";
+const char kUploadData[] = "hello!";
+const int kUploadDataSize = arraysize(kUploadData)-1;
+
+// NOTE: In GCC, on a Mac, this can't be in an anonymous namespace!
+// This struct holds information used to construct spdy control and data frames.
+struct SpdyHeaderInfo {
+  SpdyControlType kind;
+  SpdyStreamId id;
+  SpdyStreamId assoc_id;
+  SpdyPriority priority;
+  size_t credential_slot;
+  SpdyControlFlags control_flags;
+  bool compressed;
+  SpdyStatusCodes status;
+  const char* data;
+  uint32 data_length;
+  SpdyDataFlags data_flags;
+};
+
+// An ECSignatureCreator that returns deterministic signatures.
+class MockECSignatureCreator : public crypto::ECSignatureCreator {
+ public:
+  explicit MockECSignatureCreator(crypto::ECPrivateKey* key);
+
+  // crypto::ECSignatureCreator
+  virtual bool Sign(const uint8* data,
+                    int data_len,
+                    std::vector<uint8>* signature) OVERRIDE;
+  virtual bool DecodeSignature(const std::vector<uint8>& signature,
+                               std::vector<uint8>* out_raw_sig) OVERRIDE;
+
+ private:
+  crypto::ECPrivateKey* key_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockECSignatureCreator);
+};
+
+// An ECSignatureCreatorFactory creates MockECSignatureCreator.
+class MockECSignatureCreatorFactory : public crypto::ECSignatureCreatorFactory {
+ public:
+  MockECSignatureCreatorFactory();
+  virtual ~MockECSignatureCreatorFactory();
+
+  // crypto::ECSignatureCreatorFactory
+  virtual crypto::ECSignatureCreator* Create(
+      crypto::ECPrivateKey* key) OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockECSignatureCreatorFactory);
+};
+
+// Chop a frame into an array of MockWrites.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks);
+
+// Chop a SpdyFrame into an array of MockWrites.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks);
+
+// Chop a frame into an array of MockReads.
+// |data| is the frame to chop.
+// |length| is the length of the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const char* data, int length, int num_chunks);
+
+// Chop a SpdyFrame into an array of MockReads.
+// |frame| is the frame to chop.
+// |num_chunks| is the number of chunks to create.
+MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks);
+
+// Adds headers and values to a map.
+// |extra_headers| is an array of { name, value } pairs, arranged as strings
+// where the even entries are the header names, and the odd entries are the
+// header values.
+// |headers| gets filled in from |extra_headers|.
+void AppendHeadersToSpdyFrame(const char* const extra_headers[],
+                              int extra_header_count,
+                              SpdyHeaderBlock* headers);
+
+// Writes |str| of the given |len| to the buffer pointed to by |buffer_handle|.
+// Uses a template so buffer_handle can be a char* or an unsigned char*.
+// Updates the |*buffer_handle| pointer by |len|
+// Returns the number of bytes written into *|buffer_handle|
+template<class T>
+int AppendToBuffer(const char* str,
+                   int len,
+                   T** buffer_handle,
+                   int* buffer_len_remaining) {
+  DCHECK_GT(len, 0);
+  DCHECK(NULL != buffer_handle) << "NULL buffer handle";
+  DCHECK(NULL != *buffer_handle) << "NULL pointer";
+  DCHECK(NULL != buffer_len_remaining)
+      << "NULL buffer remainder length pointer";
+  DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
+  memcpy(*buffer_handle, str, len);
+  *buffer_handle += len;
+  *buffer_len_remaining -= len;
+  return len;
+}
+
+// Writes |val| to a location of size |len|, in big-endian format.
+// in the buffer pointed to by |buffer_handle|.
+// Updates the |*buffer_handle| pointer by |len|
+// Returns the number of bytes written
+int AppendToBuffer(int val,
+                   int len,
+                   unsigned char** buffer_handle,
+                   int* buffer_len_remaining);
+
+// Construct a SPDY packet.
+// |head| is the start of the packet, up to but not including
+// the header value pairs.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |tail| is any (relatively constant) header-value pairs to add.
+// |buffer| is the buffer we're filling in.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info,
+                               const char* const extra_headers[],
+                               int extra_header_count,
+                               const char* const tail[],
+                               int tail_header_count);
+
+// Construct a generic SpdyControlFrame.
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize);
+SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
+                                     int extra_header_count,
+                                     bool compressed,
+                                     int stream_id,
+                                     RequestPriority request_priority,
+                                     SpdyControlType type,
+                                     SpdyControlFlags flags,
+                                     const char* const* kHeaders,
+                                     int kHeadersSize,
+                                     int associated_stream_id);
+
+// Construct an expected SPDY reply string.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// |buffer| is the buffer we're filling in.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyReplyString(const char* const extra_headers[],
+                             int extra_header_count,
+                             char* buffer,
+                             int buffer_length);
+
+// Construct an expected SPDY SETTINGS frame.
+// |settings| are the settings to set.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdySettings(const SettingsMap& settings);
+
+// Construct an expected SPDY CREDENTIAL frame.
+// |credential| is the credential to send.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyCredential(const SpdyCredential& credential);
+
+// Construct a SPDY PING frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyPing(uint32 ping_id);
+
+// Construct a SPDY GOAWAY frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyGoAway();
+
+// Construct a SPDY WINDOW_UPDATE frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyWindowUpdate(SpdyStreamId, uint32 delta_window_size);
+
+// Construct a SPDY RST_STREAM frame.
+// Returns the constructed frame.  The caller takes ownership of the frame.
+SpdyFrame* ConstructSpdyRstStream(SpdyStreamId stream_id,
+                                  SpdyStatusCodes status);
+
+// Construct a single SPDY header entry, for validation.
+// |extra_headers| are the extra header-value pairs.
+// |buffer| is the buffer we're filling in.
+// |index| is the index of the header we want.
+// Returns the number of bytes written into |buffer|.
+int ConstructSpdyHeader(const char* const extra_headers[],
+                        int extra_header_count,
+                        char* buffer,
+                        int buffer_length,
+                        int index);
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed
+// for the url |url|.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const url,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority);
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority);
+
+// Constructs a standard SPDY GET SYN packet, optionally compressed.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.  If |direct| is false, the
+// the full url will be used instead of simply the path.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
+                            int extra_header_count,
+                            bool compressed,
+                            int stream_id,
+                            RequestPriority request_priority,
+                            bool direct);
+
+// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
+SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
+                                int extra_header_count,
+                                int stream_id);
+
+// Constructs a standard SPDY push SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id);
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url);
+SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
+                             int extra_header_count,
+                             int stream_id,
+                             int associated_stream_id,
+                             const char* url,
+                             const char* status,
+                             const char* location);
+SpdyFrame* ConstructSpdyPush(int stream_id,
+                             int associated_stream_id,
+                             const char* url);
+
+SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
+                                    const char* const extra_headers[],
+                                    int extra_header_count);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
+                                    int extra_header_count,
+                                    int stream_id);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id);
+
+// Constructs a standard SPDY SYN_REPLY packet with an Internal Server
+// Error status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(int stream_id);
+
+// Constructs a standard SPDY SYN_REPLY packet with the specified status code.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdySynReplyError(const char* const status,
+                                      const char* const* const extra_headers,
+                                      int extra_header_count,
+                                      int stream_id);
+
+// Constructs a standard SPDY POST SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPost(int64 content_length,
+                             const char* const extra_headers[],
+                             int extra_header_count);
+
+// Constructs a chunked transfer SPDY POST SYN packet.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
+                                    int extra_header_count);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
+// |extra_headers| are the extra header-value pairs, which typically
+// will vary the most between calls.
+// Returns a SpdyFrame.
+SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
+                                     int extra_header_count);
+
+// Constructs a single SPDY data frame with the contents "hello!"
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
+                                  bool fin);
+
+// Constructs a single SPDY data frame with the given content.
+SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
+                                  uint32 len, bool fin);
+
+// Wraps |frame| in the payload of a data frame in stream |stream_id|.
+SpdyFrame* ConstructWrappedSpdyFrame(const scoped_ptr<SpdyFrame>& frame,
+                                     int stream_id);
+
+// Create an async MockWrite from the given SpdyFrame.
+MockWrite CreateMockWrite(const SpdyFrame& req);
+
+// Create an async MockWrite from the given SpdyFrame and sequence number.
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq);
+
+MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode);
+
+// Create a MockRead from the given SpdyFrame.
+MockRead CreateMockRead(const SpdyFrame& resp);
+
+// Create a MockRead from the given SpdyFrame and sequence number.
+MockRead CreateMockRead(const SpdyFrame& resp, int seq);
+
+MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode);
+
+// Combines the given SpdyFrames into the given char array and returns
+// the total length.
+int CombineFrames(const SpdyFrame** frames, int num_frames,
+                  char* buff, int buff_len);
+
+// Helper to manage the lifetimes of the dependencies for a
+// HttpNetworkTransaction.
+struct SpdySessionDependencies {
+  // Default set of dependencies -- "null" proxy service.
+  SpdySessionDependencies();
+
+  // Custom proxy service dependency.
+  explicit SpdySessionDependencies(ProxyService* proxy_service);
+
+  ~SpdySessionDependencies();
+
+  static HttpNetworkSession* SpdyCreateSession(
+      SpdySessionDependencies* session_deps);
+  static HttpNetworkSession* SpdyCreateSessionDeterministic(
+      SpdySessionDependencies* session_deps);
+  static HttpNetworkSession::Params CreateSessionParams(
+      SpdySessionDependencies* session_deps);
+
+  // NOTE: host_resolver must be ordered before http_auth_handler_factory.
+  scoped_ptr<MockHostResolverBase> host_resolver;
+  scoped_ptr<CertVerifier> cert_verifier;
+  scoped_ptr<ProxyService> proxy_service;
+  scoped_refptr<SSLConfigService> ssl_config_service;
+  scoped_ptr<MockClientSocketFactory> socket_factory;
+  scoped_ptr<DeterministicMockClientSocketFactory> deterministic_socket_factory;
+  scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
+  HttpServerPropertiesImpl http_server_properties;
+  bool enable_ip_pooling;
+  bool enable_compression;
+  bool enable_ping;
+  size_t initial_recv_window_size;
+  SpdySession::TimeFunc time_func;
+  std::string trusted_spdy_proxy;
+  NetLog* net_log;
+};
+
+class SpdyURLRequestContext : public URLRequestContext {
+ public:
+  SpdyURLRequestContext();
+  virtual ~SpdyURLRequestContext();
+
+  MockClientSocketFactory& socket_factory() { return socket_factory_; }
+
+ private:
+  MockClientSocketFactory socket_factory_;
+  net::URLRequestContextStorage storage_;
+};
+
+const SpdyHeaderInfo MakeSpdyHeader(SpdyControlType type);
+
+class SpdySessionPoolPeer {
+ public:
+  explicit SpdySessionPoolPeer(SpdySessionPool* pool)
+      : pool_(pool) {}
+
+  void AddAlias(const IPEndPoint& address, const HostPortProxyPair& pair) {
+    pool_->AddAlias(address, pair);
+  }
+
+  void RemoveAliases(const HostPortProxyPair& pair) {
+    pool_->RemoveAliases(pair);
+  }
+
+  void RemoveSpdySession(const scoped_refptr<SpdySession>& session) {
+    pool_->Remove(session);
+  }
+
+  void DisableDomainAuthenticationVerification() {
+    pool_->verify_domain_authentication_ = false;
+  }
+
+  void EnableSendingInitialSettings(bool enabled) {
+    pool_->enable_sending_initial_settings_ = enabled;
+  }
+
+ private:
+  SpdySessionPool* const pool_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdySessionPoolPeer);
+};
+
+}  // namespace test_spdy3
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_TEST_UTIL_H_
diff --git a/src/net/spdy/spdy_websocket_stream.cc b/src/net/spdy/spdy_websocket_stream.cc
new file mode 100644
index 0000000..6323b71
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_stream.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_websocket_stream.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/io_buffer.h"
+#include "net/spdy/spdy_framer.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+SpdyWebSocketStream::SpdyWebSocketStream(
+    SpdySession* spdy_session, Delegate* delegate)
+    : stream_(NULL),
+      spdy_session_(spdy_session),
+      delegate_(delegate) {
+  DCHECK(spdy_session_);
+  DCHECK(delegate_);
+}
+
+SpdyWebSocketStream::~SpdyWebSocketStream() {
+  if (stream_) {
+    // If Close() has not already been called, DetachDelegate() will send a
+    // SPDY RST_STREAM. Deleting SpdyWebSocketStream is good enough to initiate
+    // graceful shutdown, so we call Close() to avoid sending a RST_STREAM.
+    // For safe, we should eliminate |delegate_| for OnClose() calback.
+    delegate_ = NULL;
+    stream_->Close();
+  }
+}
+
+int SpdyWebSocketStream::InitializeStream(const GURL& url,
+                                          RequestPriority request_priority,
+                                          const BoundNetLog& net_log) {
+  if (spdy_session_->IsClosed())
+    return ERR_SOCKET_NOT_CONNECTED;
+
+  int result = spdy_session_->CreateStream(
+      url, request_priority, &stream_, net_log,
+      base::Bind(&SpdyWebSocketStream::OnSpdyStreamCreated,
+                 base::Unretained(this)));
+
+  if (result == OK) {
+    DCHECK(stream_);
+    stream_->SetDelegate(this);
+  }
+  return result;
+}
+
+int SpdyWebSocketStream::SendRequest(scoped_ptr<SpdyHeaderBlock> headers) {
+  if (!stream_) {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+  stream_->set_spdy_headers(headers.Pass());
+  int result = stream_->SendRequest(true);
+  if (result < OK && result != ERR_IO_PENDING)
+    Close();
+  return result;
+}
+
+int SpdyWebSocketStream::SendData(const char* data, int length) {
+  if (!stream_) {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+  scoped_refptr<IOBuffer> buf(new IOBuffer(length));
+  memcpy(buf->data(), data, length);
+  return stream_->WriteStreamData(buf.get(), length, DATA_FLAG_NONE);
+}
+
+void SpdyWebSocketStream::Close() {
+  if (spdy_session_)
+    spdy_session_->CancelPendingCreateStreams(&stream_);
+  if (stream_)
+    stream_->Close();
+}
+
+bool SpdyWebSocketStream::OnSendHeadersComplete(int status) {
+  DCHECK(delegate_);
+  delegate_->OnSentSpdyHeaders(status);
+  return true;
+}
+
+int SpdyWebSocketStream::OnSendBody() {
+  NOTREACHED();
+  return ERR_UNEXPECTED;
+}
+
+int SpdyWebSocketStream::OnSendBodyComplete(int status, bool* eof) {
+  NOTREACHED();
+  *eof = true;
+  return ERR_UNEXPECTED;
+}
+
+int SpdyWebSocketStream::OnResponseReceived(
+    const SpdyHeaderBlock& response,
+    base::Time response_time, int status) {
+  DCHECK(delegate_);
+  return delegate_->OnReceivedSpdyResponseHeader(response, status);
+}
+
+void SpdyWebSocketStream::OnHeadersSent() {
+  // This will be called when WebSocket over SPDY supports new framing.
+  NOTREACHED();
+}
+
+int SpdyWebSocketStream::OnDataReceived(const char* data, int length) {
+  DCHECK(delegate_);
+  delegate_->OnReceivedSpdyData(data, length);
+  return OK;
+}
+
+void SpdyWebSocketStream::OnDataSent(int length) {
+  DCHECK(delegate_);
+  delegate_->OnSentSpdyData(length);
+}
+
+void SpdyWebSocketStream::OnClose(int status) {
+  stream_ = NULL;
+
+  // Destruction without Close() call OnClose() with delegate_ being NULL.
+  if (!delegate_)
+    return;
+  Delegate* delegate = delegate_;
+  delegate_ = NULL;
+  delegate->OnCloseSpdyStream();
+}
+
+void SpdyWebSocketStream::OnSpdyStreamCreated(int result) {
+  DCHECK_NE(ERR_IO_PENDING, result);
+  if (result == OK) {
+    DCHECK(stream_);
+    stream_->SetDelegate(this);
+  }
+  DCHECK(delegate_);
+  delegate_->OnCreatedSpdyStream(result);
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_websocket_stream.h b/src/net/spdy/spdy_websocket_stream.h
new file mode 100644
index 0000000..5ab4c48
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_stream.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_WEBSOCKET_STREAM_H_
+#define NET_SPDY_SPDY_WEBSOCKET_STREAM_H_
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time.h"
+#include "net/base/completion_callback.h"
+#include "net/base/request_priority.h"
+#include "net/spdy/spdy_framer.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+// The SpdyWebSocketStream is a WebSocket-specific type of stream known to a
+// SpdySession. WebSocket's opening handshake is converted to SPDY's
+// SYN_STREAM/SYN_REPLY. WebSocket frames are encapsulated as SPDY data frames.
+class NET_EXPORT_PRIVATE SpdyWebSocketStream
+    : public SpdyStream::Delegate {
+ public:
+  // Delegate handles asynchronous events.
+  class NET_EXPORT_PRIVATE Delegate {
+   public:
+    // Called when InitializeStream() finishes asynchronously. This delegate is
+    // called if InitializeStream() returns ERR_IO_PENDING. |status| indicates
+    // network error.
+    virtual void OnCreatedSpdyStream(int status) = 0;
+
+    // Called on corresponding to OnSendHeadersComplete() or SPDY's SYN frame
+    // has been sent.
+    virtual void OnSentSpdyHeaders(int status) = 0;
+
+    // Called on corresponding to OnResponseReceived() or SPDY's SYN_STREAM,
+    // SYN_REPLY, or HEADERS frames are received. This callback may be called
+    // multiple times as SPDY's delegate does.
+    virtual int OnReceivedSpdyResponseHeader(
+        const SpdyHeaderBlock& headers,
+        int status) = 0;
+
+    // Called when data is sent.
+    virtual void OnSentSpdyData(int amount_sent) = 0;
+
+    // Called when data is received.
+    virtual void OnReceivedSpdyData(const char* data, int length) = 0;
+
+    // Called when SpdyStream is closed.
+    virtual void OnCloseSpdyStream() = 0;
+
+   protected:
+    virtual ~Delegate() {}
+  };
+
+  SpdyWebSocketStream(SpdySession* spdy_session, Delegate* delegate);
+  virtual ~SpdyWebSocketStream();
+
+  // Initializes SPDY stream for the WebSocket.
+  // It might create SPDY stream asynchronously.  In this case, this method
+  // returns ERR_IO_PENDING and call OnCreatedSpdyStream delegate with result
+  // after completion. In other cases, delegate does not be called.
+  int InitializeStream(const GURL& url,
+                       RequestPriority request_priority,
+                       const BoundNetLog& stream_net_log);
+
+  int SendRequest(scoped_ptr<SpdyHeaderBlock> headers);
+  int SendData(const char* data, int length);
+  void Close();
+
+  // SpdyStream::Delegate
+  virtual bool OnSendHeadersComplete(int status) OVERRIDE;
+  virtual int OnSendBody() OVERRIDE;
+  virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE;
+  virtual int OnResponseReceived(const SpdyHeaderBlock& response,
+                                 base::Time response_time,
+                                 int status) OVERRIDE;
+  virtual void OnHeadersSent() OVERRIDE;
+  virtual int OnDataReceived(const char* data, int length) OVERRIDE;
+  virtual void OnDataSent(int length) OVERRIDE;
+  virtual void OnClose(int status) OVERRIDE;
+
+ private:
+  friend class SpdyWebSocketStreamSpdy2Test;
+  friend class SpdyWebSocketStreamSpdy3Test;
+  FRIEND_TEST_ALL_PREFIXES(SpdyWebSocketStreamSpdy2Test, Basic);
+  FRIEND_TEST_ALL_PREFIXES(SpdyWebSocketStreamSpdy3Test, Basic);
+
+  void OnSpdyStreamCreated(int status);
+
+  scoped_refptr<SpdyStream> stream_;
+  scoped_refptr<SpdySession> spdy_session_;
+  Delegate* delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyWebSocketStream);
+};
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_WEBSOCKET_STREAM_H_
diff --git a/src/net/spdy/spdy_websocket_stream_spdy2_unittest.cc b/src/net/spdy/spdy_websocket_stream_spdy2_unittest.cc
new file mode 100644
index 0000000..20b7217
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_stream_spdy2_unittest.cc
@@ -0,0 +1,615 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_websocket_stream.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "net/base/completion_callback.h"
+#include "net/proxy/proxy_server.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+#include "net/spdy/spdy_websocket_test_util_spdy2.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy2;
+
+namespace net {
+
+namespace {
+
+struct SpdyWebSocketStreamEvent {
+  enum EventType {
+    EVENT_CREATED,
+    EVENT_SENT_HEADERS,
+    EVENT_RECEIVED_HEADER,
+    EVENT_SENT_DATA,
+    EVENT_RECEIVED_DATA,
+    EVENT_CLOSE,
+  };
+  SpdyWebSocketStreamEvent(EventType type,
+                           const SpdyHeaderBlock& headers,
+                           int result,
+                           const std::string& data)
+      : event_type(type),
+        headers(headers),
+        result(result),
+        data(data) {}
+
+  EventType event_type;
+  SpdyHeaderBlock headers;
+  int result;
+  std::string data;
+};
+
+class SpdyWebSocketStreamEventRecorder : public SpdyWebSocketStream::Delegate {
+ public:
+  explicit SpdyWebSocketStreamEventRecorder(const CompletionCallback& callback)
+      : callback_(callback) {}
+  virtual ~SpdyWebSocketStreamEventRecorder() {}
+
+  typedef base::Callback<void(SpdyWebSocketStreamEvent*)> StreamEventCallback;
+
+  void SetOnCreated(const StreamEventCallback& callback) {
+    on_created_ = callback;
+  }
+  void SetOnSentHeaders(const StreamEventCallback& callback) {
+    on_sent_headers_ = callback;
+  }
+  void SetOnReceivedHeader(const StreamEventCallback& callback) {
+    on_received_header_ = callback;
+  }
+  void SetOnSentData(const StreamEventCallback& callback) {
+    on_sent_data_ = callback;
+  }
+  void SetOnReceivedData(const StreamEventCallback& callback) {
+    on_received_data_ = callback;
+  }
+  void SetOnClose(const StreamEventCallback& callback) {
+    on_close_ = callback;
+  }
+
+  virtual void OnCreatedSpdyStream(int result) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(SpdyWebSocketStreamEvent::EVENT_CREATED,
+                                 SpdyHeaderBlock(),
+                                 result,
+                                 std::string()));
+    if (!on_created_.is_null())
+      on_created_.Run(&events_.back());
+  }
+  virtual void OnSentSpdyHeaders(int result) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+                                 SpdyHeaderBlock(),
+                                 result,
+                                 std::string()));
+    if (!on_sent_data_.is_null())
+      on_sent_data_.Run(&events_.back());
+  }
+  virtual int OnReceivedSpdyResponseHeader(
+      const SpdyHeaderBlock& headers, int status) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            headers,
+            status,
+            std::string()));
+    if (!on_received_header_.is_null())
+      on_received_header_.Run(&events_.back());
+    return status;
+  }
+  virtual void OnSentSpdyData(int amount_sent) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            SpdyHeaderBlock(),
+            amount_sent,
+            std::string()));
+    if (!on_sent_data_.is_null())
+      on_sent_data_.Run(&events_.back());
+  }
+  virtual void OnReceivedSpdyData(const char* data, int length) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            SpdyHeaderBlock(),
+            length,
+            std::string(data, length)));
+    if (!on_received_data_.is_null())
+      on_received_data_.Run(&events_.back());
+  }
+  virtual void OnCloseSpdyStream() {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_CLOSE,
+            SpdyHeaderBlock(),
+            OK,
+            std::string()));
+    if (!on_close_.is_null())
+      on_close_.Run(&events_.back());
+    if (!callback_.is_null())
+      callback_.Run(OK);
+  }
+
+  const std::vector<SpdyWebSocketStreamEvent>& GetSeenEvents() const {
+    return events_;
+  }
+
+ private:
+  std::vector<SpdyWebSocketStreamEvent> events_;
+  StreamEventCallback on_created_;
+  StreamEventCallback on_sent_headers_;
+  StreamEventCallback on_received_header_;
+  StreamEventCallback on_sent_data_;
+  StreamEventCallback on_received_data_;
+  StreamEventCallback on_close_;
+  CompletionCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyWebSocketStreamEventRecorder);
+};
+
+}  // namespace
+
+class SpdyWebSocketStreamSpdy2Test : public testing::Test {
+ public:
+  OrderedSocketData* data() { return data_.get(); }
+
+  void DoSendHelloFrame(SpdyWebSocketStreamEvent* event) {
+    // Record the actual stream_id.
+    created_stream_id_ = websocket_stream_->stream_->stream_id();
+    websocket_stream_->SendData(kMessageFrame, kMessageFrameLength);
+  }
+
+  void DoSendClosingFrame(SpdyWebSocketStreamEvent* event) {
+    websocket_stream_->SendData(kClosingFrame, kClosingFrameLength);
+  }
+
+  void DoClose(SpdyWebSocketStreamEvent* event) {
+    websocket_stream_->Close();
+  }
+
+  void DoSync(SpdyWebSocketStreamEvent* event) {
+    sync_callback_.callback().Run(OK);
+  }
+
+ protected:
+  SpdyWebSocketStreamSpdy2Test() {}
+  virtual ~SpdyWebSocketStreamSpdy2Test() {}
+
+  virtual void SetUp() {
+    host_port_pair_.set_host("example.com");
+    host_port_pair_.set_port(80);
+    host_port_proxy_pair_.first = host_port_pair_;
+    host_port_proxy_pair_.second = ProxyServer::Direct();
+
+    spdy_settings_id_to_set_ = SETTINGS_MAX_CONCURRENT_STREAMS;
+    spdy_settings_flags_to_set_ = SETTINGS_FLAG_PLEASE_PERSIST;
+    spdy_settings_value_to_set_ = 1;
+
+    spdy_settings_to_send_[spdy_settings_id_to_set_] =
+        SettingsFlagsAndValue(
+            SETTINGS_FLAG_PERSISTED, spdy_settings_value_to_set_);
+  }
+
+  virtual void TearDown() {
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void Prepare(SpdyStreamId stream_id) {
+    stream_id_ = stream_id;
+
+    request_frame_.reset(ConstructSpdyWebSocketSynStream(
+        stream_id_,
+        "/echo",
+        "example.com",
+        "http://example.com/wsdemo"));
+
+    response_frame_.reset(ConstructSpdyWebSocketSynReply(stream_id_));
+
+    message_frame_.reset(ConstructSpdyWebSocketDataFrame(
+        kMessageFrame,
+        kMessageFrameLength,
+        stream_id_,
+        false));
+
+    closing_frame_.reset(ConstructSpdyWebSocketDataFrame(
+        kClosingFrame,
+        kClosingFrameLength,
+        stream_id_,
+        false));
+  }
+
+  int InitSession(MockRead* reads, size_t reads_count,
+                  MockWrite* writes, size_t writes_count,
+                  bool throttling) {
+    data_.reset(new OrderedSocketData(reads, reads_count,
+                                      writes, writes_count));
+    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
+    http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+    SpdySessionPool* spdy_session_pool(http_session_->spdy_session_pool());
+
+    if (throttling) {
+      // Set max concurrent streams to 1.
+      spdy_session_pool->http_server_properties()->SetSpdySetting(
+          host_port_pair_,
+          spdy_settings_id_to_set_,
+          spdy_settings_flags_to_set_,
+          spdy_settings_value_to_set_);
+    }
+
+    EXPECT_FALSE(spdy_session_pool->HasSession(host_port_proxy_pair_));
+    session_ = spdy_session_pool->Get(host_port_proxy_pair_, BoundNetLog());
+    EXPECT_TRUE(spdy_session_pool->HasSession(host_port_proxy_pair_));
+    transport_params_ = new TransportSocketParams(host_port_pair_, MEDIUM,
+                                                  false, false,
+                                                  OnHostResolutionCallback());
+    TestCompletionCallback callback;
+    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+    EXPECT_EQ(ERR_IO_PENDING,
+              connection->Init(host_port_pair_.ToString(), transport_params_,
+                               MEDIUM, callback.callback(),
+                               http_session_->GetTransportSocketPool(
+                                   HttpNetworkSession::NORMAL_SOCKET_POOL),
+                               BoundNetLog()));
+    EXPECT_EQ(OK, callback.WaitForResult());
+    return session_->InitializeWithSocket(connection.release(), false, OK);
+  }
+
+  void SendRequest() {
+    scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+    (*headers)["path"] = "/echo";
+    (*headers)["host"] = "example.com";
+    (*headers)["version"] = "WebSocket/13";
+    (*headers)["scheme"] = "ws";
+    (*headers)["origin"] = "http://example.com/wsdemo";
+
+    websocket_stream_->SendRequest(headers.Pass());
+  }
+
+  SpdySettingsIds spdy_settings_id_to_set_;
+  SpdySettingsFlags spdy_settings_flags_to_set_;
+  uint32 spdy_settings_value_to_set_;
+  SettingsMap spdy_settings_to_send_;
+  SpdySessionDependencies session_deps_;
+  scoped_ptr<OrderedSocketData> data_;
+  scoped_refptr<HttpNetworkSession> http_session_;
+  scoped_refptr<SpdySession> session_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+  scoped_ptr<SpdyWebSocketStream> websocket_stream_;
+  SpdyStreamId stream_id_;
+  SpdyStreamId created_stream_id_;
+  scoped_ptr<SpdyFrame> request_frame_;
+  scoped_ptr<SpdyFrame> response_frame_;
+  scoped_ptr<SpdyFrame> message_frame_;
+  scoped_ptr<SpdyFrame> closing_frame_;
+  HostPortPair host_port_pair_;
+  HostPortProxyPair host_port_proxy_pair_;
+  TestCompletionCallback completion_callback_;
+  TestCompletionCallback sync_callback_;
+
+  static const char kMessageFrame[];
+  static const char kClosingFrame[];
+  static const size_t kMessageFrameLength;
+  static const size_t kClosingFrameLength;
+};
+
+// TODO(toyoshim): Replace old framing data to new one, then use HEADERS and
+// data frames.
+const char SpdyWebSocketStreamSpdy2Test::kMessageFrame[] = "\x81\x05hello";
+const char SpdyWebSocketStreamSpdy2Test::kClosingFrame[] = "\x88\0";
+const size_t SpdyWebSocketStreamSpdy2Test::kMessageFrameLength =
+    arraysize(SpdyWebSocketStreamSpdy2Test::kMessageFrame) - 1;
+const size_t SpdyWebSocketStreamSpdy2Test::kClosingFrameLength =
+    arraysize(SpdyWebSocketStreamSpdy2Test::kClosingFrame) - 1;
+
+TEST_F(SpdyWebSocketStreamSpdy2Test, Basic) {
+  Prepare(1);
+  MockWrite writes[] = {
+    CreateMockWrite(*request_frame_.get(), 1),
+    CreateMockWrite(*message_frame_.get(), 3),
+    CreateMockWrite(*closing_frame_.get(), 5)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*response_frame_.get(), 2),
+    CreateMockRead(*message_frame_.get(), 4),
+    // Skip sequence 6 to notify closing has been sent.
+    CreateMockRead(*closing_frame_.get(), 7),
+    MockRead(SYNCHRONOUS, 0, 8)  // EOF cause OnCloseSpdyStream event.
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), false));
+
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSendClosingFrame,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
+
+  ASSERT_TRUE(websocket_stream_->stream_);
+
+  SendRequest();
+
+  completion_callback_.WaitForResult();
+
+  EXPECT_EQ(stream_id_, created_stream_id_);
+
+  websocket_stream_.reset();
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_EQ(7U, events.size());
+
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[0].event_type);
+  EXPECT_LT(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[1].event_type);
+  EXPECT_EQ(OK, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[2].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[4].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[4].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[5].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[5].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE,
+            events[6].event_type);
+  EXPECT_EQ(OK, events[6].result);
+
+  // EOF close SPDY session.
+  EXPECT_TRUE(!http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+TEST_F(SpdyWebSocketStreamSpdy2Test, DestructionBeforeClose) {
+  Prepare(1);
+  MockWrite writes[] = {
+    CreateMockWrite(*request_frame_.get(), 1),
+    CreateMockWrite(*message_frame_.get(), 3)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*response_frame_.get(), 2),
+    CreateMockRead(*message_frame_.get(), 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5)
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), false));
+
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSync,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
+
+  SendRequest();
+
+  sync_callback_.WaitForResult();
+
+  // WebSocketStream destruction remove its SPDY stream from the session.
+  EXPECT_TRUE(session_->IsStreamActive(stream_id_));
+  websocket_stream_.reset();
+  EXPECT_FALSE(session_->IsStreamActive(stream_id_));
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_GE(4U, events.size());
+
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[0].event_type);
+  EXPECT_LT(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[1].event_type);
+  EXPECT_EQ(OK, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[2].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+TEST_F(SpdyWebSocketStreamSpdy2Test, DestructionAfterExplicitClose) {
+  Prepare(1);
+  MockWrite writes[] = {
+    CreateMockWrite(*request_frame_.get(), 1),
+    CreateMockWrite(*message_frame_.get(), 3),
+    CreateMockWrite(*closing_frame_.get(), 5)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*response_frame_.get(), 2),
+    CreateMockRead(*message_frame_.get(), 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 6)
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), false));
+
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoClose,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
+
+  SendRequest();
+
+  completion_callback_.WaitForResult();
+
+  // SPDY stream has already been removed from the session by Close().
+  EXPECT_FALSE(session_->IsStreamActive(stream_id_));
+  websocket_stream_.reset();
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_EQ(5U, events.size());
+
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[0].event_type);
+  EXPECT_LT(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[1].event_type);
+  EXPECT_EQ(OK, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[2].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE, events[4].event_type);
+
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+}
+
+TEST_F(SpdyWebSocketStreamSpdy2Test, IOPending) {
+  Prepare(1);
+  scoped_ptr<SpdyFrame> settings_frame(
+      ConstructSpdySettings(spdy_settings_to_send_));
+  MockWrite writes[] = {
+    // Setting throttling make SpdySession send settings frame automatically.
+    CreateMockWrite(*settings_frame.get(), 1),
+    CreateMockWrite(*request_frame_.get(), 3),
+    CreateMockWrite(*message_frame_.get(), 6),
+    CreateMockWrite(*closing_frame_.get(), 9)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame.get(), 2),
+    CreateMockRead(*response_frame_.get(), 4),
+    // Skip sequence 5 (I/O Pending)
+    CreateMockRead(*message_frame_.get(), 7),
+    // Skip sequence 8 (I/O Pending)
+    CreateMockRead(*closing_frame_.get(), 10),
+    MockRead(SYNCHRONOUS, 0, 11)  // EOF cause OnCloseSpdyStream event.
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), true));
+
+  // Create a dummy WebSocketStream which cause ERR_IO_PENDING to another
+  // WebSocketStream under test.
+  SpdyWebSocketStreamEventRecorder block_delegate((CompletionCallback()));
+
+  scoped_ptr<SpdyWebSocketStream> block_stream(
+      new SpdyWebSocketStream(session_, &block_delegate));
+  BoundNetLog block_net_log;
+  GURL block_url("ws://example.com/block");
+  ASSERT_EQ(OK,
+            block_stream->InitializeStream(block_url, HIGHEST, block_net_log));
+
+  // Create a WebSocketStream under test.
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnCreated(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSync,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy2Test::DoSendClosingFrame,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(ERR_IO_PENDING, websocket_stream_->InitializeStream(
+      url, HIGHEST, net_log));
+
+  // Delete the fist stream to allow create the second stream.
+  block_stream.reset();
+  ASSERT_EQ(OK, sync_callback_.WaitForResult());
+
+  SendRequest();
+
+  completion_callback_.WaitForResult();
+
+  websocket_stream_.reset();
+
+  const std::vector<SpdyWebSocketStreamEvent>& block_events =
+      block_delegate.GetSeenEvents();
+  ASSERT_EQ(0U, block_events.size());
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_EQ(8U, events.size());
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CREATED,
+            events[0].event_type);
+  EXPECT_EQ(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[1].event_type);
+  EXPECT_LT(0, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[2].event_type);
+  EXPECT_EQ(OK, events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[4].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[4].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[5].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[5].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[6].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[6].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE,
+            events[7].event_type);
+  EXPECT_EQ(OK, events[7].result);
+
+  // EOF close SPDY session.
+  EXPECT_TRUE(!http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_websocket_stream_spdy3_unittest.cc b/src/net/spdy/spdy_websocket_stream_spdy3_unittest.cc
new file mode 100644
index 0000000..932d0a0
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_stream_spdy3_unittest.cc
@@ -0,0 +1,615 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_websocket_stream.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "net/base/completion_callback.h"
+#include "net/proxy/proxy_server.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+#include "net/spdy/spdy_websocket_test_util_spdy3.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace net::test_spdy3;
+
+namespace net {
+
+namespace {
+
+struct SpdyWebSocketStreamEvent {
+  enum EventType {
+    EVENT_CREATED,
+    EVENT_SENT_HEADERS,
+    EVENT_RECEIVED_HEADER,
+    EVENT_SENT_DATA,
+    EVENT_RECEIVED_DATA,
+    EVENT_CLOSE,
+  };
+  SpdyWebSocketStreamEvent(EventType type,
+                           const SpdyHeaderBlock& headers,
+                           int result,
+                           const std::string& data)
+      : event_type(type),
+        headers(headers),
+        result(result),
+        data(data) {}
+
+  EventType event_type;
+  SpdyHeaderBlock headers;
+  int result;
+  std::string data;
+};
+
+class SpdyWebSocketStreamEventRecorder : public SpdyWebSocketStream::Delegate {
+ public:
+  explicit SpdyWebSocketStreamEventRecorder(const CompletionCallback& callback)
+      : callback_(callback) {}
+  virtual ~SpdyWebSocketStreamEventRecorder() {}
+
+  typedef base::Callback<void(SpdyWebSocketStreamEvent*)> StreamEventCallback;
+
+  void SetOnCreated(const StreamEventCallback& callback) {
+    on_created_ = callback;
+  }
+  void SetOnSentHeaders(const StreamEventCallback& callback) {
+    on_sent_headers_ = callback;
+  }
+  void SetOnReceivedHeader(const StreamEventCallback& callback) {
+    on_received_header_ = callback;
+  }
+  void SetOnSentData(const StreamEventCallback& callback) {
+    on_sent_data_ = callback;
+  }
+  void SetOnReceivedData(const StreamEventCallback& callback) {
+    on_received_data_ = callback;
+  }
+  void SetOnClose(const StreamEventCallback& callback) {
+    on_close_ = callback;
+  }
+
+  virtual void OnCreatedSpdyStream(int result) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(SpdyWebSocketStreamEvent::EVENT_CREATED,
+                                 SpdyHeaderBlock(),
+                                 result,
+                                 std::string()));
+    if (!on_created_.is_null())
+      on_created_.Run(&events_.back());
+  }
+  virtual void OnSentSpdyHeaders(int result) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+                                 SpdyHeaderBlock(),
+                                 result,
+                                 std::string()));
+    if (!on_sent_data_.is_null())
+      on_sent_data_.Run(&events_.back());
+  }
+  virtual int OnReceivedSpdyResponseHeader(
+      const SpdyHeaderBlock& headers, int status) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            headers,
+            status,
+            std::string()));
+    if (!on_received_header_.is_null())
+      on_received_header_.Run(&events_.back());
+    return status;
+  }
+  virtual void OnSentSpdyData(int amount_sent) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            SpdyHeaderBlock(),
+            amount_sent,
+            std::string()));
+    if (!on_sent_data_.is_null())
+      on_sent_data_.Run(&events_.back());
+  }
+  virtual void OnReceivedSpdyData(const char* data, int length) {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            SpdyHeaderBlock(),
+            length,
+            std::string(data, length)));
+    if (!on_received_data_.is_null())
+      on_received_data_.Run(&events_.back());
+  }
+  virtual void OnCloseSpdyStream() {
+    events_.push_back(
+        SpdyWebSocketStreamEvent(
+            SpdyWebSocketStreamEvent::EVENT_CLOSE,
+            SpdyHeaderBlock(),
+            OK,
+            std::string()));
+    if (!on_close_.is_null())
+      on_close_.Run(&events_.back());
+    if (!callback_.is_null())
+      callback_.Run(OK);
+  }
+
+  const std::vector<SpdyWebSocketStreamEvent>& GetSeenEvents() const {
+    return events_;
+  }
+
+ private:
+  std::vector<SpdyWebSocketStreamEvent> events_;
+  StreamEventCallback on_created_;
+  StreamEventCallback on_sent_headers_;
+  StreamEventCallback on_received_header_;
+  StreamEventCallback on_sent_data_;
+  StreamEventCallback on_received_data_;
+  StreamEventCallback on_close_;
+  CompletionCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpdyWebSocketStreamEventRecorder);
+};
+
+}  // namespace
+
+class SpdyWebSocketStreamSpdy3Test : public testing::Test {
+ public:
+  OrderedSocketData* data() { return data_.get(); }
+
+  void DoSendHelloFrame(SpdyWebSocketStreamEvent* event) {
+    // Record the actual stream_id.
+    created_stream_id_ = websocket_stream_->stream_->stream_id();
+    websocket_stream_->SendData(kMessageFrame, kMessageFrameLength);
+  }
+
+  void DoSendClosingFrame(SpdyWebSocketStreamEvent* event) {
+    websocket_stream_->SendData(kClosingFrame, kClosingFrameLength);
+  }
+
+  void DoClose(SpdyWebSocketStreamEvent* event) {
+    websocket_stream_->Close();
+  }
+
+  void DoSync(SpdyWebSocketStreamEvent* event) {
+    sync_callback_.callback().Run(OK);
+  }
+
+ protected:
+  SpdyWebSocketStreamSpdy3Test() {}
+  virtual ~SpdyWebSocketStreamSpdy3Test() {}
+
+  virtual void SetUp() {
+    host_port_pair_.set_host("example.com");
+    host_port_pair_.set_port(80);
+    host_port_proxy_pair_.first = host_port_pair_;
+    host_port_proxy_pair_.second = ProxyServer::Direct();
+
+    spdy_settings_id_to_set_ = SETTINGS_MAX_CONCURRENT_STREAMS;
+    spdy_settings_flags_to_set_ = SETTINGS_FLAG_PLEASE_PERSIST;
+    spdy_settings_value_to_set_ = 1;
+
+    spdy_settings_to_send_[spdy_settings_id_to_set_] =
+        SettingsFlagsAndValue(
+            SETTINGS_FLAG_PERSISTED, spdy_settings_value_to_set_);
+  }
+
+  virtual void TearDown() {
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void Prepare(SpdyStreamId stream_id) {
+    stream_id_ = stream_id;
+
+    request_frame_.reset(ConstructSpdyWebSocketSynStream(
+        stream_id_,
+        "/echo",
+        "example.com",
+        "http://example.com/wsdemo"));
+
+    response_frame_.reset(ConstructSpdyWebSocketSynReply(stream_id_));
+
+    message_frame_.reset(ConstructSpdyWebSocketDataFrame(
+        kMessageFrame,
+        kMessageFrameLength,
+        stream_id_,
+        false));
+
+    closing_frame_.reset(ConstructSpdyWebSocketDataFrame(
+        kClosingFrame,
+        kClosingFrameLength,
+        stream_id_,
+        false));
+  }
+
+  int InitSession(MockRead* reads, size_t reads_count,
+                  MockWrite* writes, size_t writes_count,
+                  bool throttling) {
+    data_.reset(new OrderedSocketData(reads, reads_count,
+                                      writes, writes_count));
+    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
+    http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+    SpdySessionPool* spdy_session_pool(http_session_->spdy_session_pool());
+
+    if (throttling) {
+      // Set max concurrent streams to 1.
+      spdy_session_pool->http_server_properties()->SetSpdySetting(
+          host_port_pair_,
+          spdy_settings_id_to_set_,
+          spdy_settings_flags_to_set_,
+          spdy_settings_value_to_set_);
+    }
+
+    EXPECT_FALSE(spdy_session_pool->HasSession(host_port_proxy_pair_));
+    session_ = spdy_session_pool->Get(host_port_proxy_pair_, BoundNetLog());
+    EXPECT_TRUE(spdy_session_pool->HasSession(host_port_proxy_pair_));
+    transport_params_ = new TransportSocketParams(host_port_pair_, MEDIUM,
+                                                  false, false,
+                                                  OnHostResolutionCallback());
+    TestCompletionCallback callback;
+    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+    EXPECT_EQ(ERR_IO_PENDING,
+              connection->Init(host_port_pair_.ToString(), transport_params_,
+                               MEDIUM, callback.callback(),
+                               http_session_->GetTransportSocketPool(
+                                   HttpNetworkSession::NORMAL_SOCKET_POOL),
+                               BoundNetLog()));
+    EXPECT_EQ(OK, callback.WaitForResult());
+    return session_->InitializeWithSocket(connection.release(), false, OK);
+  }
+
+  void SendRequest() {
+    scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+    (*headers)[":path"] = "/echo";
+    (*headers)[":host"] = "example.com";
+    (*headers)[":version"] = "WebSocket/13";
+    (*headers)[":scheme"] = "ws";
+    (*headers)[":origin"] = "http://example.com/wsdemo";
+
+    websocket_stream_->SendRequest(headers.Pass());
+  }
+
+  SpdySettingsIds spdy_settings_id_to_set_;
+  SpdySettingsFlags spdy_settings_flags_to_set_;
+  uint32 spdy_settings_value_to_set_;
+  SettingsMap spdy_settings_to_send_;
+  SpdySessionDependencies session_deps_;
+  scoped_ptr<OrderedSocketData> data_;
+  scoped_refptr<HttpNetworkSession> http_session_;
+  scoped_refptr<SpdySession> session_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+  scoped_ptr<SpdyWebSocketStream> websocket_stream_;
+  SpdyStreamId stream_id_;
+  SpdyStreamId created_stream_id_;
+  scoped_ptr<SpdyFrame> request_frame_;
+  scoped_ptr<SpdyFrame> response_frame_;
+  scoped_ptr<SpdyFrame> message_frame_;
+  scoped_ptr<SpdyFrame> closing_frame_;
+  HostPortPair host_port_pair_;
+  HostPortProxyPair host_port_proxy_pair_;
+  TestCompletionCallback completion_callback_;
+  TestCompletionCallback sync_callback_;
+
+  static const char kMessageFrame[];
+  static const char kClosingFrame[];
+  static const size_t kMessageFrameLength;
+  static const size_t kClosingFrameLength;
+};
+
+// TODO(toyoshim): Replace old framing data to new one, then use HEADERS and
+// data frames.
+const char SpdyWebSocketStreamSpdy3Test::kMessageFrame[] = "\x81\x05hello";
+const char SpdyWebSocketStreamSpdy3Test::kClosingFrame[] = "\x88\0";
+const size_t SpdyWebSocketStreamSpdy3Test::kMessageFrameLength =
+    arraysize(SpdyWebSocketStreamSpdy3Test::kMessageFrame) - 1;
+const size_t SpdyWebSocketStreamSpdy3Test::kClosingFrameLength =
+    arraysize(SpdyWebSocketStreamSpdy3Test::kClosingFrame) - 1;
+
+TEST_F(SpdyWebSocketStreamSpdy3Test, Basic) {
+  Prepare(1);
+  MockWrite writes[] = {
+    CreateMockWrite(*request_frame_.get(), 1),
+    CreateMockWrite(*message_frame_.get(), 3),
+    CreateMockWrite(*closing_frame_.get(), 5)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*response_frame_.get(), 2),
+    CreateMockRead(*message_frame_.get(), 4),
+    // Skip sequence 6 to notify closing has been sent.
+    CreateMockRead(*closing_frame_.get(), 7),
+    MockRead(SYNCHRONOUS, 0, 8)  // EOF cause OnCloseSpdyStream event.
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), false));
+
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSendClosingFrame,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
+
+  ASSERT_TRUE(websocket_stream_->stream_);
+
+  SendRequest();
+
+  completion_callback_.WaitForResult();
+
+  EXPECT_EQ(stream_id_, created_stream_id_);
+
+  websocket_stream_.reset();
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_EQ(7U, events.size());
+
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[0].event_type);
+  EXPECT_LT(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[1].event_type);
+  EXPECT_EQ(OK, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[2].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[4].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[4].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[5].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[5].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE,
+            events[6].event_type);
+  EXPECT_EQ(OK, events[6].result);
+
+  // EOF close SPDY session.
+  EXPECT_TRUE(!http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+TEST_F(SpdyWebSocketStreamSpdy3Test, DestructionBeforeClose) {
+  Prepare(1);
+  MockWrite writes[] = {
+    CreateMockWrite(*request_frame_.get(), 1),
+    CreateMockWrite(*message_frame_.get(), 3)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*response_frame_.get(), 2),
+    CreateMockRead(*message_frame_.get(), 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 5)
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), false));
+
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSync,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
+
+  SendRequest();
+
+  sync_callback_.WaitForResult();
+
+  // WebSocketStream destruction remove its SPDY stream from the session.
+  EXPECT_TRUE(session_->IsStreamActive(stream_id_));
+  websocket_stream_.reset();
+  EXPECT_FALSE(session_->IsStreamActive(stream_id_));
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_GE(4U, events.size());
+
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[0].event_type);
+  EXPECT_LT(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[1].event_type);
+  EXPECT_EQ(OK, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[2].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+TEST_F(SpdyWebSocketStreamSpdy3Test, DestructionAfterExplicitClose) {
+  Prepare(1);
+  MockWrite writes[] = {
+    CreateMockWrite(*request_frame_.get(), 1),
+    CreateMockWrite(*message_frame_.get(), 3),
+    CreateMockWrite(*closing_frame_.get(), 5)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*response_frame_.get(), 2),
+    CreateMockRead(*message_frame_.get(), 4),
+    MockRead(ASYNC, ERR_IO_PENDING, 6)
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), false));
+
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoClose,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
+
+  SendRequest();
+
+  completion_callback_.WaitForResult();
+
+  // SPDY stream has already been removed from the session by Close().
+  EXPECT_FALSE(session_->IsStreamActive(stream_id_));
+  websocket_stream_.reset();
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_EQ(5U, events.size());
+
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[0].event_type);
+  EXPECT_LT(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[1].event_type);
+  EXPECT_EQ(OK, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[2].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE, events[4].event_type);
+
+  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+}
+
+TEST_F(SpdyWebSocketStreamSpdy3Test, IOPending) {
+  Prepare(1);
+  scoped_ptr<SpdyFrame> settings_frame(
+      ConstructSpdySettings(spdy_settings_to_send_));
+  MockWrite writes[] = {
+    // Setting throttling make SpdySession send settings frame automatically.
+    CreateMockWrite(*settings_frame.get(), 1),
+    CreateMockWrite(*request_frame_.get(), 3),
+    CreateMockWrite(*message_frame_.get(), 6),
+    CreateMockWrite(*closing_frame_.get(), 9)
+  };
+
+  MockRead reads[] = {
+    CreateMockRead(*settings_frame.get(), 2),
+    CreateMockRead(*response_frame_.get(), 4),
+    // Skip sequence 5 (I/O Pending)
+    CreateMockRead(*message_frame_.get(), 7),
+    // Skip sequence 8 (I/O Pending)
+    CreateMockRead(*closing_frame_.get(), 10),
+    MockRead(SYNCHRONOUS, 0, 11)  // EOF cause OnCloseSpdyStream event.
+  };
+
+  EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
+                            writes, arraysize(writes), true));
+
+  // Create a dummy WebSocketStream which cause ERR_IO_PENDING to another
+  // WebSocketStream under test.
+  SpdyWebSocketStreamEventRecorder block_delegate((CompletionCallback()));
+
+  scoped_ptr<SpdyWebSocketStream> block_stream(
+      new SpdyWebSocketStream(session_, &block_delegate));
+  BoundNetLog block_net_log;
+  GURL block_url("ws://example.com/block");
+  ASSERT_EQ(OK,
+            block_stream->InitializeStream(block_url, HIGHEST, block_net_log));
+
+  // Create a WebSocketStream under test.
+  SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
+  delegate.SetOnCreated(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSync,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedHeader(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSendHelloFrame,
+                 base::Unretained(this)));
+  delegate.SetOnReceivedData(
+      base::Bind(&SpdyWebSocketStreamSpdy3Test::DoSendClosingFrame,
+                 base::Unretained(this)));
+
+  websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
+  BoundNetLog net_log;
+  GURL url("ws://example.com/echo");
+  ASSERT_EQ(ERR_IO_PENDING, websocket_stream_->InitializeStream(
+      url, HIGHEST, net_log));
+
+  // Delete the first stream to allow create the second stream.
+  block_stream.reset();
+  ASSERT_EQ(OK, sync_callback_.WaitForResult());
+
+  SendRequest();
+
+  completion_callback_.WaitForResult();
+
+  websocket_stream_.reset();
+
+  const std::vector<SpdyWebSocketStreamEvent>& block_events =
+      block_delegate.GetSeenEvents();
+  ASSERT_EQ(0U, block_events.size());
+
+  const std::vector<SpdyWebSocketStreamEvent>& events =
+      delegate.GetSeenEvents();
+  ASSERT_EQ(8U, events.size());
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CREATED,
+            events[0].event_type);
+  EXPECT_EQ(0, events[0].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
+            events[1].event_type);
+  EXPECT_LT(0, events[1].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
+            events[2].event_type);
+  EXPECT_EQ(OK, events[2].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[3].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[4].event_type);
+  EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[4].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
+            events[5].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[5].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
+            events[6].event_type);
+  EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[6].result);
+  EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE,
+            events[7].event_type);
+  EXPECT_EQ(OK, events[7].result);
+
+  // EOF close SPDY session.
+  EXPECT_TRUE(!http_session_->spdy_session_pool()->HasSession(
+      host_port_proxy_pair_));
+  EXPECT_TRUE(data()->at_read_eof());
+  EXPECT_TRUE(data()->at_write_eof());
+}
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_websocket_test_util_spdy2.cc b/src/net/spdy/spdy_websocket_test_util_spdy2.cc
new file mode 100644
index 0000000..1a45949
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_test_util_spdy2.cc
@@ -0,0 +1,162 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_websocket_test_util_spdy2.h"
+
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_test_util_spdy2.h"
+
+static const int kDefaultAssociatedStreamId = 0;
+static const bool kDefaultCompressed = false;
+static const char* const kDefaultDataPointer = NULL;
+static const uint32 kDefaultDataLength = 0;
+static const char** const kDefaultExtraHeaders = NULL;
+static const int kDefaultExtraHeaderCount = 0;
+
+namespace net {
+
+namespace test_spdy2 {
+
+SpdyFrame* ConstructSpdyWebSocketSynStream(int stream_id,
+                                           const char* path,
+                                           const char* host,
+                                           const char* origin) {
+  const char* const kWebSocketHeaders[] = {
+    "path",
+    path,
+    "host",
+    host,
+    "version",
+    "WebSocket/13",
+    "scheme",
+    "ws",
+    "origin",
+    origin
+  };
+  return ConstructSpdyControlFrame(/*extra_headers*/ NULL,
+                                   /*extra_header_count*/ 0,
+                                   /*compressed*/ false,
+                                   stream_id,
+                                   HIGHEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kWebSocketHeaders,
+                                   arraysize(kWebSocketHeaders));
+}
+
+SpdyFrame* ConstructSpdyWebSocketSynReply(int stream_id) {
+  static const char* const kStandardWebSocketHeaders[] = {
+    "status",
+    "101"
+  };
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardWebSocketHeaders,
+                                   arraysize(kStandardWebSocketHeaders));
+}
+
+SpdyFrame* ConstructSpdyWebSocketHandshakeRequestFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority) {
+
+  // SPDY SYN_STREAM control frame header.
+  const SpdyHeaderInfo kSynStreamHeader = {
+    SYN_STREAM,
+    stream_id,
+    kDefaultAssociatedStreamId,
+    ConvertRequestPriorityToSpdyPriority(request_priority, 2),
+    CONTROL_FLAG_NONE,
+    kDefaultCompressed,
+    INVALID,
+    kDefaultDataPointer,
+    kDefaultDataLength,
+    DATA_FLAG_NONE
+  };
+
+  // Construct SPDY SYN_STREAM control frame.
+  return ConstructSpdyPacket(
+      kSynStreamHeader,
+      kDefaultExtraHeaders,
+      kDefaultExtraHeaderCount,
+      headers,
+      header_count);
+}
+
+SpdyFrame* ConstructSpdyWebSocketHandshakeResponseFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority) {
+
+  // SPDY SYN_REPLY control frame header.
+  const SpdyHeaderInfo kSynReplyHeader = {
+    SYN_REPLY,
+    stream_id,
+    kDefaultAssociatedStreamId,
+    ConvertRequestPriorityToSpdyPriority(request_priority, 2),
+    CONTROL_FLAG_NONE,
+    kDefaultCompressed,
+    INVALID,
+    kDefaultDataPointer,
+    kDefaultDataLength,
+    DATA_FLAG_NONE
+  };
+
+  // Construct SPDY SYN_REPLY control frame.
+  return ConstructSpdyPacket(
+      kSynReplyHeader,
+      kDefaultExtraHeaders,
+      kDefaultExtraHeaderCount,
+      headers,
+      header_count);
+}
+
+SpdyFrame* ConstructSpdyWebSocketHeadersFrame(int stream_id,
+                                              const char* length,
+                                              bool fin) {
+  static const char* const kHeaders[] = {
+    "opcode",
+    "1",  // text frame
+    "length",
+    length,
+    "fin",
+    fin ? "1" : "0"
+  };
+  return ConstructSpdyControlFrame(/*extra_headers*/ NULL,
+                                   /*extra_header_count*/ 0,
+                                   /*compression*/ false,
+                                   stream_id,
+                                   LOWEST,
+                                   HEADERS,
+                                   CONTROL_FLAG_NONE,
+                                   kHeaders,
+                                   arraysize(kHeaders));
+}
+
+SpdyFrame* ConstructSpdyWebSocketDataFrame(
+    const char* data,
+    int len,
+    SpdyStreamId stream_id,
+    bool fin) {
+
+  // Construct SPDY data frame.
+  BufferedSpdyFramer framer(2, false);
+  return framer.CreateDataFrame(
+      stream_id,
+      data,
+      len,
+      fin ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+}  // namespace test_spdy2
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_websocket_test_util_spdy2.h b/src/net/spdy/spdy_websocket_test_util_spdy2.h
new file mode 100644
index 0000000..3856bb6
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_test_util_spdy2.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_WEBSOCKET_TEST_UTIL_H_
+#define NET_SPDY_SPDY_WEBSOCKET_TEST_UTIL_H_
+
+#include "net/base/request_priority.h"
+#include "net/spdy/spdy_protocol.h"
+
+namespace net {
+
+namespace test_spdy2 {
+
+// Constructs a standard SPDY SYN_STREAM frame for WebSocket over SPDY opening
+// handshake.
+SpdyFrame* ConstructSpdyWebSocketSynStream(int stream_id,
+                                           const char* path,
+                                           const char* host,
+                                           const char* origin);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the WebSocket over SPDY
+// opening handshake.
+SpdyFrame* ConstructSpdyWebSocketSynReply(int stream_id);
+
+// Constructs a WebSocket over SPDY handshake request packet.
+SpdyFrame* ConstructSpdyWebSocketHandshakeRequestFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority);
+
+// Constructs a WebSocket over SPDY handshake response packet.
+SpdyFrame* ConstructSpdyWebSocketHandshakeResponseFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority);
+
+// Constructs a SPDY HEADERS frame for a WebSocket frame over SPDY.
+SpdyFrame* ConstructSpdyWebSocketHeadersFrame(int stream_id,
+                                              const char* length,
+                                              bool fin);
+
+// Constructs a WebSocket over SPDY data packet.
+SpdyFrame* ConstructSpdyWebSocketDataFrame(const char* data,
+                                           int len,
+                                           SpdyStreamId stream_id,
+                                           bool fin);
+
+}  // namespace test_spdy2
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_WEBSOCKET_TEST_UTIL_H_
diff --git a/src/net/spdy/spdy_websocket_test_util_spdy3.cc b/src/net/spdy/spdy_websocket_test_util_spdy3.cc
new file mode 100644
index 0000000..4e2eec4
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_test_util_spdy3.cc
@@ -0,0 +1,165 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_websocket_test_util_spdy3.h"
+
+#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_test_util_spdy3.h"
+
+static const int kDefaultAssociatedStreamId = 0;
+static const bool kDefaultCompressed = false;
+static const char* const kDefaultDataPointer = NULL;
+static const uint32 kDefaultDataLength = 0;
+static const char** const kDefaultExtraHeaders = NULL;
+static const int kDefaultExtraHeaderCount = 0;
+static const int kDefaultCredentialSlot = 0;
+
+namespace net {
+
+namespace test_spdy3 {
+
+SpdyFrame* ConstructSpdyWebSocketSynStream(int stream_id,
+                                           const char* path,
+                                           const char* host,
+                                           const char* origin) {
+  const char* const kWebSocketHeaders[] = {
+    ":path",
+    path,
+    ":host",
+    host,
+    ":version",
+    "WebSocket/13",
+    ":scheme",
+    "ws",
+    ":origin",
+    origin
+  };
+  return ConstructSpdyControlFrame(/*extra_headers*/ NULL,
+                                   /*extra_header_count*/ 0,
+                                   /*compressed*/ false,
+                                   stream_id,
+                                   HIGHEST,
+                                   SYN_STREAM,
+                                   CONTROL_FLAG_NONE,
+                                   kWebSocketHeaders,
+                                   arraysize(kWebSocketHeaders));
+}
+
+SpdyFrame* ConstructSpdyWebSocketSynReply(int stream_id) {
+  static const char* const kStandardWebSocketHeaders[] = {
+    ":status",
+    "101"
+  };
+  return ConstructSpdyControlFrame(NULL,
+                                   0,
+                                   false,
+                                   stream_id,
+                                   LOWEST,
+                                   SYN_REPLY,
+                                   CONTROL_FLAG_NONE,
+                                   kStandardWebSocketHeaders,
+                                   arraysize(kStandardWebSocketHeaders));
+}
+
+SpdyFrame* ConstructSpdyWebSocketHandshakeRequestFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority) {
+
+  // SPDY SYN_STREAM control frame header.
+  const SpdyHeaderInfo kSynStreamHeader = {
+    SYN_STREAM,
+    stream_id,
+    kDefaultAssociatedStreamId,
+    ConvertRequestPriorityToSpdyPriority(request_priority, 3),
+    kDefaultCredentialSlot,
+    CONTROL_FLAG_NONE,
+    kDefaultCompressed,
+    INVALID,
+    kDefaultDataPointer,
+    kDefaultDataLength,
+    DATA_FLAG_NONE
+  };
+
+  // Construct SPDY SYN_STREAM control frame.
+  return ConstructSpdyPacket(
+      kSynStreamHeader,
+      kDefaultExtraHeaders,
+      kDefaultExtraHeaderCount,
+      headers,
+      header_count);
+}
+
+SpdyFrame* ConstructSpdyWebSocketHandshakeResponseFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority) {
+
+  // SPDY SYN_REPLY control frame header.
+  const SpdyHeaderInfo kSynReplyHeader = {
+    SYN_REPLY,
+    stream_id,
+    kDefaultAssociatedStreamId,
+    ConvertRequestPriorityToSpdyPriority(request_priority, 3),
+    kDefaultCredentialSlot,
+    CONTROL_FLAG_NONE,
+    kDefaultCompressed,
+    INVALID,
+    kDefaultDataPointer,
+    kDefaultDataLength,
+    DATA_FLAG_NONE
+  };
+
+  // Construct SPDY SYN_REPLY control frame.
+  return ConstructSpdyPacket(
+      kSynReplyHeader,
+      kDefaultExtraHeaders,
+      kDefaultExtraHeaderCount,
+      headers,
+      header_count);
+}
+
+SpdyFrame* ConstructSpdyWebSocketHeadersFrame(int stream_id,
+                                              const char* length,
+                                              bool fin) {
+  static const char* const kHeaders[] = {
+    ":opcode",
+    "1",  // text frame
+    ":length",
+    length,
+    ":fin",
+    fin ? "1" : "0"
+  };
+  return ConstructSpdyControlFrame(/*extra_headers*/ NULL,
+                                   /*extra_header_count*/ 0,
+                                   /*compression*/ false,
+                                   stream_id,
+                                   LOWEST,
+                                   HEADERS,
+                                   CONTROL_FLAG_NONE,
+                                   kHeaders,
+                                   arraysize(kHeaders));
+}
+
+SpdyFrame* ConstructSpdyWebSocketDataFrame(
+    const char* data,
+    int len,
+    SpdyStreamId stream_id,
+    bool fin) {
+
+  // Construct SPDY data frame.
+  BufferedSpdyFramer framer(3, false);
+  return framer.CreateDataFrame(
+      stream_id,
+      data,
+      len,
+      fin ? DATA_FLAG_FIN : DATA_FLAG_NONE);
+}
+
+}  // namespace test_spdy3
+
+}  // namespace net
diff --git a/src/net/spdy/spdy_websocket_test_util_spdy3.h b/src/net/spdy/spdy_websocket_test_util_spdy3.h
new file mode 100644
index 0000000..3446738
--- /dev/null
+++ b/src/net/spdy/spdy_websocket_test_util_spdy3.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_WEBSOCKET_TEST_UTIL_H_
+#define NET_SPDY_SPDY_WEBSOCKET_TEST_UTIL_H_
+
+#include "net/base/request_priority.h"
+#include "net/spdy/spdy_protocol.h"
+
+namespace net {
+
+namespace test_spdy3 {
+
+// Constructs a standard SPDY SYN_STREAM frame for WebSocket over SPDY opening
+// handshake.
+SpdyFrame* ConstructSpdyWebSocketSynStream(int stream_id,
+                                           const char* path,
+                                           const char* host,
+                                           const char* origin);
+
+// Constructs a standard SPDY SYN_REPLY packet to match the WebSocket over SPDY
+// opening handshake.
+SpdyFrame* ConstructSpdyWebSocketSynReply(int stream_id);
+
+// Constructs a WebSocket over SPDY handshake request packet.
+SpdyFrame* ConstructSpdyWebSocketHandshakeRequestFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority);
+
+// Constructs a WebSocket over SPDY handshake response packet.
+SpdyFrame* ConstructSpdyWebSocketHandshakeResponseFrame(
+    const char* const headers[],
+    int header_count,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority);
+
+// Constructs a SPDY HEADERS frame for a WebSocket frame over SPDY.
+SpdyFrame* ConstructSpdyWebSocketHeadersFrame(int stream_id,
+                                              const char* length,
+                                              bool fin);
+
+// Constructs a WebSocket over SPDY data packet.
+SpdyFrame* ConstructSpdyWebSocketDataFrame(const char* data,
+                                           int len,
+                                           SpdyStreamId stream_id,
+                                           bool fin);
+
+}  // namespace test_spdy3
+
+}  // namespace net
+
+#endif  // NET_SPDY_SPDY_WEBSOCKET_TEST_UTIL_H_
