spdy_test_util_common.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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"
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/string_number_conversions.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/mock_cert_verifier.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_cache.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_network_session.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_network_transaction.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_server_properties_impl.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/socket_test_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/buffered_spdy_framer.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_session.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_stream.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool next_proto_is_spdy(NextProto next_proto) {
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return next_proto >= kProtoSPDYMinimumVersion &&
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         next_proto <= kProtoSPDYMaximumVersion;
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Parses a URL into the scheme, host, and path components required for a
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// SPDY request.
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ParseUrl(const char* const url, std::string* scheme, std::string* host,
33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              std::string* path) {
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL gurl(url);
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  path->assign(gurl.PathForRequest());
36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheme->assign(gurl.scheme());
37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  host->assign(gurl.host());
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (gurl.has_port()) {
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    host->append(":");
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    host->append(gurl.port());
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a frame into an array of MockWrites.
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |data| is the frame to chop.
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |length| is the length of the frame to chop.
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) {
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite* chunks = new MockWrite[num_chunks];
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int chunk_size = length / num_chunks;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int index = 0; index < num_chunks; index++) {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* ptr = data + (index * chunk_size);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (index == num_chunks - 1)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chunks;
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a SpdyFrame into an array of MockWrites.
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |frame| is the frame to chop.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks) {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ChopWriteFrame(frame.data(), frame.size(), num_chunks);
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a frame into an array of MockReads.
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |data| is the frame to chop.
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |length| is the length of the frame to chop.
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead* ChopReadFrame(const char* data, int length, int num_chunks) {
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead* chunks = new MockRead[num_chunks];
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int chunk_size = length / num_chunks;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int index = 0; index < num_chunks; index++) {
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* ptr = data + (index * chunk_size);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (index == num_chunks - 1)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chunk_size += length % chunk_size;  // The last chunk takes the remainder.
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    chunks[index] = MockRead(ASYNC, ptr, chunk_size);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chunks;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Chop a SpdyFrame into an array of MockReads.
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |frame| is the frame to chop.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |num_chunks| is the number of chunks to create.
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks) {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ChopReadFrame(frame.data(), frame.size(), num_chunks);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Adds headers and values to a map.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |extra_headers| is an array of { name, value } pairs, arranged as strings
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// where the even entries are the header names, and the odd entries are the
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// header values.
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |headers| gets filled in from |extra_headers|.
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppendToHeaderBlock(const char* const extra_headers[],
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int extra_header_count,
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         SpdyHeaderBlock* headers) {
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string this_header;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string this_value;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!extra_header_count)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sanity check: Non-NULL header list.
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != extra_headers) << "NULL header value pair list";
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sanity check: Non-NULL header map.
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != headers) << "NULL header map";
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Copy in the headers.
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < extra_header_count; i++) {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Sanity check: Non-empty header.
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    this_header = extra_headers[i * 2];
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string::size_type header_len = this_header.length();
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!header_len)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    this_value = extra_headers[1 + (i * 2)];
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string new_value;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (headers->find(this_header) != headers->end()) {
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // More than one entry in the header.
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Don't add the header again, just the append to the value,
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // separated by a NULL character.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Adjust the value.
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value = (*headers)[this_header];
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Put in a NULL separator.
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value.append(1, '\0');
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Append the new value.
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value += this_value;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Not a duplicate, just write the value.
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_value = this_value;
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    (*headers)[this_header] = new_value;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Writes |val| to a location of size |len|, in big-endian format.
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// in the buffer pointed to by |buffer_handle|.
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Updates the |*buffer_handle| pointer by |len|
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns the number of bytes written
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int AppendToBuffer(int val,
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   int len,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   unsigned char** buffer_handle,
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   int* buffer_len_remaining) {
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (len <= 0)
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return 0;
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK((size_t) len <= sizeof(len)) << "Data length too long for data type";
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != buffer_handle) << "NULL buffer handle";
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != *buffer_handle) << "NULL pointer";
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(NULL != buffer_len_remaining)
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      << "NULL buffer remainder length pointer";
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < len; i++) {
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int shift = (8 * (len - (i + 1)));
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned char val_chunk = (val >> shift) & 0x0FF;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *(*buffer_handle)++ = val_chunk;
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *buffer_len_remaining += 1;
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return len;
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockWrite from the given SpdyFrame.
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite CreateMockWrite(const SpdyFrame& req) {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockWrite(ASYNC, req.data(), req.size());
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockWrite from the given SpdyFrame and sequence number.
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite CreateMockWrite(const SpdyFrame& req, int seq) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CreateMockWrite(req, seq, ASYNC);
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockWrite from the given SpdyFrame and sequence number.
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode) {
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockWrite(mode, req.data(), req.size(), seq);
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockRead from the given SpdyFrame.
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead CreateMockRead(const SpdyFrame& resp) {
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockRead(ASYNC, resp.data(), resp.size());
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockRead from the given SpdyFrame and sequence number.
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead CreateMockRead(const SpdyFrame& resp, int seq) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CreateMockRead(resp, seq, ASYNC);
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create a MockRead from the given SpdyFrame and sequence number.
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode) {
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MockRead(mode, resp.data(), resp.size(), seq);
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Combines the given SpdyFrames into the given char array and returns
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the total length.
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int CombineFrames(const SpdyFrame** frames, int num_frames,
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  char* buff, int buff_len) {
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int total_len = 0;
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < num_frames; ++i) {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    total_len += frames[i]->size();
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_LE(total_len, buff_len);
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  char* ptr = buff;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < num_frames; ++i) {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int len = frames[i]->size();
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    memcpy(ptr, frames[i]->data(), len);
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ptr += len;
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return total_len;
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityGetter() : priority_(0) {}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~PriorityGetter() {}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyPriority priority() const {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return priority_;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE {}
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStreamError(SpdyStreamId stream_id,
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& description) OVERRIDE {}
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSynStream(SpdyStreamId stream_id,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyStreamId associated_stream_id,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyPriority priority,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           uint8 credential_slot,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool fin,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool unidirectional,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SpdyHeaderBlock& headers) OVERRIDE {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority_ = priority;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSynReply(SpdyStreamId stream_id,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          bool fin,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const SpdyHeaderBlock& headers) OVERRIDE {}
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHeaders(SpdyStreamId stream_id,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool fin,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const SpdyHeaderBlock& headers) OVERRIDE {}
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStreamFrameData(SpdyStreamId stream_id,
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const char* data,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 size_t len,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) OVERRIDE {}
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSettings(bool clear_persisted) OVERRIDE {}
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSetting(
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE {}
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPing(uint32 unique_id) OVERRIDE {}
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnRstStream(SpdyStreamId stream_id,
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyRstStreamStatus status) OVERRIDE {}
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        SpdyGoAwayStatus status) OVERRIDE {}
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowUpdate(SpdyStreamId stream_id,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32 delta_window_size) OVERRIDE {}
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSynStreamCompressed(
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t uncompressed_size,
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t compressed_size) OVERRIDE {}
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyPriority priority_;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetSpdyPriority(int version,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const SpdyFrame& frame,
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     SpdyPriority* priority) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferedSpdyFramer framer(version, false);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityGetter priority_getter;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_visitor(&priority_getter);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t frame_size = frame.size();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (framer.ProcessInput(frame.data(), frame_size) != frame_size) {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *priority = priority_getter.priority();
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<SpdyStream> CreateStreamSynchronously(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<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;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = stream_request.StartRequest(session, url, priority, net_log,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       CompletionCallback());
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (rv == OK) ? stream_request.ReleaseStream() : NULL;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StreamReleaserCallback::StreamReleaserCallback(
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdySession* session,
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyStream* first_stream)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : session_(session),
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_stream_(first_stream) {}
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StreamReleaserCallback::~StreamReleaserCallback() {}
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CompletionCallback StreamReleaserCallback::MakeCallback(
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyStreamRequest* request) {
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::Bind(&StreamReleaserCallback::OnComplete,
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    base::Unretained(this),
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    request);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StreamReleaserCallback::OnComplete(
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyStreamRequest* request, int result) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session_ = NULL;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_stream_->Cancel();
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_stream_ = NULL;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request->ReleaseStream()->Cancel();
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResult(result);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockECSignatureCreator::MockECSignatureCreator(crypto::ECPrivateKey* key)
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : key_(key) {
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MockECSignatureCreator::Sign(const uint8* data,
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int data_len,
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  std::vector<uint8>* signature) {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<uint8> private_key_value;
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  key_->ExportValue(&private_key_value);
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string head = "fakesignature";
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string tail = "/fakesignature";
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->clear();
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), head.begin(), head.end());
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), private_key_value.begin(),
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    private_key_value.end());
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), '-');
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), data, data + data_len);
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signature->insert(signature->end(), tail.begin(), tail.end());
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MockECSignatureCreator::DecodeSignature(
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::vector<uint8>& signature,
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<uint8>* out_raw_sig) {
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *out_raw_sig = signature;
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockECSignatureCreatorFactory::MockECSignatureCreatorFactory() {
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  crypto::ECSignatureCreator::SetFactoryForTesting(this);
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MockECSignatureCreatorFactory::~MockECSignatureCreatorFactory() {
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)crypto::ECSignatureCreator* MockECSignatureCreatorFactory::Create(
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    crypto::ECPrivateKey* key) {
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new MockECSignatureCreator(key);
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionDependencies::SpdySessionDependencies(NextProto protocol)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : host_resolver(new MockCachingHostResolver),
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cert_verifier(new MockCertVerifier),
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      proxy_service(ProxyService::CreateDirect()),
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ssl_config_service(new SSLConfigServiceDefaults),
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      socket_factory(new MockClientSocketFactory),
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      deterministic_socket_factory(new DeterministicMockClientSocketFactory),
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      http_auth_handler_factory(
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_ip_pooling(true),
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_compression(false),
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_ping(false),
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      enable_user_alternate_protocol_ports(false),
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      protocol(protocol),
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_initial_recv_window_size(kSpdyStreamInitialWindowSize),
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      time_func(&base::TimeTicks::Now),
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net_log(NULL) {
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: The CancelledTransaction test does cleanup by running all
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // tasks in the message loop (RunAllPending).  Unfortunately, that
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // doesn't clean up tasks on the host resolver thread; and
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TCPConnectJob is currently not cancellable.  Using synchronous
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // lookups allows the test to shutdown cleanly.  Until we have
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // cancellable TCPConnectJobs, use synchronous lookups.
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_resolver->set_synchronous_mode(true);
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionDependencies::SpdySessionDependencies(
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NextProto protocol, ProxyService* proxy_service)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : host_resolver(new MockHostResolver),
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cert_verifier(new MockCertVerifier),
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),
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net_log(NULL) {
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionDependencies::~SpdySessionDependencies() {}
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps) {
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.client_socket_factory = session_deps->socket_factory.get();
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpNetworkSession* http_session = new HttpNetworkSession(params);
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_peer.EnableSendingInitialSettings(false);
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return http_session;
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps) {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params = CreateSessionParams(session_deps);
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.client_socket_factory =
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->deterministic_socket_factory.get();
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpNetworkSession* http_session = new HttpNetworkSession(params);
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_peer.EnableSendingInitialSettings(false);
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return http_session;
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)net::HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps) {
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(session_deps->protocol)) <<
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "Invalid protocol: " << session_deps->protocol;
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params;
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.host_resolver = session_deps->host_resolver.get();
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.cert_verifier = session_deps->cert_verifier.get();
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.proxy_service = session_deps->proxy_service.get();
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.ssl_config_service = session_deps->ssl_config_service;
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_auth_handler_factory =
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->http_auth_handler_factory.get();
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_server_properties = &session_deps->http_server_properties;
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_compression = session_deps->enable_compression;
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping;
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_user_alternate_protocol_ports =
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->enable_user_alternate_protocol_ports;
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.spdy_default_protocol = session_deps->protocol;
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.spdy_stream_initial_recv_window_size =
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps->stream_initial_recv_window_size;
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.time_func = session_deps->time_func;
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.trusted_spdy_proxy = session_deps->trusted_spdy_proxy;
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.net_log = session_deps->net_log;
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return params;
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : storage_(this) {
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_cert_verifier(new MockCertVerifier);
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_proxy_service(ProxyService::CreateDirect());
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_resolver()));
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_http_server_properties(new HttpServerPropertiesImpl);
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::HttpNetworkSession::Params params;
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.client_socket_factory = &socket_factory_;
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.host_resolver = host_resolver();
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.cert_verifier = cert_verifier();
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.proxy_service = proxy_service();
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.ssl_config_service = ssl_config_service();
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_auth_handler_factory = http_auth_handler_factory();
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.network_delegate = network_delegate();
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_compression = false;
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.enable_spdy_ping_based_connection_checking = false;
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.spdy_default_protocol = protocol;
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.http_server_properties = http_server_properties();
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> network_session(
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new HttpNetworkSession(params));
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionPoolPeer pool_peer(network_session->spdy_session_pool());
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_peer.EnableSendingInitialSettings(false);
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  storage_.set_http_transaction_factory(new HttpCache(
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_session,
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      HttpCache::DefaultBackend::InMemory(0)));
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdyURLRequestContext::~SpdyURLRequestContext() {
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SpdySessionPoolPeer::SpdySessionPoolPeer(SpdySessionPool* pool) : pool_(pool) {
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SpdySessionPoolPeer::AddAlias(
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IPEndPoint& address,
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const HostPortProxyPair& pair) {
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_->AddAlias(address, pair);
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SpdySessionPoolPeer::RemoveAliases(const HostPortProxyPair& pair) {
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_->RemoveAliases(pair);
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SpdySessionPoolPeer::RemoveSpdySession(
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const scoped_refptr<SpdySession>& session) {
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_->Remove(session);
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SpdySessionPoolPeer::DisableDomainAuthenticationVerification() {
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_->verify_domain_authentication_ = false;
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SpdySessionPoolPeer::EnableSendingInitialSettings(bool enabled) {
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pool_->enable_sending_initial_settings_ = enabled;
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)NextProto NextProtoFromSpdyVersion(int spdy_version) {
520b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  switch (spdy_version) {
521b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kSpdyVersion2:
522b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kProtoSPDY2;
523b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kSpdyVersion3:
524b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kProtoSPDY3;
525b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kSpdyVersion4:
526b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kProtoSPDY4a1;
527b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  default:
528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    NOTREACHED();
529b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kProtoUnknown;
530b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
531b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
532b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
533b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)int SpdyVersionFromNextProto(NextProto next_proto) {
534b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  switch (next_proto) {
535b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kProtoSPDY2:
536b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kProtoSPDY21:
537b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kSpdyVersion2;
538b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kProtoSPDY3:
539b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kProtoSPDY31:
540b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kSpdyVersion3;
541b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  case kProtoSPDY4a1:
542b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return kSpdyVersion4;
543b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  default:
544b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    NOTREACHED();
545b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return 0;
546b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
547b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
548b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
549b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)SpdyTestUtil::SpdyTestUtil(NextProto protocol)
550b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    : protocol_(protocol),
551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      spdy_version_(SpdyVersionFromNextProto(protocol)) {
552b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
553b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
554b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
555b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlock(
556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::StringPiece url) const {
557b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string scheme, host, path;
558b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ParseUrl(url.data(), &scheme, &host, &path);
559b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const bool spdy2 = protocol_ < kProtoSPDY3;
560b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const char* const headers[] = {
561b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "method"  : ":method",  "GET",
562b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "url"     : ":path",    path.c_str(),
563b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "host"    : ":host",    host.c_str(),
564b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "scheme"  : ":scheme",  scheme.c_str(),
565b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "version" : ":version", "HTTP/1.1"
566b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  };
567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> header_block(new SpdyHeaderBlock());
568b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  AppendToHeaderBlock(headers, arraysize(headers) / 2, header_block.get());
569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return header_block.Pass();
570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
572b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPostHeaderBlock(
573b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::StringPiece url,
574b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    int64 content_length) const {
575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string scheme, host, path;
576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ParseUrl(url.data(), &scheme, &host, &path);
577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string length_str = base::Int64ToString(content_length);
578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const bool spdy2 = protocol_ < kProtoSPDY3;
579b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const char* const headers[] = {
580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "method"  : ":method",  "POST",
581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "url"     : ":path",    path.c_str(),
582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "host"    : ":host",    host.c_str(),
583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "scheme"  : ":scheme",  scheme.c_str(),
584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    spdy2 ? "version" : ":version", "HTTP/1.1",
585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    "content-length",               length_str.c_str()
586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  };
587b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> header_block(new SpdyHeaderBlock());
588b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  AppendToHeaderBlock(headers, arraysize(headers) / 2, header_block.get());
589b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return header_block.Pass();
590b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
591b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
592b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(
593b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const SpdyHeaderInfo& header_info,
594b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    scoped_ptr<SpdyHeaderBlock> headers) const {
595b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  BufferedSpdyFramer framer(spdy_version_, header_info.compressed);
596b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const bool spdy2 = protocol_ < kProtoSPDY3;
597b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SpdyFrame* frame = NULL;
598b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  switch (header_info.kind) {
599b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case DATA:
600b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateDataFrame(header_info.id, header_info.data,
601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.data_length,
602b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.data_flags);
603b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
604b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case SYN_STREAM:
605b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateSynStream(header_info.id, header_info.assoc_id,
606b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.priority,
607b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     spdy2 ? 0 : header_info.credential_slot,
608b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.control_flags,
609b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     header_info.compressed, headers.get());
610b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
611b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case SYN_REPLY:
612b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateSynReply(header_info.id, header_info.control_flags,
613b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                    header_info.compressed, headers.get());
614b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
615b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case RST_STREAM:
616b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateRstStream(header_info.id, header_info.status);
617b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
618b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case HEADERS:
619b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      frame = framer.CreateHeaders(header_info.id, header_info.control_flags,
620b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                   header_info.compressed, headers.get());
621b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
622b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    default:
623b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ADD_FAILURE();
624b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
625b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
626b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return frame;
627b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
628b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
629b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(const SpdyHeaderInfo& header_info,
630b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            const char* const extra_headers[],
631b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            int extra_header_count,
632b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            const char* const tail_headers[],
633b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                            int tail_header_count) const {
634b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
635b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
636b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (tail_headers && tail_header_count)
637b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    AppendToHeaderBlock(tail_headers, tail_header_count, headers.get());
638b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return ConstructSpdyFrame(header_info, headers.Pass());
639b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
640b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
642