12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_util_common.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cstddef>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_split.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/mock_cert_verifier.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_cache.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_network_session.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_network_transaction.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_server_properties_impl.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/socket_test_util.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/socket/ssl_client_socket.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/socket/transport_client_socket_pool.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/buffered_spdy_framer.h"
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/spdy/spdy_framer.h"
23a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/spdy/spdy_http_utils.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_session.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/spdy/spdy_session_pool.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_stream.h"
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool next_proto_is_spdy(NextProto next_proto) {
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return next_proto >= kProtoSPDYMinimumVersion &&
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      next_proto <= kProtoSPDYMaximumVersion;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Parses a URL into the scheme, host, and path components required for a
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// SPDY request.
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ParseUrl(base::StringPiece url, std::string* scheme, std::string* host,
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              std::string* path) {
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL gurl(url.as_string());
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  path->assign(gurl.PathForRequest());
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheme->assign(gurl.scheme());
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  host->assign(gurl.host());
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (gurl.has_port()) {
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    host->append(":");
48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    host->append(gurl.port());
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)NextProtoVector SpdyNextProtos() {
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NextProtoVector next_protos;
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  next_protos.push_back(kProtoHTTP11);
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  next_protos.push_back(kProtoDeprecatedSPDY2);
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  next_protos.push_back(kProtoSPDY3);
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  next_protos.push_back(kProtoSPDY31);
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  next_protos.push_back(kProtoSPDY4);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  next_protos.push_back(kProtoQUIC1SPDY3);
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return next_protos;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a frame into an array of MockWrites.
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |data| is the frame to chop.
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |length| is the length of the frame to chop.
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite* chunks = new MockWrite[num_chunks];
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int chunk_size = length / num_chunks;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int index = 0; index < num_chunks; index++) {
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* ptr = data + (index * chunk_size);
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (index == num_chunks - 1)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chunks;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a SpdyFrame into an array of MockWrites.
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |frame| is the frame to chop.
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks) {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ChopWriteFrame(frame.data(), frame.size(), num_chunks);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a frame into an array of MockReads.
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |data| is the frame to chop.
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |length| is the length of the frame to chop.
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead* ChopReadFrame(const char* data, int length, int num_chunks) {
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead* chunks = new MockRead[num_chunks];
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int chunk_size = length / num_chunks;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int index = 0; index < num_chunks; index++) {
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* ptr = data + (index * chunk_size);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (index == num_chunks - 1)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    chunks[index] = MockRead(ASYNC, ptr, chunk_size);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chunks;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a SpdyFrame into an array of MockReads.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |frame| is the frame to chop.
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks) {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ChopReadFrame(frame.data(), frame.size(), num_chunks);
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Adds headers and values to a map.
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |extra_headers| is an array of { name, value } pairs, arranged as strings
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// where the even entries are the header names, and the odd entries are the
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// header values.
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |headers| gets filled in from |extra_headers|.
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppendToHeaderBlock(const char* const extra_headers[],
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int extra_header_count,
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         SpdyHeaderBlock* headers) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string this_header;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string this_value;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!extra_header_count)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sanity check: Non-NULL header list.
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != extra_headers) << "NULL header value pair list";
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sanity check: Non-NULL header map.
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != headers) << "NULL header map";
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Copy in the headers.
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < extra_header_count; i++) {
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Sanity check: Non-empty header.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    this_header = extra_headers[i * 2];
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string::size_type header_len = this_header.length();
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!header_len)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    this_value = extra_headers[1 + (i * 2)];
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string new_value;
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (headers->find(this_header) != headers->end()) {
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // More than one entry in the header.
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Don't add the header again, just the append to the value,
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // separated by a NULL character.
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Adjust the value.
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value = (*headers)[this_header];
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Put in a NULL separator.
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value.append(1, '\0');
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Append the new value.
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value += this_value;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Not a duplicate, just write the value.
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value = this_value;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    (*headers)[this_header] = new_value;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockWrite from the given SpdyFrame.
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite CreateMockWrite(const SpdyFrame& req) {
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockWrite(ASYNC, req.data(), req.size());
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockWrite from the given SpdyFrame and sequence number.
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite CreateMockWrite(const SpdyFrame& req, int seq) {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CreateMockWrite(req, seq, ASYNC);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockWrite from the given SpdyFrame and sequence number.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode) {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockWrite(mode, req.data(), req.size(), seq);
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockRead from the given SpdyFrame.
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead CreateMockRead(const SpdyFrame& resp) {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockRead(ASYNC, resp.data(), resp.size());
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockRead from the given SpdyFrame and sequence number.
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead CreateMockRead(const SpdyFrame& resp, int seq) {
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CreateMockRead(resp, seq, ASYNC);
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockRead from the given SpdyFrame and sequence number.
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode) {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockRead(mode, resp.data(), resp.size(), seq);
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Combines the given SpdyFrames into the given char array and returns
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the total length.
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int CombineFrames(const SpdyFrame** frames, int num_frames,
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  char* buff, int buff_len) {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int total_len = 0;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < num_frames; ++i) {
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    total_len += frames[i]->size();
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_LE(total_len, buff_len);
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  char* ptr = buff;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < num_frames; ++i) {
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int len = frames[i]->size();
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    memcpy(ptr, frames[i]->data(), len);
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ptr += len;
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return total_len;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityGetter() : priority_(0) {}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~PriorityGetter() {}
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyPriority priority() const {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return priority_;
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE {}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStreamError(SpdyStreamId stream_id,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& description) OVERRIDE {}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSynStream(SpdyStreamId stream_id,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyStreamId associated_stream_id,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyPriority priority,
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool fin,
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool unidirectional,
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SpdyHeaderBlock& headers) OVERRIDE {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority_ = priority;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSynReply(SpdyStreamId stream_id,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          bool fin,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const SpdyHeaderBlock& headers) OVERRIDE {}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHeaders(SpdyStreamId stream_id,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool fin,
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const SpdyHeaderBlock& headers) OVERRIDE {}
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 size_t length,
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 bool fin) OVERRIDE {}
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStreamFrameData(SpdyStreamId stream_id,
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const char* data,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 size_t len,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) OVERRIDE {}
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSettings(bool clear_persisted) OVERRIDE {}
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSetting(
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE {}
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnRstStream(SpdyStreamId stream_id,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyRstStreamStatus status) OVERRIDE {}
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        SpdyGoAwayStatus status) OVERRIDE {}
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowUpdate(SpdyStreamId stream_id,
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32 delta_window_size) OVERRIDE {}
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnPushPromise(SpdyStreamId stream_id,
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             SpdyStreamId promised_stream_id,
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             const SpdyHeaderBlock& headers) OVERRIDE {}
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE {
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyPriority priority_;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool GetSpdyPriority(SpdyMajorVersion version,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const SpdyFrame& frame,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     SpdyPriority* priority) {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferedSpdyFramer framer(version, false);
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityGetter priority_getter;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_visitor(&priority_getter);
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t frame_size = frame.size();
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (framer.ProcessInput(frame.data(), frame_size) != frame_size) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *priority = priority_getter.priority();
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)base::WeakPtr<SpdyStream> CreateStreamSynchronously(
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdyStreamType type,
280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const base::WeakPtr<SpdySession>& session,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RequestPriority priority,
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BoundNetLog& net_log) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyStreamRequest stream_request;
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int rv = stream_request.StartRequest(type, session, url, priority, net_log,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       CompletionCallback());
287a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return
288a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      (rv == OK) ? stream_request.ReleaseStream() : base::WeakPtr<SpdyStream>();
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)StreamReleaserCallback::StreamReleaserCallback() {}
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StreamReleaserCallback::~StreamReleaserCallback() {}
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CompletionCallback StreamReleaserCallback::MakeCallback(
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyStreamRequest* request) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::Bind(&StreamReleaserCallback::OnComplete,
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    base::Unretained(this),
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    request);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StreamReleaserCallback::OnComplete(
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyStreamRequest* request, int result) {
304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (result == OK)
305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    request->ReleaseStream()->Cancel();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResult(result);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockECSignatureCreator::MockECSignatureCreator(crypto::ECPrivateKey* key)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : key_(key) {
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MockECSignatureCreator::Sign(const uint8* data,
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int data_len,
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  std::vector<uint8>* signature) {
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<uint8> private_key_value;
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  key_->ExportValue(&private_key_value);
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string head = "fakesignature";
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string tail = "/fakesignature";
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->clear();
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), head.begin(), head.end());
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), private_key_value.begin(),
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    private_key_value.end());
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), '-');
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), data, data + data_len);
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), tail.begin(), tail.end());
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MockECSignatureCreator::DecodeSignature(
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::vector<uint8>& signature,
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<uint8>* out_raw_sig) {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *out_raw_sig = signature;
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockECSignatureCreatorFactory::MockECSignatureCreatorFactory() {
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  crypto::ECSignatureCreator::SetFactoryForTesting(this);
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockECSignatureCreatorFactory::~MockECSignatureCreatorFactory() {
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)crypto::ECSignatureCreator* MockECSignatureCreatorFactory::Create(
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    crypto::ECPrivateKey* key) {
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new MockECSignatureCreator(key);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionDependencies::SpdySessionDependencies(NextProto protocol)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : host_resolver(new MockCachingHostResolver),
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cert_verifier(new MockCertVerifier),
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      transport_security_state(new TransportSecurityState),
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      proxy_service(ProxyService::CreateDirect()),
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ssl_config_service(new SSLConfigServiceDefaults),
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      socket_factory(new MockClientSocketFactory),
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      http_auth_handler_factory(
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_ip_pooling(true),
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_compression(false),
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_ping(false),
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_user_alternate_protocol_ports(false),
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      protocol(protocol),
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_initial_recv_window_size(kSpdyStreamInitialWindowSize),
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      time_func(&base::TimeTicks::Now),
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      force_spdy_over_ssl(false),
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      force_spdy_always(false),
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      use_alternate_protocols(false),
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      enable_websocket_over_spdy(false),
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net_log(NULL) {
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: The CancelledTransaction test does cleanup by running all
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // tasks in the message loop (RunAllPending).  Unfortunately, that
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // doesn't clean up tasks on the host resolver thread; and
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TCPConnectJob is currently not cancellable.  Using synchronous
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // lookups allows the test to shutdown cleanly.  Until we have
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // cancellable TCPConnectJobs, use synchronous lookups.
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_resolver->set_synchronous_mode(true);
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionDependencies::SpdySessionDependencies(
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NextProto protocol, ProxyService* proxy_service)
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : host_resolver(new MockHostResolver),
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cert_verifier(new MockCertVerifier),
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      transport_security_state(new TransportSecurityState),
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      proxy_service(proxy_service),
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ssl_config_service(new SSLConfigServiceDefaults),
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      socket_factory(new MockClientSocketFactory),
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      http_auth_handler_factory(
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_ip_pooling(true),
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_compression(false),
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_ping(false),
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_user_alternate_protocol_ports(false),
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      protocol(protocol),
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_initial_recv_window_size(kSpdyStreamInitialWindowSize),
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      time_func(&base::TimeTicks::Now),
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      force_spdy_over_ssl(false),
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      force_spdy_always(false),
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      use_alternate_protocols(false),
40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      enable_websocket_over_spdy(false),
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net_log(NULL) {
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionDependencies::~SpdySessionDependencies() {}
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps) {
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.client_socket_factory = session_deps->socket_factory.get();
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpNetworkSession* http_session = new HttpNetworkSession(params);
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  pool_peer.SetEnableSendingInitialData(false);
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return http_session;
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps) {
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.client_socket_factory =
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->deterministic_socket_factory.get();
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpNetworkSession* http_session = new HttpNetworkSession(params);
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  pool_peer.SetEnableSendingInitialData(false);
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return http_session;
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)net::HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps) {
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(session_deps->protocol)) <<
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "Invalid protocol: " << session_deps->protocol;
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params;
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.host_resolver = session_deps->host_resolver.get();
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.cert_verifier = session_deps->cert_verifier.get();
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  params.transport_security_state =
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      session_deps->transport_security_state.get();
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.proxy_service = session_deps->proxy_service.get();
447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  params.ssl_config_service = session_deps->ssl_config_service.get();
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_auth_handler_factory =
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->http_auth_handler_factory.get();
450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  params.http_server_properties =
451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      session_deps->http_server_properties.GetWeakPtr();
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_compression = session_deps->enable_compression;
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping;
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_user_alternate_protocol_ports =
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->enable_user_alternate_protocol_ports;
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.spdy_default_protocol = session_deps->protocol;
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.spdy_stream_initial_recv_window_size =
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->stream_initial_recv_window_size;
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.time_func = session_deps->time_func;
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.next_protos = session_deps->next_protos;
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.trusted_spdy_proxy = session_deps->trusted_spdy_proxy;
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.force_spdy_over_ssl = session_deps->force_spdy_over_ssl;
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.force_spdy_always = session_deps->force_spdy_always;
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.use_alternate_protocols = session_deps->use_alternate_protocols;
46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.enable_websocket_over_spdy = session_deps->enable_websocket_over_spdy;
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.net_log = session_deps->net_log;
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return params;
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol,
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             bool force_spdy_over_ssl,
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             bool force_spdy_always)
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : storage_(this) {
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_cert_verifier(new MockCertVerifier);
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  storage_.set_transport_security_state(new TransportSecurityState);
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_proxy_service(ProxyService::CreateDirect());
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_resolver()));
483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  storage_.set_http_server_properties(
484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  storage_.set_job_factory(new URLRequestJobFactoryImpl());
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params;
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.client_socket_factory = &socket_factory_;
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.host_resolver = host_resolver();
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.cert_verifier = cert_verifier();
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  params.transport_security_state = transport_security_state();
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.proxy_service = proxy_service();
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.ssl_config_service = ssl_config_service();
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_auth_handler_factory = http_auth_handler_factory();
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.network_delegate = network_delegate();
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_compression = false;
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_ping_based_connection_checking = false;
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.spdy_default_protocol = protocol;
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.force_spdy_over_ssl = force_spdy_over_ssl;
499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.force_spdy_always = force_spdy_always;
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_server_properties = http_server_properties();
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> network_session(
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new HttpNetworkSession(params));
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionPoolPeer pool_peer(network_session->spdy_session_pool());
504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  pool_peer.SetEnableSendingInitialData(false);
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_http_transaction_factory(new HttpCache(
506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      network_session.get(), HttpCache::DefaultBackend::InMemory(0)));
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdyURLRequestContext::~SpdyURLRequestContext() {
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AssertNoURLRequests();
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key) {
5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return pool->FindAvailableSession(key, BoundNetLog()) != NULL;
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
5187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
519ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::WeakPtr<SpdySession> CreateSpdySessionHelper(
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const scoped_refptr<HttpNetworkSession>& http_session,
5217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SpdySessionKey& key,
5227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const BoundNetLog& net_log,
523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    Error expected_status,
5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool is_secure) {
5257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(HasSpdySession(http_session->spdy_session_pool(), key));
5267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<TransportSocketParams> transport_params(
5287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      new TransportSocketParams(
5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          key.host_port_pair(), false, false, OnHostResolutionCallback(),
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
5317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestCompletionCallback callback;
5347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int rv = ERR_UNEXPECTED;
5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (is_secure) {
5377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SSLConfig ssl_config;
5387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_refptr<SSLSocketParams> ssl_params(
5397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        new SSLSocketParams(transport_params,
5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                            NULL,
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                            NULL,
5427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            key.host_port_pair(),
5437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            ssl_config,
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            key.privacy_mode(),
5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            0,
5467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            false,
5477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            false));
5487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    rv = connection->Init(key.host_port_pair().ToString(),
5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          ssl_params,
5507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          MEDIUM,
5517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          callback.callback(),
5527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          http_session->GetSSLSocketPool(
5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                              HttpNetworkSession::NORMAL_SOCKET_POOL),
5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          net_log);
5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
5567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    rv = connection->Init(key.host_port_pair().ToString(),
5577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          transport_params,
5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          MEDIUM,
5597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          callback.callback(),
5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          http_session->GetTransportSocketPool(
5617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                              HttpNetworkSession::NORMAL_SOCKET_POOL),
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          net_log);
5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (rv == ERR_IO_PENDING)
5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    rv = callback.WaitForResult();
5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(OK, rv);
5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
570effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::WeakPtr<SpdySession> spdy_session =
5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
572effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          key, connection.Pass(), net_log, OK, is_secure);
573effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Failure is reported asynchronously.
574effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(spdy_session != NULL);
575effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return spdy_session;
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::WeakPtr<SpdySession> CreateInsecureSpdySession(
5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const scoped_refptr<HttpNetworkSession>& http_session,
5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SpdySessionKey& key,
5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const BoundNetLog& net_log) {
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return CreateSpdySessionHelper(http_session, key, net_log,
586ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 OK, false /* is_secure */);
5877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
589effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbase::WeakPtr<SpdySession> TryCreateInsecureSpdySessionExpectingFailure(
590ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const scoped_refptr<HttpNetworkSession>& http_session,
591ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const SpdySessionKey& key,
592ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    Error expected_error,
593ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const BoundNetLog& net_log) {
594ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK_LT(expected_error, ERR_IO_PENDING);
595effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return CreateSpdySessionHelper(http_session, key, net_log,
596effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 expected_error, false /* is_secure */);
597ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
598ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::WeakPtr<SpdySession> CreateSecureSpdySession(
6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const scoped_refptr<HttpNetworkSession>& http_session,
6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SpdySessionKey& key,
6027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const BoundNetLog& net_log) {
6037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return CreateSpdySessionHelper(http_session, key, net_log,
604ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 OK, true /* is_secure */);
6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// A ClientSocket used for CreateFakeSpdySession() below.
6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass FakeSpdySessionClientSocket : public MockClientSocket {
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
612ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  FakeSpdySessionClientSocket(int read_result)
613ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      : MockClientSocket(BoundNetLog()),
614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        read_result_(read_result) {}
615ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
6167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual ~FakeSpdySessionClientSocket() {}
6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual int Read(IOBuffer* buf, int buf_len,
6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   const CompletionCallback& callback) OVERRIDE {
620ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return read_result_;
6217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual int Write(IOBuffer* buf, int buf_len,
6247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    const CompletionCallback& callback) OVERRIDE {
6257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return ERR_IO_PENDING;
6267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Return kProtoUnknown to use the pool's default protocol.
6297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
6307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return kProtoUnknown;
6317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The functions below are not expected to be called.
6347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual int Connect(const CompletionCallback& callback) OVERRIDE {
6367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ADD_FAILURE();
6377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return ERR_UNEXPECTED;
6387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool WasEverUsed() const OVERRIDE {
6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ADD_FAILURE();
6427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return false;
6437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool UsingTCPFastOpen() const OVERRIDE {
6467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ADD_FAILURE();
6477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return false;
6487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool WasNpnNegotiated() const OVERRIDE {
6517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ADD_FAILURE();
6527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return false;
6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ADD_FAILURE();
6577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return false;
6587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
660ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private:
661ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int read_result_;
662ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
6637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
664ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::WeakPtr<SpdySession> CreateFakeSpdySessionHelper(
665ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SpdySessionPool* pool,
666ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const SpdySessionKey& key,
667ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    Error expected_status) {
668ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_NE(expected_status, ERR_IO_PENDING);
6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(HasSpdySession(pool, key));
6707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle());
6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  handle->SetSocket(scoped_ptr<StreamSocket>(new FakeSpdySessionClientSocket(
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      expected_status == OK ? ERR_IO_PENDING : expected_status)));
673effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::WeakPtr<SpdySession> spdy_session =
6747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      pool->CreateAvailableSessionFromSocket(
675effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          key, handle.Pass(), BoundNetLog(), OK, true /* is_secure */);
676effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Failure is reported asynchronously.
677effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(spdy_session != NULL);
678effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(HasSpdySession(pool, key));
6797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return spdy_session;
6807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}  // namespace
683ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
684ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::WeakPtr<SpdySession> CreateFakeSpdySession(SpdySessionPool* pool,
685ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                                 const SpdySessionKey& key) {
686ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return CreateFakeSpdySessionHelper(pool, key, OK);
687ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
688ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
689effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbase::WeakPtr<SpdySession> TryCreateFakeSpdySessionExpectingFailure(
690effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SpdySessionPool* pool,
691effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const SpdySessionKey& key,
692effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    Error expected_error) {
693ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK_LT(expected_error, ERR_IO_PENDING);
694effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return CreateFakeSpdySessionHelper(pool, key, expected_error);
695ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
696ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
6977dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSpdySessionPoolPeer::SpdySessionPoolPeer(SpdySessionPool* pool) : pool_(pool) {
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SpdySessionPoolPeer::RemoveAliases(const SpdySessionKey& key) {
7017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  pool_->RemoveAliases(key);
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SpdySessionPoolPeer::DisableDomainAuthenticationVerification() {
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_->verify_domain_authentication_ = false;
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
708a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SpdySessionPoolPeer::SetEnableSendingInitialData(bool enabled) {
709a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  pool_->enable_sending_initial_data_ = enabled;
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
712b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)SpdyTestUtil::SpdyTestUtil(NextProto protocol)
713b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    : protocol_(protocol),
714558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      spdy_version_(NextProtoToSpdyMajorVersion(protocol)) {
715b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
716b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
717b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SpdyTestUtil::AddUrlToHeaderBlock(base::StringPiece url,
719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       SpdyHeaderBlock* headers) const {
720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (is_spdy2()) {
721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    (*headers)["url"] = url.as_string();
722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string scheme, host, path;
724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ParseUrl(url, &scheme, &host, &path);
725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    (*headers)[GetSchemeKey()] = scheme;
726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    (*headers)[GetHostKey()] = host;
727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    (*headers)[GetPathKey()] = path;
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
731b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlock(
732b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::StringPiece url) const {
7337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return ConstructHeaderBlock("GET", url, NULL);
7347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlockForProxy(
7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::StringPiece url) const {
7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(ConstructGetHeaderBlock(url));
7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (is_spdy2())
7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    (*headers)[GetPathKey()] = url.data();
7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return headers.Pass();
7427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeadHeaderBlock(
7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::StringPiece url,
7467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 content_length) const {
7477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return ConstructHeaderBlock("HEAD", url, &content_length);
748b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
749b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
750b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPostHeaderBlock(
751b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::StringPiece url,
752b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    int64 content_length) const {
7537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return ConstructHeaderBlock("POST", url, &content_length);
7547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
7557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPutHeaderBlock(
7577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::StringPiece url,
7587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 content_length) const {
7597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return ConstructHeaderBlock("PUT", url, &content_length);
760b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
761b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
762b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(
763b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const SpdyHeaderInfo& header_info,
764b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    scoped_ptr<SpdyHeaderBlock> headers) const {
765b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  BufferedSpdyFramer framer(spdy_version_, header_info.compressed);
766b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SpdyFrame* frame = NULL;
767b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  switch (header_info.kind) {
768b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case DATA:
769b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateDataFrame(header_info.id, header_info.data,
770b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.data_length,
771b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.data_flags);
772b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
773b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case SYN_STREAM:
77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      {
77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        frame = framer.CreateSynStream(header_info.id, header_info.assoc_id,
77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                       header_info.priority,
77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                       header_info.control_flags,
778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       headers.get());
77990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
780b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
781b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case SYN_REPLY:
782b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateSynReply(header_info.id, header_info.control_flags,
783a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    headers.get());
784b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
785b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case RST_STREAM:
786b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateRstStream(header_info.id, header_info.status);
787b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
788b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case HEADERS:
789b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateHeaders(header_info.id, header_info.control_flags,
790a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   headers.get());
791b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
792b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    default:
793b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ADD_FAILURE();
794b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
795b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
796b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return frame;
797b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
798b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
799b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(const SpdyHeaderInfo& header_info,
800b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            const char* const extra_headers[],
801b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            int extra_header_count,
802b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            const char* const tail_headers[],
803b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            int tail_header_count) const {
804b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
805b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
806b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (tail_headers && tail_header_count)
807b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    AppendToHeaderBlock(tail_headers, tail_header_count, headers.get());
808b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return ConstructSpdyFrame(header_info, headers.Pass());
809b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
810b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
811a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_ptr<SpdyHeaderBlock> headers,
813a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    bool compressed,
814a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    SpdyStreamId stream_id,
815a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    RequestPriority request_priority,
816a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    SpdyFrameType type,
817a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    SpdyControlFlags flags,
818a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    SpdyStreamId associated_stream_id) const {
819116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_GE(type, DATA);
820116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_LE(type, PRIORITY);
82190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const SpdyHeaderInfo header_info = {
822a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    type,
823a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    stream_id,
824a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    associated_stream_id,
825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ConvertRequestPriorityToSpdyPriority(request_priority, spdy_version_),
826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    0,  // credential slot
827a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    flags,
828a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    compressed,
829a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    RST_STREAM_INVALID,  // status
830a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    NULL,  // data
831a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    0,  // length
832a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    DATA_FLAG_NONE
833a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
834868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ConstructSpdyFrame(header_info, headers.Pass());
835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const extra_headers[],
839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int extra_header_count,
840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool compressed,
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SpdyStreamId stream_id,
842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RequestPriority request_priority,
843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SpdyFrameType type,
844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SpdyControlFlags flags,
845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const* tail_headers,
846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int tail_header_size,
847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SpdyStreamId associated_stream_id) const {
848a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
849a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (tail_headers && tail_header_size)
85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AppendToHeaderBlock(tail_headers, tail_header_size / 2, headers.get());
852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ConstructSpdyControlFrame(
853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      headers.Pass(), compressed, stream_id,
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request_priority, type, flags, associated_stream_id);
85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
85690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::string SpdyTestUtil::ConstructSpdyReplyString(
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const SpdyHeaderBlock& headers) const {
859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string reply_string;
860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (SpdyHeaderBlock::const_iterator it = headers.begin();
861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       it != headers.end(); ++it) {
862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string key = it->first;
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Remove leading colon from "special" headers (for SPDY3 and
864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // above).
865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (spdy_version() >= SPDY3 && key[0] == ':')
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      key = key.substr(1);
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::vector<std::string> values;
868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::SplitString(it->second, '\0', &values);
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (std::vector<std::string>::const_iterator it2 = values.begin();
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)         it2 != values.end(); ++it2) {
871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      reply_string += key + ": " + *it2 + "\n";
87290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
87390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return reply_string;
87590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
87690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(jgraettinger): Eliminate uses of this method in tests (prefer
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// SpdySettingsIR).
87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdySettings(
88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SettingsMap& settings) const {
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdySettingsIR settings_ir;
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (SettingsMap::const_iterator it = settings.begin();
8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != settings.end();
8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    settings_ir.AddSetting(
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it->first,
8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0,
8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (it->second.first & SETTINGS_FLAG_PERSISTED) != 0,
8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it->second.second);
8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
891c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return CreateFramer(false)->SerializeFrame(settings_ir);
89290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
89390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdySettingsAck() const {
895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  char kEmptyWrite[] = "";
896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (spdy_version() > SPDY3) {
898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SpdySettingsIR settings_ir;
899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    settings_ir.set_is_ack(true);
900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return CreateFramer(false)->SerializeFrame(settings_ir);
901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // No settings ACK write occurs. Create an empty placeholder write.
903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return new SpdyFrame(kEmptyWrite, 0, false);
904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id, bool is_ack) const {
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyPingIR ping_ir(ping_id);
908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ping_ir.set_is_ack(is_ack);
909c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return CreateFramer(false)->SerializeFrame(ping_ir);
91090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
91190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
91290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway() const {
91390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ConstructSpdyGoAway(0);
91490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
91590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
91690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(
91790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdyStreamId last_good_stream_id) const {
9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyGoAwayIR go_ir(last_good_stream_id, GOAWAY_OK, "go away");
919c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return CreateFramer(false)->SerializeFrame(go_ir);
92090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
92190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
922f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(SpdyStreamId last_good_stream_id,
923f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             SpdyGoAwayStatus status,
924f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             const std::string& desc) const {
925f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SpdyGoAwayIR go_ir(last_good_stream_id, status, desc);
926f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return CreateFramer(false)->SerializeFrame(go_ir);
927f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
928f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
92990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(
93090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SpdyStreamId stream_id, uint32 delta_window_size) const {
9315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
932c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return CreateFramer(false)->SerializeFrame(update_ir);
93390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
93490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(jgraettinger): Eliminate uses of this method in tests (prefer
9365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// SpdyRstStreamIR).
93790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyRstStream(
93890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdyStreamId stream_id,
93990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdyRstStreamStatus status) const {
94046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SpdyRstStreamIR rst_ir(stream_id, status, "");
941c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return CreateFramer(false)->SerializeRstStream(rst_ir);
94290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
94390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
94490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGet(
94590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* const url,
94690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool compressed,
94790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdyStreamId stream_id,
94890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RequestPriority request_priority) const {
949116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyHeaderBlock> block(ConstructGetHeaderBlock(url));
950116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdySyn(
951116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      stream_id, *block, request_priority, compressed, true);
95290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
95390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
95490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const extra_headers[],
95590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          int extra_header_count,
95690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          bool compressed,
95790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          int stream_id,
95890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          RequestPriority request_priority,
95990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          bool direct) const {
960116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock block;
961116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetMethodKey()] = "GET";
962116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetPathKey()] =
963116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (is_spdy2() && !direct) ? "http://www.google.com/" : "/";
964116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetHostKey()] = "www.google.com";
965116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetSchemeKey()] = "http";
966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MaybeAddVersionHeader(&block);
967116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
968116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdySyn(stream_id, block, request_priority, compressed, true);
96990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
97090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
97190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyConnect(
97290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* const extra_headers[],
97390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int extra_header_count,
9743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int stream_id,
9753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RequestPriority priority) const {
976116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock block;
977116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetMethodKey()] = "CONNECT";
978116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetPathKey()] = "www.google.com:443";
979116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetHostKey()] = "www.google.com";
980116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MaybeAddVersionHeader(&block);
981116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
982116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdySyn(stream_id, block, priority, false, false);
98390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
984868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
986868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int extra_header_count,
987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int stream_id,
988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int associated_stream_id,
989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           const char* url) {
9906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (spdy_version() < SPDY4) {
9916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SpdySynStreamIR syn_stream(stream_id);
9926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.set_associated_to_stream_id(associated_stream_id);
9936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader("hello", "bye");
9946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader(GetStatusKey(), "200 OK");
9956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader(GetVersionKey(), "HTTP/1.1");
9966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AddUrlToHeaderBlock(url, syn_stream.mutable_name_value_block());
9976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AppendToHeaderBlock(extra_headers,
9986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        extra_header_count,
9996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        syn_stream.mutable_name_value_block());
10006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return CreateFramer(false)->SerializeFrame(syn_stream);
10016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  } else {
10026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
10036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AddUrlToHeaderBlock(url, push_promise.mutable_name_value_block());
10046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<SpdyFrame> push_promise_frame(
10056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CreateFramer(false)->SerializeFrame(push_promise));
10066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1007116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdyHeadersIR headers(stream_id);
10086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    headers.SetHeader("hello", "bye");
10096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    headers.SetHeader(GetStatusKey(), "200 OK");
10106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AppendToHeaderBlock(
10116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        extra_headers, extra_header_count, headers.mutable_name_value_block());
10126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<SpdyFrame> headers_frame(
10136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CreateFramer(false)->SerializeFrame(headers));
10146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int joint_data_size = push_promise_frame->size() + headers_frame->size();
10166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<char[]> data(new char[joint_data_size]);
10176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const SpdyFrame* frames[2] = {
10186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        push_promise_frame.get(), headers_frame.get(),
10196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    };
10206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int combined_size =
10216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
10226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    DCHECK_EQ(combined_size, joint_data_size);
10236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return new SpdyFrame(data.release(), joint_data_size, true);
1024c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
1028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int extra_header_count,
1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int stream_id,
1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int associated_stream_id,
1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           const char* url,
1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           const char* status,
1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           const char* location) {
10346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (spdy_version() < SPDY4) {
10356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SpdySynStreamIR syn_stream(stream_id);
10366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.set_associated_to_stream_id(associated_stream_id);
10376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader("hello", "bye");
10386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader(GetStatusKey(), status);
10396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader(GetVersionKey(), "HTTP/1.1");
10406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.SetHeader("location", location);
10416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AddUrlToHeaderBlock(url, syn_stream.mutable_name_value_block());
10426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AppendToHeaderBlock(extra_headers,
10436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        extra_header_count,
10446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        syn_stream.mutable_name_value_block());
10456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return CreateFramer(false)->SerializeFrame(syn_stream);
10466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  } else {
10476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
10486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AddUrlToHeaderBlock(url, push_promise.mutable_name_value_block());
10496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<SpdyFrame> push_promise_frame(
10506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CreateFramer(false)->SerializeFrame(push_promise));
10516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1052116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdyHeadersIR headers(stream_id);
10536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    headers.SetHeader("hello", "bye");
10546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    headers.SetHeader(GetStatusKey(), status);
10556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    headers.SetHeader("location", location);
10566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AppendToHeaderBlock(
10576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        extra_headers, extra_header_count, headers.mutable_name_value_block());
10586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<SpdyFrame> headers_frame(
10596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CreateFramer(false)->SerializeFrame(headers));
10606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int joint_data_size = push_promise_frame->size() + headers_frame->size();
10626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<char[]> data(new char[joint_data_size]);
10636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const SpdyFrame* frames[2] = {
10646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        push_promise_frame.get(), headers_frame.get(),
10656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    };
10666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int combined_size =
10676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
10686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    DCHECK_EQ(combined_size, joint_data_size);
10696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return new SpdyFrame(data.release(), joint_data_size, true);
10706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
10716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
10726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructInitialSpdyPushFrame(
10746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<SpdyHeaderBlock> headers,
10756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int stream_id,
10766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int associated_stream_id) {
10776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (spdy_version() < SPDY4) {
10786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SpdySynStreamIR syn_stream(stream_id);
10796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.set_associated_to_stream_id(associated_stream_id);
10806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SetPriority(LOWEST, &syn_stream);
10816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    syn_stream.set_name_value_block(*headers);
10826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return CreateFramer(false)->SerializeFrame(syn_stream);
10836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  } else {
10846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
10856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    push_promise.set_name_value_block(*headers);
10866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return CreateFramer(false)->SerializeFrame(push_promise);
1087c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyPushHeaders(
1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int stream_id,
1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const extra_headers[],
1093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int extra_header_count) {
1094c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SpdyHeadersIR headers(stream_id);
1095c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  headers.SetHeader(GetStatusKey(), "200 OK");
1096c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MaybeAddVersionHeader(&headers);
1097c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count,
1098c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                      headers.mutable_name_value_block());
1099c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return CreateFramer(false)->SerializeFrame(headers);
1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1102116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSpdyFrame* SpdyTestUtil::ConstructSpdySyn(int stream_id,
1103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                          const SpdyHeaderBlock& block,
1104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                          RequestPriority priority,
1105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                          bool compressed,
1106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                          bool fin) const {
1107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (protocol_ < kProtoSPDY4) {
1108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdySynStreamIR syn_stream(stream_id);
1109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syn_stream.set_name_value_block(block);
1110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syn_stream.set_priority(
1111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ConvertRequestPriorityToSpdyPriority(priority, spdy_version()));
1112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syn_stream.set_fin(fin);
1113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return CreateFramer(compressed)->SerializeFrame(syn_stream);
1114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
1115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdyHeadersIR headers(stream_id);
1116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    headers.set_name_value_block(block);
1117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    headers.set_has_priority(true);
1118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    headers.set_priority(
1119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ConvertRequestPriorityToSpdyPriority(priority, spdy_version()));
1120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    headers.set_fin(fin);
1121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return CreateFramer(compressed)->SerializeFrame(headers);
1122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1125116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSpdyFrame* SpdyTestUtil::ConstructSpdyReply(int stream_id,
1126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            const SpdyHeaderBlock& headers) {
1127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (protocol_ < kProtoSPDY4) {
1128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdySynReplyIR syn_reply(stream_id);
1129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syn_reply.set_name_value_block(headers);
1130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return CreateFramer(false)->SerializeFrame(syn_reply);
1131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
1132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdyHeadersIR reply(stream_id);
1133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    reply.set_name_value_block(headers);
1134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return CreateFramer(false)->SerializeFrame(reply);
1135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError(
1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const status,
1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const* const extra_headers,
1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int extra_header_count,
1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int stream_id) {
1143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock block;
1144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block["hello"] = "bye";
1145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetStatusKey()] = status;
1146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MaybeAddVersionHeader(&block);
1147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdyReply(stream_id, block);
1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReplyRedirect(int stream_id) {
1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    "location", "http://www.foo.com/index.php",
1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders,
1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    arraysize(kExtraHeaders)/2, stream_id);
1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError(int stream_id) {
1161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1);
1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReply(
1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const extra_headers[],
1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int extra_header_count,
1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int stream_id) {
1168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock block;
1169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block["hello"] = "bye";
1170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetStatusKey()] = "200";
1171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MaybeAddVersionHeader(&block);
1172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdyReply(stream_id, block);
1175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url,
1178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           SpdyStreamId stream_id,
1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int64 content_length,
1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           RequestPriority priority,
1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           const char* const extra_headers[],
1182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           int extra_header_count) {
1183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyHeaderBlock> block(
1184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ConstructPostHeaderBlock(url, content_length));
1185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count, block.get());
1186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdySyn(stream_id, *block, priority, false, false);
1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructChunkedSpdyPost(
1190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const extra_headers[],
1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int extra_header_count) {
1192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock block;
1193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetMethodKey()] = "POST";
1194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetPathKey()] = "/";
1195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetHostKey()] = "www.google.com";
1196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  block[GetSchemeKey()] = "http";
1197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MaybeAddVersionHeader(&block);
1198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdySyn(1, block, LOWEST, false, false);
1200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyPostSynReply(
1203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const char* const extra_headers[],
1204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int extra_header_count) {
1205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(jgraettinger): Remove this method.
1206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ConstructSpdyGetSynReply(NULL, 0, 1);
1207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, bool fin) {
1210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
12115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyDataIR data_ir(stream_id,
12125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::StringPiece(kUploadData, kUploadDataSize));
12135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data_ir.set_fin(fin);
12145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return framer.SerializeData(data_ir);
1215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
1218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                const char* data,
1219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                uint32 len,
1220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                bool fin) {
1221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyDataIR data_ir(stream_id, base::StringPiece(data, len));
12235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data_ir.set_fin(fin);
12245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return framer.SerializeData(data_ir);
1225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructWrappedSpdyFrame(
1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const scoped_ptr<SpdyFrame>& frame,
1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int stream_id) {
1230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ConstructSpdyBodyFrame(stream_id, frame->data(),
1231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                frame->size(), false);
1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const SpdyHeaderInfo SpdyTestUtil::MakeSpdyHeader(SpdyFrameType type) {
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const SpdyHeaderInfo kHeader = {
1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    type,
1237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    1,                            // Stream ID
1238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0,                            // Associated stream ID
1239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ConvertRequestPriorityToSpdyPriority(LOWEST, spdy_version_),
1240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    kSpdyCredentialSlotUnused,
1241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CONTROL_FLAG_FIN,             // Control Flags
1242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    false,                        // Compressed
1243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RST_STREAM_INVALID,
1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    NULL,                         // Data
1245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0,                            // Length
1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DATA_FLAG_NONE
1247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
1248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return kHeader;
1249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<SpdyFramer> SpdyTestUtil::CreateFramer(bool compressed) const {
1252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<SpdyFramer> framer(new SpdyFramer(spdy_version_));
1253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  framer->set_enable_compression(compressed);
1254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return framer.Pass();
1255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* SpdyTestUtil::GetMethodKey() const {
1258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return is_spdy2() ? "method" : ":method";
1259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* SpdyTestUtil::GetStatusKey() const {
1262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return is_spdy2() ? "status" : ":status";
1263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* SpdyTestUtil::GetHostKey() const {
1266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (protocol_ < kProtoSPDY3)
1267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return "host";
1268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (protocol_ < kProtoSPDY4)
1269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return ":host";
1270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  else
1271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return ":authority";
1272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* SpdyTestUtil::GetSchemeKey() const {
1275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return is_spdy2() ? "scheme" : ":scheme";
1276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* SpdyTestUtil::GetVersionKey() const {
1279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return is_spdy2() ? "version" : ":version";
1280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* SpdyTestUtil::GetPathKey() const {
1283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return is_spdy2() ? "url" : ":path";
1284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock(
12877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::StringPiece method,
12887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::StringPiece url,
12897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64* content_length) const {
12907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string scheme, host, path;
12917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ParseUrl(url.data(), &scheme, &host, &path);
12927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
12937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  (*headers)[GetMethodKey()] = method.as_string();
12947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  (*headers)[GetPathKey()] = path.c_str();
12957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  (*headers)[GetHostKey()] = host.c_str();
12967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  (*headers)[GetSchemeKey()] = scheme.c_str();
1297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (include_version_header()) {
1298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    (*headers)[GetVersionKey()] = "HTTP/1.1";
1299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
13007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (content_length) {
13017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string length_str = base::Int64ToString(*content_length);
13027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    (*headers)["content-length"] = length_str;
13037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
13047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return headers.Pass();
13057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
13067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SpdyTestUtil::MaybeAddVersionHeader(
1308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    SpdyFrameWithNameValueBlockIR* frame_ir) const {
1309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (include_version_header()) {
1310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    frame_ir->SetHeader(GetVersionKey(), "HTTP/1.1");
1311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1314116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SpdyTestUtil::MaybeAddVersionHeader(SpdyHeaderBlock* block) const {
1315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (include_version_header()) {
1316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    (*block)[GetVersionKey()] = "HTTP/1.1";
1317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SpdyTestUtil::SetPriority(RequestPriority priority,
1321c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                               SpdySynStreamIR* ir) const {
1322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ir->set_priority(ConvertRequestPriorityToSpdyPriority(
1323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      priority, spdy_version()));
1324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1325c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
1327