1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/http/http_network_session.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_network_transaction.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/spdy/spdy_framer.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/spdy/spdy_http_utils.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Chop a frame into an array of MockWrites. 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |data| is the frame to chop. 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |length| is the length of the frame to chop. 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |num_chunks| is the number of chunks to create. 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite* chunks = new MockWrite[num_chunks]; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int chunk_size = length / num_chunks; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int index = 0; index < num_chunks; index++) { 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* ptr = data + (index * chunk_size); 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index == num_chunks - 1) 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chunk_size += length % chunk_size; // The last chunk takes the remainder. 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chunks[index] = MockWrite(true, ptr, chunk_size); 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return chunks; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Chop a SpdyFrame into an array of MockWrites. 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |frame| is the frame to chop. 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |num_chunks| is the number of chunks to create. 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockWrite* ChopWriteFrame(const spdy::SpdyFrame& frame, int num_chunks) { 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ChopWriteFrame(frame.data(), 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame.length() + spdy::SpdyFrame::size(), 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch num_chunks); 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Chop a frame into an array of MockReads. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |data| is the frame to chop. 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |length| is the length of the frame to chop. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |num_chunks| is the number of chunks to create. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockRead* ChopReadFrame(const char* data, int length, int num_chunks) { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead* chunks = new MockRead[num_chunks]; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int chunk_size = length / num_chunks; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int index = 0; index < num_chunks; index++) { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* ptr = data + (index * chunk_size); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index == num_chunks - 1) 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chunk_size += length % chunk_size; // The last chunk takes the remainder. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chunks[index] = MockRead(true, ptr, chunk_size); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return chunks; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Chop a SpdyFrame into an array of MockReads. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |frame| is the frame to chop. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |num_chunks| is the number of chunks to create. 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockRead* ChopReadFrame(const spdy::SpdyFrame& frame, int num_chunks) { 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ChopReadFrame(frame.data(), 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame.length() + spdy::SpdyFrame::size(), 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch num_chunks); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Adds headers and values to a map. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| is an array of { name, value } pairs, arranged as strings 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// where the even entries are the header names, and the odd entries are the 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// header values. 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |headers| gets filled in from |extra_headers|. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AppendHeadersToSpdyFrame(const char* const extra_headers[], 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyHeaderBlock* headers) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string this_header; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string this_value; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!extra_header_count) 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Non-NULL header list. 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL != extra_headers) << "NULL header value pair list"; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Non-NULL header map. 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL != headers) << "NULL header map"; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy in the headers. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < extra_header_count; i++) { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Non-empty header. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair"; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_header = extra_headers[i * 2]; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string::size_type header_len = this_header.length(); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!header_len) 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_value = extra_headers[1 + (i * 2)]; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string new_value; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (headers->find(this_header) != headers->end()) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // More than one entry in the header. 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't add the header again, just the append to the value, 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // separated by a NULL character. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Adjust the value. 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_value = (*headers)[this_header]; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Put in a NULL separator. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_value.append(1, '\0'); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Append the new value. 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_value += this_value; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Not a duplicate, just write the value. 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_value = this_value; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*headers)[this_header] = new_value; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Writes |val| to a location of size |len|, in big-endian format. 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the buffer pointed to by |buffer_handle|. 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Updates the |*buffer_handle| pointer by |len| 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the number of bytes written 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint AppendToBuffer(int val, 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int len, 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned char** buffer_handle, 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* buffer_len_remaining) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (len <= 0) 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK((size_t) len <= sizeof(len)) << "Data length too long for data type"; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL != buffer_handle) << "NULL buffer handle"; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL != *buffer_handle) << "NULL pointer"; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL != buffer_len_remaining) 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "NULL buffer remainder length pointer"; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size"; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < len; i++) { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int shift = (8 * (len - (i + 1))); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned char val_chunk = (val >> shift) & 0x0FF; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *(*buffer_handle)++ = val_chunk; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *buffer_len_remaining += 1; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return len; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct a SPDY packet. 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |head| is the start of the packet, up to but not including 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the header value pairs. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs, which typically 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will vary the most between calls. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |tail| is any (relatively constant) header-value pairs to add. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |buffer| is the buffer we're filling in. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a SpdyFrame. 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info, 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* const extra_headers[], 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count, 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* const tail[], 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int tail_header_count) { 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyHeaderBlock headers; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy in the extra headers to our map. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy in the tail headers to our map. 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tail && tail_header_count) 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AppendHeadersToSpdyFrame(tail, tail_header_count, &headers); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFrame* frame = NULL; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (header_info.kind) { 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case spdy::SYN_STREAM: 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame = framer.CreateSynStream(header_info.id, header_info.assoc_id, 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_info.priority, 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_info.control_flags, 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_info.compressed, &headers); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case spdy::SYN_REPLY: 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame = framer.CreateSynReply(header_info.id, header_info.control_flags, 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_info.compressed, &headers); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case spdy::RST_STREAM: 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame = framer.CreateRstStream(header_info.id, header_info.status); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch case spdy::HEADERS: 177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch frame = framer.CreateHeaders(header_info.id, header_info.control_flags, 178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch header_info.compressed, &headers); 179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch break; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame = framer.CreateDataFrame(header_info.id, header_info.data, 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_info.data_length, 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_info.data_flags); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return frame; 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct an expected SPDY SETTINGS frame. 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |settings| are the settings to set. 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the constructed frame. The caller takes ownership of the frame. 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdySettings(spdy::SpdySettings settings) { 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return framer.CreateSettings(settings); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1972c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun// Construct a SPDY PING frame. 1982c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun// Returns the constructed frame. The caller takes ownership of the frame. 1992c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurunspdy::SpdyFrame* ConstructSpdyPing() { 2002c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun spdy::SpdyFramer framer; 2012c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return framer.CreatePingFrame(1); 2022c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun} 2032c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct a SPDY GOAWAY frame. 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the constructed frame. The caller takes ownership of the frame. 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyGoAway() { 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return framer.CreateGoAway(0); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct a SPDY WINDOW_UPDATE frame. 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the constructed frame. The caller takes ownership of the frame. 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyWindowUpdate( 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyStreamId stream_id, uint32 delta_window_size) { 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return framer.CreateWindowUpdate(stream_id, delta_window_size); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct a SPDY RST_STREAM frame. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the constructed frame. The caller takes ownership of the frame. 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyRstStream(spdy::SpdyStreamId stream_id, 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyStatusCodes status) { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return framer.CreateRstStream(stream_id, status); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct a single SPDY header entry, for validation. 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs. 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |buffer| is the buffer we're filling in. 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |index| is the index of the header we want. 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the number of bytes written into |buffer|. 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstructSpdyHeader(const char* const extra_headers[], 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count, 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer, 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int buffer_length, 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* this_header = NULL; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* this_value = NULL; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!buffer || !buffer_length) 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *buffer = '\0'; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Non-empty header list. 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL != extra_headers) << "NULL extra headers pointer"; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Index out of range. 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK((index >= 0) && (index < extra_header_count)) 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "Index " << index 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " out of range [0, " << extra_header_count << ")"; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_header = extra_headers[index * 2]; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Non-empty header. 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*this_header) 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string::size_type header_len = strlen(this_header); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!header_len) 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_value = extra_headers[1 + (index * 2)]; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sanity check: Non-empty value. 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*this_value) 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_value = ""; 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int n = base::snprintf(buffer, 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_length, 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "%s: %s\r\n", 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_header, 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this_value); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return n; 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[], 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool compressed, 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RequestPriority request_priority, 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdyControlType type, 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdyControlFlags flags, 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const* kHeaders, 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int kHeadersSize) { 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick compressed, 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_priority, 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick type, 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick flags, 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kHeaders, 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kHeadersSize, 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0); 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[], 2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool compressed, 2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RequestPriority request_priority, 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdyControlType type, 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdyControlFlags flags, 2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const* kHeaders, 2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int kHeadersSize, 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int associated_stream_id) { 2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = { 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick type, // Kind = Syn 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, // Stream ID 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick associated_stream_id, // Associated stream ID 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ConvertRequestPriorityToSpdyPriority(request_priority), 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick flags, // Control Flags 3053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick compressed, // Compressed 3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyPacket(kSynStartHeader, 3123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_headers, 3133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kHeaders, 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kHeadersSize / 2); 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructs a standard SPDY GET SYN packet, optionally compressed 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// for the url |url|. 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs, which typically 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will vary the most between calls. 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a SpdyFrame. 3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyGet(const char* const url, 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool compressed, 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int stream_id, 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestPriority request_priority) { 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SpdyHeaderInfo kSynStartHeader = { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_STREAM, // Kind = Syn 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch stream_id, // Stream ID 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated stream ID 3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(request_priority), 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_FIN, // Control Flags 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch compressed, // Compressed 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Length 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL gurl(url); 3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is so ugly. Why are we using char* in here again? 3443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string str_path = gurl.PathForRequest(); 3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string str_scheme = gurl.scheme(); 346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string str_host = gurl.host(); 347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (gurl.has_port()) { 348201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch str_host += ":"; 349201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch str_host += gurl.port(); 350201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_array<char> req(new char[str_path.size() + 1]); 3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_array<char> scheme(new char[str_scheme.size() + 1]); 3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_array<char> host(new char[str_host.size() + 1]); 3543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memcpy(req.get(), str_path.c_str(), str_path.size()); 3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memcpy(scheme.get(), str_scheme.c_str(), str_scheme.size()); 3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memcpy(host.get(), str_host.c_str(), str_host.size()); 3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req.get()[str_path.size()] = '\0'; 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scheme.get()[str_scheme.size()] = '\0'; 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host.get()[str_host.size()] = '\0'; 3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const headers[] = { 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "method", 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET", 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", 3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req.get(), 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host.get(), 3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scheme.get(), 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1" 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ConstructSpdyPacket( 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSynStartHeader, 3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, 3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick headers, 3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(headers) / 2); 3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructs a standard SPDY GET SYN packet, optionally compressed. 3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// |extra_headers| are the extra header-value pairs, which typically 3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// will vary the most between calls. 3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Returns a SpdyFrame. 3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[], 3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool compressed, 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RequestPriority request_priority) { 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyGet(extra_headers, extra_header_count, compressed, 3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, request_priority, true); 3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructs a standard SPDY GET SYN packet, optionally compressed. 3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// |extra_headers| are the extra header-value pairs, which typically 3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// will vary the most between calls. 3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Returns a SpdyFrame. 3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[], 3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool compressed, 4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RequestPriority request_priority, 4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool direct) { 4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (direct ? "/" : "http://www.google.com/"), 4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.google.com", 4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick compressed, 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_priority, 4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_FIN, 4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders)); 4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 427731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request. 428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[], 429731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int extra_header_count, 430731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int stream_id) { 431731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const char* const kConnectHeaders[] = { 432731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "method", "CONNECT", 433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "url", "www.google.com:443", 434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "host", "www.google.com", 435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "version", "HTTP/1.1", 436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 437731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ConstructSpdyControlFrame(extra_headers, 438731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick extra_header_count, 439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick /*compressed*/ false, 440731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick stream_id, 441731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOWEST, 442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy::SYN_STREAM, 443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy::CONTROL_FLAG_NONE, 444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick kConnectHeaders, 445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick arraysize(kConnectHeaders)); 446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructs a standard SPDY push SYN packet. 4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// |extra_headers| are the extra header-value pairs, which typically 4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// will vary the most between calls. 4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Returns a SpdyFrame. 4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[], 4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int associated_stream_id) { 4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello", 4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "bye", 4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", 4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "200", 4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, 4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders), 4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick associated_stream_id); 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[], 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int associated_stream_id, 480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url) { 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello", 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "bye", 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "200 OK", 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch url, 4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 4903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 4943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 4963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, 4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders), 5003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick associated_stream_id); 5013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[], 5043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int extra_header_count, 5053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int stream_id, 5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int associated_stream_id, 507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url, 5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* status, 509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* location) { 5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello", 5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "bye", 5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", 5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick status, 5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "location", 5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick location, 5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url, 5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 5203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, 5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders), 5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick associated_stream_id); 5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochspdy::SpdyFrame* ConstructSpdyPush(int stream_id, 535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int associated_stream_id, 536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url) { 537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* const kStandardGetHeaders[] = { 538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch url 540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 541201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ConstructSpdyControlFrame(0, 542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream_id, 545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders, 549201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kStandardGetHeaders), 550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch associated_stream_id); 551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 552201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochspdy::SpdyFrame* ConstructSpdyPushHeaders(int stream_id, 554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* const extra_headers[], 555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int extra_header_count) { 556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* const kStandardGetHeaders[] = { 557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ConstructSpdyControlFrame(extra_headers, 563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch extra_header_count, 564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream_id, 566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders, 570201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kStandardGetHeaders)); 571201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 573513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Constructs a standard SPDY SYN_REPLY packet with the specified status code. 5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Returns a SpdyFrame. 575513209b27ff55e2841eac0e4120199c23acce758Ben Murdochspdy::SpdyFrame* ConstructSpdySynReplyError( 576513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const status, 577513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const* const extra_headers, 578513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int extra_header_count, 579513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int stream_id) { 580513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const kStandardGetHeaders[] = { 5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello", 5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "bye", 5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", 584513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch status, 5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 588513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ConstructSpdyControlFrame(extra_headers, 589513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch extra_header_count, 5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders)); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 599513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET. 600513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// |extra_headers| are the extra header-value pairs, which typically 601513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// will vary the most between calls. 602513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Returns a SpdyFrame. 603513209b27ff55e2841eac0e4120199c23acce758Ben Murdochspdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) { 604513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static const char* const kExtraHeaders[] = { 605513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "location", 606513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "http://www.foo.com/index.php", 607513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 608513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders, 609513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch arraysize(kExtraHeaders)/2, stream_id); 610513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 611513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a standard SPDY SYN_REPLY packet with an Internal Server 613731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Error status code. 614731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Returns a SpdyFrame. 615731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* ConstructSpdySynReplyError(int stream_id) { 616513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1); 617731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 619513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 620513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 621731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET. 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs, which typically 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will vary the most between calls. 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a SpdyFrame. 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[], 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count, 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int stream_id) { 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* const kStandardGetHeaders[] = { 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello", 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "bye", 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "200", 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1" 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 6393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, 6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, 6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 6453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders)); 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Constructs a standard SPDY POST SYN packet. 6493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// |content_length| is the size of post data. 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs, which typically 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will vary the most between calls. 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a SpdyFrame. 6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyPost(int64 content_length, 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const extra_headers[], 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count) { 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string length_str = base::Int64ToString(content_length); 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* post_headers[] = { 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "method", 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "POST", 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/", 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.google.com", 6643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", 6673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1", 6683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", 6693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick length_str.c_str() 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 6723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 6733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 6743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, 6753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 6763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, 6773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 6783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick post_headers, 6793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(post_headers)); 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 682dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Constructs a chunked transfer SPDY POST SYN packet. 683dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// |extra_headers| are the extra header-value pairs, which typically 684dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// will vary the most between calls. 685dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Returns a SpdyFrame. 686dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenspdy::SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[], 687dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int extra_header_count) { 688dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const char* post_headers[] = { 689dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "method", 690dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "POST", 691dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "url", 692dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "/", 693dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "host", 694dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "www.google.com", 695dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "scheme", 696dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "http", 697dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "version", 698dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "HTTP/1.1" 699dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 700dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return ConstructSpdyControlFrame(extra_headers, 701dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen extra_header_count, 702dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen false, 703dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1, 704dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOWEST, 705dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy::SYN_STREAM, 706dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy::CONTROL_FLAG_NONE, 707dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen post_headers, 708dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen arraysize(post_headers)); 709dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 710dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST. 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs, which typically 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will vary the most between calls. 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a SpdyFrame. 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[], 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count) { 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* const kStandardGetHeaders[] = { 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello", 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "bye", 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "200", 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "/index.php", 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1" 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ConstructSpdyControlFrame(extra_headers, 7283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extra_header_count, 7293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, 7303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, 7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOWEST, 7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, 7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, 7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kStandardGetHeaders, 7353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kStandardGetHeaders)); 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructs a single SPDY data frame with the default contents. 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochspdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id, bool fin) { 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 7413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return framer.CreateDataFrame( 7423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, kUploadData, kUploadDataSize, 7433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fin ? spdy::DATA_FLAG_FIN : spdy::DATA_FLAG_NONE); 7443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructs a single SPDY data frame with the given content. 7473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickspdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data, 7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick uint32 len, bool fin) { 7493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdyFramer framer; 7503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return framer.CreateDataFrame( 7513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream_id, data, len, fin ? spdy::DATA_FLAG_FIN : spdy::DATA_FLAG_NONE); 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 754731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Wraps |frame| in the payload of a data frame in stream |stream_id|. 755731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* ConstructWrappedSpdyFrame( 756731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const scoped_ptr<spdy::SpdyFrame>& frame, 757731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int stream_id) { 758731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ConstructSpdyBodyFrame(stream_id, frame->data(), 759731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick frame->length() + spdy::SpdyFrame::size(), 760731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick false); 761731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 762731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Construct an expected SPDY reply string. 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |extra_headers| are the extra header-value pairs, which typically 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will vary the most between calls. 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |buffer| is the buffer we're filling in. 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the number of bytes written into |buffer|. 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstructSpdyReplyString(const char* const extra_headers[], 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extra_header_count, 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer, 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int buffer_length) { 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int packet_size = 0; 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_count = 0; 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer_write = buffer; 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int buffer_left = buffer_length; 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyHeaderBlock headers; 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!buffer || !buffer_length) 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy in the extra headers. 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers); 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch header_count = headers.size(); 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The iterator gets us the list of header/value pairs in sorted order. 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyHeaderBlock::iterator next = headers.begin(); 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyHeaderBlock::iterator last = headers.end(); 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for ( ; next != last; ++next) { 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Write the header. 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int value_len, current_len, offset; 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_string = next->first.c_str(); 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer(header_string, 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next->first.length(), 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer(": ", 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch strlen(": "), 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Write the value(s). 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* value_string = next->second.c_str(); 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if it's split among two or more values. 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value_len = next->second.length(); 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_len = strlen(value_string); 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offset = 0; 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Handle the first N-1 values. 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (current_len < value_len) { 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Finish this line -- write the current value. 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer(value_string + offset, 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_len - offset, 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer("\n", 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch strlen("\n"), 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Advance to next value. 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offset = current_len + 1; 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_len += 1 + strlen(value_string + offset); 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start another line -- add the header again. 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer(header_string, 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next->first.length(), 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer(": ", 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch strlen(": "), 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(value_len, current_len); 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy the last (or only) value. 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer(value_string + offset, 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value_len - offset, 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch packet_size += AppendToBuffer("\n", 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch strlen("\n"), 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_write, 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer_left); 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return packet_size; 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Create a MockWrite from the given SpdyFrame. 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockWrite CreateMockWrite(const spdy::SpdyFrame& req) { 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockWrite( 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, req.data(), req.length() + spdy::SpdyFrame::size()); 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Create a MockWrite from the given SpdyFrame and sequence number. 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq) { 8493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CreateMockWrite(req, seq, true); 8503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 8513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 8523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Create a MockWrite from the given SpdyFrame and sequence number. 8533345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickMockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq, bool async) { 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockWrite( 8553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick async, req.data(), req.length() + spdy::SpdyFrame::size(), seq); 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Create a MockRead from the given SpdyFrame. 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockRead CreateMockRead(const spdy::SpdyFrame& resp) { 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockRead( 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, resp.data(), resp.length() + spdy::SpdyFrame::size()); 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Create a MockRead from the given SpdyFrame and sequence number. 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq) { 8663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CreateMockRead(resp, seq, true); 8673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 8683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 8693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Create a MockRead from the given SpdyFrame and sequence number. 8703345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickMockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq, bool async) { 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockRead( 8723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick async, resp.data(), resp.length() + spdy::SpdyFrame::size(), seq); 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Combines the given SpdyFrames into the given char array and returns 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the total length. 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint CombineFrames(const spdy::SpdyFrame** frames, int num_frames, 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buff, int buff_len) { 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int total_len = 0; 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < num_frames; ++i) { 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch total_len += frames[i]->length() + spdy::SpdyFrame::size(); 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(total_len, buff_len); 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* ptr = buff; 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < num_frames; ++i) { 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int len = frames[i]->length() + spdy::SpdyFrame::size(); 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch memcpy(ptr, frames[i]->data(), len); 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ptr += len; 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return total_len; 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 89372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSpdySessionDependencies::SpdySessionDependencies() 894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : host_resolver(new MockCachingHostResolver), 89572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cert_verifier(new CertVerifier), 89672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proxy_service(ProxyService::CreateDirect()), 89772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_config_service(new SSLConfigServiceDefaults), 89872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen socket_factory(new MockClientSocketFactory), 89972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen deterministic_socket_factory(new DeterministicMockClientSocketFactory), 90072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen http_auth_handler_factory( 90172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuthHandlerFactory::CreateDefault(host_resolver.get())) { 90272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Note: The CancelledTransaction test does cleanup by running all 90372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // tasks in the message loop (RunAllPending). Unfortunately, that 90472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // doesn't clean up tasks on the host resolver thread; and 90572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TCPConnectJob is currently not cancellable. Using synchronous 90672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // lookups allows the test to shutdown cleanly. Until we have 90772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // cancellable TCPConnectJobs, use synchronous lookups. 90872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen host_resolver->set_synchronous_mode(true); 90972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 91172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSpdySessionDependencies::SpdySessionDependencies(ProxyService* proxy_service) 91272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : host_resolver(new MockHostResolver), 91372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cert_verifier(new CertVerifier), 91472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proxy_service(proxy_service), 91572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_config_service(new SSLConfigServiceDefaults), 91672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen socket_factory(new MockClientSocketFactory), 91772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen deterministic_socket_factory(new DeterministicMockClientSocketFactory), 91872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen http_auth_handler_factory( 91972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuthHandlerFactory::CreateDefault(host_resolver.get())) {} 92072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 92172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSpdySessionDependencies::~SpdySessionDependencies() {} 92272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 92372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 92472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenHttpNetworkSession* SpdySessionDependencies::SpdyCreateSession( 92572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SpdySessionDependencies* session_deps) { 92672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpNetworkSession::Params params; 92772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.client_socket_factory = session_deps->socket_factory.get(); 92872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.host_resolver = session_deps->host_resolver.get(); 92972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.cert_verifier = session_deps->cert_verifier.get(); 93072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.proxy_service = session_deps->proxy_service; 93172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.ssl_config_service = session_deps->ssl_config_service; 93272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.http_auth_handler_factory = 93372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps->http_auth_handler_factory.get(); 93472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return new HttpNetworkSession(params); 93572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 93672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 93772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 93872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenHttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic( 93972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SpdySessionDependencies* session_deps) { 94072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpNetworkSession::Params params; 94172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.client_socket_factory = 94272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps->deterministic_socket_factory.get(); 94372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.host_resolver = session_deps->host_resolver.get(); 94472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.cert_verifier = session_deps->cert_verifier.get(); 94572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.proxy_service = session_deps->proxy_service; 94672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.ssl_config_service = session_deps->ssl_config_service; 94772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.http_auth_handler_factory = 94872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps->http_auth_handler_factory.get(); 94972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return new HttpNetworkSession(params); 95072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 95172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSpdyURLRequestContext::SpdyURLRequestContext() { 953dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen set_host_resolver(new MockHostResolver()); 954dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen set_cert_verifier(new CertVerifier); 955dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen set_proxy_service(ProxyService::CreateDirect()); 956dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen set_ssl_config_service(new SSLConfigServiceDefaults); 957dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault( 958dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen host_resolver())); 95972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpNetworkSession::Params params; 96072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.client_socket_factory = &socket_factory_; 961dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params.host_resolver = host_resolver(); 962dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params.cert_verifier = cert_verifier(); 963dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params.proxy_service = proxy_service(); 964dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params.ssl_config_service = ssl_config_service(); 965dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params.http_auth_handler_factory = http_auth_handler_factory(); 966dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params.network_delegate = network_delegate(); 96772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> network_session( 96872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkSession(params)); 969dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen set_http_transaction_factory(new HttpCache( 97072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen network_session, 971dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpCache::DefaultBackend::InMemory(0))); 97272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 97372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 97472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSpdyURLRequestContext::~SpdyURLRequestContext() { 975dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete http_transaction_factory(); 976dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete http_auth_handler_factory(); 977dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete cert_verifier(); 978dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete host_resolver(); 97972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 98072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst SpdyHeaderInfo make_spdy_header(spdy::SpdyControlType type) { 9823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kHeader = { 9833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick type, // Kind = Syn 9843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 9853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 9863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2, // Priority 9873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_FIN, // Control Flags 9883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 9933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 9943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return kHeader; 9953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 997