Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_test_util_common.cc
index 2054b49..f59af9e 100644 (file)
@@ -24,6 +24,7 @@
 #include "net/spdy/spdy_session.h"
 #include "net/spdy/spdy_session_pool.h"
 #include "net/spdy/spdy_stream.h"
+#include "net/url_request/url_request_job_factory_impl.h"
 
 namespace net {
 
@@ -50,8 +51,8 @@ void ParseUrl(base::StringPiece url, std::string* scheme, std::string* host,
 
 }  // namespace
 
-std::vector<NextProto> SpdyNextProtos() {
-  std::vector<NextProto> next_protos;
+NextProtoVector SpdyNextProtos() {
+  NextProtoVector next_protos;
   for (int i = kProtoMinimumVersion; i <= kProtoMaximumVersion; ++i) {
     next_protos.push_back(static_cast<NextProto>(i));
   }
@@ -216,7 +217,6 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
   virtual void OnSynStream(SpdyStreamId stream_id,
                            SpdyStreamId associated_stream_id,
                            SpdyPriority priority,
-                           uint8 credential_slot,
                            bool fin,
                            bool unidirectional,
                            const SpdyHeaderBlock& headers) OVERRIDE {
@@ -238,7 +238,7 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
   virtual void OnSettings(bool clear_persisted) OVERRIDE {}
   virtual void OnSetting(
       SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE {}
-  virtual void OnPing(uint32 unique_id) OVERRIDE {}
+  virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
   virtual void OnRstStream(SpdyStreamId stream_id,
                            SpdyRstStreamStatus status) OVERRIDE {}
   virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
@@ -246,7 +246,8 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
   virtual void OnWindowUpdate(SpdyStreamId stream_id,
                               uint32 delta_window_size) OVERRIDE {}
   virtual void OnPushPromise(SpdyStreamId stream_id,
-                             SpdyStreamId promised_stream_id) OVERRIDE {}
+                             SpdyStreamId promised_stream_id,
+                             const SpdyHeaderBlock& headers) OVERRIDE {}
 
  private:
   SpdyPriority priority_;
@@ -358,6 +359,10 @@ SpdySessionDependencies::SpdySessionDependencies(NextProto protocol)
       protocol(protocol),
       stream_initial_recv_window_size(kSpdyStreamInitialWindowSize),
       time_func(&base::TimeTicks::Now),
+      force_spdy_over_ssl(false),
+      force_spdy_always(false),
+      use_alternate_protocols(false),
+      enable_websocket_over_spdy(false),
       net_log(NULL) {
   DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
 
@@ -388,6 +393,10 @@ SpdySessionDependencies::SpdySessionDependencies(
       protocol(protocol),
       stream_initial_recv_window_size(kSpdyStreamInitialWindowSize),
       time_func(&base::TimeTicks::Now),
+      force_spdy_over_ssl(false),
+      force_spdy_always(false),
+      use_alternate_protocols(false),
+      enable_websocket_over_spdy(false),
       net_log(NULL) {
   DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
 }
@@ -442,12 +451,19 @@ net::HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
   params.spdy_stream_initial_recv_window_size =
       session_deps->stream_initial_recv_window_size;
   params.time_func = session_deps->time_func;
+  params.next_protos = session_deps->next_protos;
   params.trusted_spdy_proxy = session_deps->trusted_spdy_proxy;
+  params.force_spdy_over_ssl = session_deps->force_spdy_over_ssl;
+  params.force_spdy_always = session_deps->force_spdy_always;
+  params.use_alternate_protocols = session_deps->use_alternate_protocols;
+  params.enable_websocket_over_spdy = session_deps->enable_websocket_over_spdy;
   params.net_log = session_deps->net_log;
   return params;
 }
 
-SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
+SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol,
+                                             bool force_spdy_over_ssl,
+                                             bool force_spdy_always)
     : storage_(this) {
   DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
 
@@ -460,6 +476,7 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
       host_resolver()));
   storage_.set_http_server_properties(
       scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
+  storage_.set_job_factory(new URLRequestJobFactoryImpl());
   net::HttpNetworkSession::Params params;
   params.client_socket_factory = &socket_factory_;
   params.host_resolver = host_resolver();
@@ -472,6 +489,8 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
   params.enable_spdy_compression = false;
   params.enable_spdy_ping_based_connection_checking = false;
   params.spdy_default_protocol = protocol;
+  params.force_spdy_over_ssl = force_spdy_over_ssl;
+  params.force_spdy_always = force_spdy_always;
   params.http_server_properties = http_server_properties();
   scoped_refptr<HttpNetworkSession> network_session(
       new HttpNetworkSession(params));
@@ -482,6 +501,7 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
 }
 
 SpdyURLRequestContext::~SpdyURLRequestContext() {
+  AssertNoURLRequests();
 }
 
 bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key) {
@@ -541,15 +561,12 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper(
 
   EXPECT_EQ(OK, rv);
 
-  base::WeakPtr<SpdySession> spdy_session;
-  EXPECT_EQ(
-      expected_status,
+  base::WeakPtr<SpdySession> spdy_session =
       http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
-          key, connection.Pass(), net_log, OK, &spdy_session,
-          is_secure));
-  EXPECT_EQ(expected_status == OK, spdy_session != NULL);
-  EXPECT_EQ(expected_status == OK,
-            HasSpdySession(http_session->spdy_session_pool(), key));
+          key, connection.Pass(), net_log, OK, is_secure);
+  // Failure is reported asynchronously.
+  EXPECT_TRUE(spdy_session != NULL);
+  EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
   return spdy_session;
 }
 
@@ -563,14 +580,14 @@ base::WeakPtr<SpdySession> CreateInsecureSpdySession(
                                  OK, false /* is_secure */);
 }
 
-void TryCreateInsecureSpdySessionExpectingFailure(
+base::WeakPtr<SpdySession> TryCreateInsecureSpdySessionExpectingFailure(
     const scoped_refptr<HttpNetworkSession>& http_session,
     const SpdySessionKey& key,
     Error expected_error,
     const BoundNetLog& net_log) {
   DCHECK_LT(expected_error, ERR_IO_PENDING);
-  CreateSpdySessionHelper(http_session, key, net_log,
-                          expected_error, false /* is_secure */);
+  return CreateSpdySessionHelper(http_session, key, net_log,
+                                 expected_error, false /* is_secure */);
 }
 
 base::WeakPtr<SpdySession> CreateSecureSpdySession(
@@ -644,17 +661,15 @@ base::WeakPtr<SpdySession> CreateFakeSpdySessionHelper(
     Error expected_status) {
   EXPECT_NE(expected_status, ERR_IO_PENDING);
   EXPECT_FALSE(HasSpdySession(pool, key));
-  base::WeakPtr<SpdySession> spdy_session;
   scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle());
   handle->SetSocket(scoped_ptr<StreamSocket>(new FakeSpdySessionClientSocket(
       expected_status == OK ? ERR_IO_PENDING : expected_status)));
-  EXPECT_EQ(
-      expected_status,
+  base::WeakPtr<SpdySession> spdy_session =
       pool->CreateAvailableSessionFromSocket(
-          key, handle.Pass(), BoundNetLog(), OK, &spdy_session,
-          true /* is_secure */));
-  EXPECT_EQ(expected_status == OK, spdy_session != NULL);
-  EXPECT_EQ(expected_status == OK, HasSpdySession(pool, key));
+          key, handle.Pass(), BoundNetLog(), OK, true /* is_secure */);
+  // Failure is reported asynchronously.
+  EXPECT_TRUE(spdy_session != NULL);
+  EXPECT_TRUE(HasSpdySession(pool, key));
   return spdy_session;
 }
 
@@ -665,11 +680,12 @@ base::WeakPtr<SpdySession> CreateFakeSpdySession(SpdySessionPool* pool,
   return CreateFakeSpdySessionHelper(pool, key, OK);
 }
 
-void TryCreateFakeSpdySessionExpectingFailure(SpdySessionPool* pool,
-                                              const SpdySessionKey& key,
-                                              Error expected_error) {
+base::WeakPtr<SpdySession> TryCreateFakeSpdySessionExpectingFailure(
+    SpdySessionPool* pool,
+    const SpdySessionKey& key,
+    Error expected_error) {
   DCHECK_LT(expected_error, ERR_IO_PENDING);
-  CreateFakeSpdySessionHelper(pool, key, expected_error);
+  return CreateFakeSpdySessionHelper(pool, key, expected_error);
 }
 
 SpdySessionPoolPeer::SpdySessionPoolPeer(SpdySessionPool* pool) : pool_(pool) {
@@ -750,10 +766,8 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(
       break;
     case SYN_STREAM:
       {
-        size_t credential_slot = is_spdy2() ? 0 : header_info.credential_slot;
         frame = framer.CreateSynStream(header_info.id, header_info.assoc_id,
                                        header_info.priority,
-                                       credential_slot,
                                        header_info.control_flags,
                                        headers.get());
       }
@@ -796,8 +810,8 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
     SpdyFrameType type,
     SpdyControlFlags flags,
     SpdyStreamId associated_stream_id) const {
-  EXPECT_GE(type, FIRST_CONTROL_TYPE);
-  EXPECT_LE(type, LAST_CONTROL_TYPE);
+  EXPECT_GE(type, DATA);
+  EXPECT_LE(type, PRIORITY);
   const SpdyHeaderInfo header_info = {
     type,
     stream_id,
@@ -868,12 +882,25 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySettings(
         (it->second.first & SETTINGS_FLAG_PERSISTED) != 0,
         it->second.second);
   }
-  return CreateFramer()->SerializeSettings(settings_ir);
+  return CreateFramer(false)->SerializeFrame(settings_ir);
+}
+
+SpdyFrame* SpdyTestUtil::ConstructSpdySettingsAck() const {
+  char kEmptyWrite[] = "";
+
+  if (spdy_version() > SPDY3) {
+    SpdySettingsIR settings_ir;
+    settings_ir.set_is_ack(true);
+    return CreateFramer(false)->SerializeFrame(settings_ir);
+  }
+  // No settings ACK write occurs. Create an empty placeholder write.
+  return new SpdyFrame(kEmptyWrite, 0, false);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id) const {
+SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id, bool is_ack) const {
   SpdyPingIR ping_ir(ping_id);
-  return CreateFramer()->SerializePing(ping_ir);
+  ping_ir.set_is_ack(is_ack);
+  return CreateFramer(false)->SerializeFrame(ping_ir);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway() const {
@@ -883,13 +910,20 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway() const {
 SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(
     SpdyStreamId last_good_stream_id) const {
   SpdyGoAwayIR go_ir(last_good_stream_id, GOAWAY_OK, "go away");
-  return CreateFramer()->SerializeGoAway(go_ir);
+  return CreateFramer(false)->SerializeFrame(go_ir);
+}
+
+SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(SpdyStreamId last_good_stream_id,
+                                             SpdyGoAwayStatus status,
+                                             const std::string& desc) const {
+  SpdyGoAwayIR go_ir(last_good_stream_id, status, desc);
+  return CreateFramer(false)->SerializeFrame(go_ir);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(
     const SpdyStreamId stream_id, uint32 delta_window_size) const {
   SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
-  return CreateFramer()->SerializeWindowUpdate(update_ir);
+  return CreateFramer(false)->SerializeFrame(update_ir);
 }
 
 // TODO(jgraettinger): Eliminate uses of this method in tests (prefer
@@ -897,8 +931,8 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(
 SpdyFrame* SpdyTestUtil::ConstructSpdyRstStream(
     SpdyStreamId stream_id,
     SpdyRstStreamStatus status) const {
-  SpdyRstStreamIR rst_ir(stream_id, status, "RST");
-  return CreateFramer()->SerializeRstStream(rst_ir);
+  SpdyRstStreamIR rst_ir(stream_id, status, "");
+  return CreateFramer(false)->SerializeRstStream(rst_ir);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyGet(
@@ -906,20 +940,9 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGet(
     bool compressed,
     SpdyStreamId stream_id,
     RequestPriority request_priority) const {
-  const SpdyHeaderInfo header_info = {
-    SYN_STREAM,
-    stream_id,
-    0,                   // associated stream ID
-    ConvertRequestPriorityToSpdyPriority(request_priority, spdy_version_),
-    0,                   // credential slot
-    CONTROL_FLAG_FIN,
-    compressed,
-    RST_STREAM_INVALID,  // status
-    NULL,                // data
-    0,                   // length
-    DATA_FLAG_NONE
-  };
-  return ConstructSpdyFrame(header_info, ConstructGetHeaderBlock(url));
+  scoped_ptr<SpdyHeaderBlock> block(ConstructGetHeaderBlock(url));
+  return ConstructSpdySyn(
+      stream_id, *block, request_priority, compressed, true);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const extra_headers[],
@@ -928,25 +951,15 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const extra_headers[],
                                           int stream_id,
                                           RequestPriority request_priority,
                                           bool direct) const {
-  const bool spdy2 = is_spdy2();
-  const char* url = (spdy2 && !direct) ? "http://www.google.com/" : "/";
-  const char* const kStandardGetHeaders[] = {
-    GetMethodKey(),  "GET",
-    GetHostKey(),    "www.google.com",
-    GetSchemeKey(),  "http",
-    GetVersionKey(), "HTTP/1.1",
-    GetPathKey(),    url
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   compressed,
-                                   stream_id,
-                                   request_priority,
-                                   SYN_STREAM,
-                                   CONTROL_FLAG_FIN,
-                                   kStandardGetHeaders,
-                                   arraysize(kStandardGetHeaders),
-                                   0);
+  SpdyHeaderBlock block;
+  block[GetMethodKey()] = "GET";
+  block[GetPathKey()] =
+      (is_spdy2() && !direct) ? "http://www.google.com/" : "/";
+  block[GetHostKey()] = "www.google.com";
+  block[GetSchemeKey()] = "http";
+  MaybeAddVersionHeader(&block);
+  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
+  return ConstructSpdySyn(stream_id, block, request_priority, compressed, true);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyConnect(
@@ -954,22 +967,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyConnect(
     int extra_header_count,
     int stream_id,
     RequestPriority priority) const {
-  const char* const kConnectHeaders[] = {
-    GetMethodKey(),  "CONNECT",
-    GetPathKey(),    "www.google.com:443",
-    GetHostKey(),    "www.google.com",
-    GetVersionKey(), "HTTP/1.1",
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   /*compressed*/ false,
-                                   stream_id,
-                                   priority,
-                                   SYN_STREAM,
-                                   CONTROL_FLAG_NONE,
-                                   kConnectHeaders,
-                                   arraysize(kConnectHeaders),
-                                   0);
+  SpdyHeaderBlock block;
+  block[GetMethodKey()] = "CONNECT";
+  block[GetPathKey()] = "www.google.com:443";
+  block[GetHostKey()] = "www.google.com";
+  MaybeAddVersionHeader(&block);
+  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
+  return ConstructSpdySyn(stream_id, block, priority, false, false);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
@@ -977,19 +981,41 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
                                            int stream_id,
                                            int associated_stream_id,
                                            const char* url) {
-  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
-  (*headers)["hello"] = "bye";
-  (*headers)[GetStatusKey()] = "200 OK";
-  (*headers)[GetVersionKey()] = "HTTP/1.1";
-  AddUrlToHeaderBlock(url, headers.get());
-  AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
-  return ConstructSpdyControlFrame(headers.Pass(),
-                                   false,
-                                   stream_id,
-                                   LOWEST,
-                                   SYN_STREAM,
-                                   CONTROL_FLAG_NONE,
-                                   associated_stream_id);
+  if (spdy_version() < SPDY4) {
+    SpdySynStreamIR syn_stream(stream_id);
+    syn_stream.set_associated_to_stream_id(associated_stream_id);
+    syn_stream.SetHeader("hello", "bye");
+    syn_stream.SetHeader(GetStatusKey(), "200 OK");
+    syn_stream.SetHeader(GetVersionKey(), "HTTP/1.1");
+    AddUrlToHeaderBlock(url, syn_stream.mutable_name_value_block());
+    AppendToHeaderBlock(extra_headers,
+                        extra_header_count,
+                        syn_stream.mutable_name_value_block());
+    return CreateFramer(false)->SerializeFrame(syn_stream);
+  } else {
+    SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
+    AddUrlToHeaderBlock(url, push_promise.mutable_name_value_block());
+    scoped_ptr<SpdyFrame> push_promise_frame(
+        CreateFramer(false)->SerializeFrame(push_promise));
+
+    SpdyHeadersIR headers(stream_id);
+    headers.SetHeader("hello", "bye");
+    headers.SetHeader(GetStatusKey(), "200 OK");
+    AppendToHeaderBlock(
+        extra_headers, extra_header_count, headers.mutable_name_value_block());
+    scoped_ptr<SpdyFrame> headers_frame(
+        CreateFramer(false)->SerializeFrame(headers));
+
+    int joint_data_size = push_promise_frame->size() + headers_frame->size();
+    scoped_ptr<char[]> data(new char[joint_data_size]);
+    const SpdyFrame* frames[2] = {
+        push_promise_frame.get(), headers_frame.get(),
+    };
+    int combined_size =
+        CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
+    DCHECK_EQ(combined_size, joint_data_size);
+    return new SpdyFrame(data.release(), joint_data_size, true);
+  }
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
@@ -999,40 +1025,108 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
                                            const char* url,
                                            const char* status,
                                            const char* location) {
-  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
-  (*headers)["hello"] = "bye";
-  (*headers)[GetStatusKey()] = status;
-  (*headers)[GetVersionKey()] = "HTTP/1.1";
-  (*headers)["location"] = location;
-  AddUrlToHeaderBlock(url, headers.get());
-  AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
-  return ConstructSpdyControlFrame(headers.Pass(),
-                                   false,
-                                   stream_id,
-                                   LOWEST,
-                                   SYN_STREAM,
-                                   CONTROL_FLAG_NONE,
-                                   associated_stream_id);
+  if (spdy_version() < SPDY4) {
+    SpdySynStreamIR syn_stream(stream_id);
+    syn_stream.set_associated_to_stream_id(associated_stream_id);
+    syn_stream.SetHeader("hello", "bye");
+    syn_stream.SetHeader(GetStatusKey(), status);
+    syn_stream.SetHeader(GetVersionKey(), "HTTP/1.1");
+    syn_stream.SetHeader("location", location);
+    AddUrlToHeaderBlock(url, syn_stream.mutable_name_value_block());
+    AppendToHeaderBlock(extra_headers,
+                        extra_header_count,
+                        syn_stream.mutable_name_value_block());
+    return CreateFramer(false)->SerializeFrame(syn_stream);
+  } else {
+    SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
+    AddUrlToHeaderBlock(url, push_promise.mutable_name_value_block());
+    scoped_ptr<SpdyFrame> push_promise_frame(
+        CreateFramer(false)->SerializeFrame(push_promise));
+
+    SpdyHeadersIR headers(stream_id);
+    headers.SetHeader("hello", "bye");
+    headers.SetHeader(GetStatusKey(), status);
+    headers.SetHeader("location", location);
+    AppendToHeaderBlock(
+        extra_headers, extra_header_count, headers.mutable_name_value_block());
+    scoped_ptr<SpdyFrame> headers_frame(
+        CreateFramer(false)->SerializeFrame(headers));
+
+    int joint_data_size = push_promise_frame->size() + headers_frame->size();
+    scoped_ptr<char[]> data(new char[joint_data_size]);
+    const SpdyFrame* frames[2] = {
+        push_promise_frame.get(), headers_frame.get(),
+    };
+    int combined_size =
+        CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
+    DCHECK_EQ(combined_size, joint_data_size);
+    return new SpdyFrame(data.release(), joint_data_size, true);
+  }
+}
+
+SpdyFrame* SpdyTestUtil::ConstructInitialSpdyPushFrame(
+    scoped_ptr<SpdyHeaderBlock> headers,
+    int stream_id,
+    int associated_stream_id) {
+  if (spdy_version() < SPDY4) {
+    SpdySynStreamIR syn_stream(stream_id);
+    syn_stream.set_associated_to_stream_id(associated_stream_id);
+    SetPriority(LOWEST, &syn_stream);
+    syn_stream.set_name_value_block(*headers);
+    return CreateFramer(false)->SerializeFrame(syn_stream);
+  } else {
+    SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
+    push_promise.set_name_value_block(*headers);
+    return CreateFramer(false)->SerializeFrame(push_promise);
+  }
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyPushHeaders(
     int stream_id,
     const char* const extra_headers[],
     int extra_header_count) {
-  const char* const kStandardGetHeaders[] = {
-    GetStatusKey(), "200 OK",
-    GetVersionKey(), "HTTP/1.1"
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   false,
-                                   stream_id,
-                                   LOWEST,
-                                   HEADERS,
-                                   CONTROL_FLAG_NONE,
-                                   kStandardGetHeaders,
-                                   arraysize(kStandardGetHeaders),
-                                   0);
+  SpdyHeadersIR headers(stream_id);
+  headers.SetHeader(GetStatusKey(), "200 OK");
+  MaybeAddVersionHeader(&headers);
+  AppendToHeaderBlock(extra_headers, extra_header_count,
+                      headers.mutable_name_value_block());
+  return CreateFramer(false)->SerializeFrame(headers);
+}
+
+SpdyFrame* SpdyTestUtil::ConstructSpdySyn(int stream_id,
+                                          const SpdyHeaderBlock& block,
+                                          RequestPriority priority,
+                                          bool compressed,
+                                          bool fin) const {
+  if (protocol_ < kProtoSPDY4) {
+    SpdySynStreamIR syn_stream(stream_id);
+    syn_stream.set_name_value_block(block);
+    syn_stream.set_priority(
+        ConvertRequestPriorityToSpdyPriority(priority, spdy_version()));
+    syn_stream.set_fin(fin);
+    return CreateFramer(compressed)->SerializeFrame(syn_stream);
+  } else {
+    SpdyHeadersIR headers(stream_id);
+    headers.set_name_value_block(block);
+    headers.set_has_priority(true);
+    headers.set_priority(
+        ConvertRequestPriorityToSpdyPriority(priority, spdy_version()));
+    headers.set_fin(fin);
+    return CreateFramer(compressed)->SerializeFrame(headers);
+  }
+}
+
+SpdyFrame* SpdyTestUtil::ConstructSpdyReply(int stream_id,
+                                            const SpdyHeaderBlock& headers) {
+  if (protocol_ < kProtoSPDY4) {
+    SpdySynReplyIR syn_reply(stream_id);
+    syn_reply.set_name_value_block(headers);
+    return CreateFramer(false)->SerializeFrame(syn_reply);
+  } else {
+    SpdyHeadersIR reply(stream_id);
+    reply.set_name_value_block(headers);
+    return CreateFramer(false)->SerializeFrame(reply);
+  }
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError(
@@ -1040,21 +1134,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError(
     const char* const* const extra_headers,
     int extra_header_count,
     int stream_id) {
-  const char* const kStandardGetHeaders[] = {
-    "hello", "bye",
-    GetStatusKey(), status,
-    GetVersionKey(), "HTTP/1.1"
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   false,
-                                   stream_id,
-                                   LOWEST,
-                                   SYN_REPLY,
-                                   CONTROL_FLAG_NONE,
-                                   kStandardGetHeaders,
-                                   arraysize(kStandardGetHeaders),
-                                   0);
+  SpdyHeaderBlock block;
+  block["hello"] = "bye";
+  block[GetStatusKey()] = status;
+  MaybeAddVersionHeader(&block);
+  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
+
+  return ConstructSpdyReply(stream_id, block);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReplyRedirect(int stream_id) {
@@ -1073,21 +1159,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReply(
     const char* const extra_headers[],
     int extra_header_count,
     int stream_id) {
-  const char* const kStandardGetHeaders[] = {
-    "hello", "bye",
-    GetStatusKey(), "200",
-    GetVersionKey(), "HTTP/1.1"
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   false,
-                                   stream_id,
-                                   LOWEST,
-                                   SYN_REPLY,
-                                   CONTROL_FLAG_NONE,
-                                   kStandardGetHeaders,
-                                   arraysize(kStandardGetHeaders),
-                                   0);
+  SpdyHeaderBlock block;
+  block["hello"] = "bye";
+  block[GetStatusKey()] = "200";
+  MaybeAddVersionHeader(&block);
+  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
+
+  return ConstructSpdyReply(stream_id, block);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url,
@@ -1096,64 +1174,30 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url,
                                            RequestPriority priority,
                                            const char* const extra_headers[],
                                            int extra_header_count) {
-  const SpdyHeaderInfo kSynStartHeader = {
-    SYN_STREAM,
-    stream_id,
-    0,                      // Associated stream ID
-    ConvertRequestPriorityToSpdyPriority(priority, spdy_version_),
-    kSpdyCredentialSlotUnused,
-    CONTROL_FLAG_NONE,
-    false,                  // Compressed
-    RST_STREAM_INVALID,
-    NULL,                   // Data
-    0,                      // Length
-    DATA_FLAG_NONE
-  };
-  return ConstructSpdyFrame(
-      kSynStartHeader, ConstructPostHeaderBlock(url, content_length));
+  scoped_ptr<SpdyHeaderBlock> block(
+      ConstructPostHeaderBlock(url, content_length));
+  AppendToHeaderBlock(extra_headers, extra_header_count, block.get());
+  return ConstructSpdySyn(stream_id, *block, priority, false, false);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructChunkedSpdyPost(
     const char* const extra_headers[],
     int extra_header_count) {
-  const char* post_headers[] = {
-    GetMethodKey(), "POST",
-    GetPathKey(), "/",
-    GetHostKey(), "www.google.com",
-    GetSchemeKey(), "http",
-    GetVersionKey(), "HTTP/1.1"
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   false,
-                                   1,
-                                   LOWEST,
-                                   SYN_STREAM,
-                                   CONTROL_FLAG_NONE,
-                                   post_headers,
-                                   arraysize(post_headers),
-                                   0);
+  SpdyHeaderBlock block;
+  block[GetMethodKey()] = "POST";
+  block[GetPathKey()] = "/";
+  block[GetHostKey()] = "www.google.com";
+  block[GetSchemeKey()] = "http";
+  MaybeAddVersionHeader(&block);
+  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
+  return ConstructSpdySyn(1, block, LOWEST, false, false);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyPostSynReply(
     const char* const extra_headers[],
     int extra_header_count) {
-  const char* const kStandardGetHeaders[] = {
-    "hello", "bye",
-    GetStatusKey(), "200",
-    GetPathKey(), "/index.php",
-    GetVersionKey(), "HTTP/1.1"
-  };
-  return ConstructSpdyControlFrame(extra_headers,
-                                   extra_header_count,
-                                   false,
-                                   1,
-                                   LOWEST,
-                                   SYN_REPLY,
-                                   CONTROL_FLAG_NONE,
-                                   kStandardGetHeaders,
-                                   arraysize(kStandardGetHeaders),
-                                   0);
+  // TODO(jgraettinger): Remove this method.
+  return ConstructSpdyGetSynReply(NULL, 0, 1);
 }
 
 SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, bool fin) {
@@ -1198,8 +1242,10 @@ const SpdyHeaderInfo SpdyTestUtil::MakeSpdyHeader(SpdyFrameType type) {
   return kHeader;
 }
 
-scoped_ptr<SpdyFramer> SpdyTestUtil::CreateFramer() const {
-  return scoped_ptr<SpdyFramer>(new SpdyFramer(spdy_version_));
+scoped_ptr<SpdyFramer> SpdyTestUtil::CreateFramer(bool compressed) const {
+  scoped_ptr<SpdyFramer> framer(new SpdyFramer(spdy_version_));
+  framer->set_enable_compression(compressed);
+  return framer.Pass();
 }
 
 const char* SpdyTestUtil::GetMethodKey() const {
@@ -1211,7 +1257,12 @@ const char* SpdyTestUtil::GetStatusKey() const {
 }
 
 const char* SpdyTestUtil::GetHostKey() const {
-  return is_spdy2() ? "host" : ":host";
+  if (protocol_ < kProtoSPDY3)
+    return "host";
+  if (protocol_ < kProtoSPDY4)
+    return ":host";
+  else
+    return ":authority";
 }
 
 const char* SpdyTestUtil::GetSchemeKey() const {
@@ -1237,7 +1288,9 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock(
   (*headers)[GetPathKey()] = path.c_str();
   (*headers)[GetHostKey()] = host.c_str();
   (*headers)[GetSchemeKey()] = scheme.c_str();
-  (*headers)[GetVersionKey()] = "HTTP/1.1";
+  if (include_version_header()) {
+    (*headers)[GetVersionKey()] = "HTTP/1.1";
+  }
   if (content_length) {
     std::string length_str = base::Int64ToString(*content_length);
     (*headers)["content-length"] = length_str;
@@ -1245,4 +1298,23 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock(
   return headers.Pass();
 }
 
+void SpdyTestUtil::MaybeAddVersionHeader(
+    SpdyFrameWithNameValueBlockIR* frame_ir) const {
+  if (include_version_header()) {
+    frame_ir->SetHeader(GetVersionKey(), "HTTP/1.1");
+  }
+}
+
+void SpdyTestUtil::MaybeAddVersionHeader(SpdyHeaderBlock* block) const {
+  if (include_version_header()) {
+    (*block)[GetVersionKey()] = "HTTP/1.1";
+  }
+}
+
+void SpdyTestUtil::SetPriority(RequestPriority priority,
+                               SpdySynStreamIR* ir) const {
+  ir->set_priority(ConvertRequestPriorityToSpdyPriority(
+      priority, spdy_version()));
+}
+
 }  // namespace net