spdy_protocol.h revision 4ad1aa43a48567659193a298fad74f55e00b3dd9
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// This file contains some protocol structures for use with SPDY 2 and 3 6// The SPDY 2 spec can be found at: 7// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2 8// The SPDY 3 spec can be found at: 9// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3 10 11#ifndef NET_SPDY_SPDY_PROTOCOL_H_ 12#define NET_SPDY_SPDY_PROTOCOL_H_ 13 14#include <map> 15#include <string> 16#include <vector> 17 18#include "base/basictypes.h" 19#include "base/compiler_specific.h" 20#include "base/logging.h" 21#include "base/memory/scoped_ptr.h" 22#include "base/strings/string_piece.h" 23#include "base/sys_byteorder.h" 24#include "net/base/net_export.h" 25#include "net/spdy/spdy_bitmasks.h" 26 27namespace net { 28 29// The major versions of SPDY. Major version differences indicate 30// framer-layer incompatibility, as opposed to minor version numbers 31// which indicate application-layer incompatibility. It is guaranteed 32// that the enum value SPDYn maps to the integer n. 33enum SpdyMajorVersion { 34 SPDY2 = 2, 35 SPDY_MIN_VERSION = SPDY2, 36 SPDY3 = 3, 37 SPDY4 = 4, 38 SPDY_MAX_VERSION = SPDY4 39}; 40 41// A SPDY stream id is a 31 bit entity. 42typedef uint32 SpdyStreamId; 43 44// Specifies the stream ID used to denote the current session (for 45// flow control). 46const SpdyStreamId kSessionFlowControlStreamId = 0; 47 48// Initial window size for a Spdy stream in bytes. 49const int32 kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes 50 51// Initial window size for a Spdy session in bytes. 52const int32 kSpdySessionInitialWindowSize = 64 * 1024; // 64 KBytes 53 54// Maximum window size for a Spdy stream or session. 55const int32 kSpdyMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int 56 57// SPDY 2 dictionary. 58// This is just a hacked dictionary to use for shrinking HTTP-like headers. 59const char kV2Dictionary[] = 60 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" 61 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi" 62 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser" 63 "-agent10010120020120220320420520630030130230330430530630740040140240340440" 64 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta" 65 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic" 66 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran" 67 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati" 68 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo" 69 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe" 70 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic" 71 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1" 72 ".1statusversionurl"; 73const int kV2DictionarySize = arraysize(kV2Dictionary); 74 75// SPDY 3 dictionary. 76const char kV3Dictionary[] = { 77 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti 78 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h 79 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p 80 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p 81 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de 82 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete.... 83 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace... 84 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept. 85 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep 86 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse 87 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc 88 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco 89 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding.... 90 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l 91 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage. 92 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep 93 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges 94 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age. 95 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow 96 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth 97 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio 98 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac 99 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr 100 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co 101 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection 102 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont 103 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base 104 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont 105 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco 106 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding.... 107 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content- 108 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language 109 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont 110 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng 111 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co 112 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo 113 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation.. 114 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten 115 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5... 116 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content 117 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range.. 118 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten 119 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type.. 120 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date.. 121 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag.. 122 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect 123 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi 124 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f 125 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h 126 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i 127 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match. 128 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo 129 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s 130 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince.... 131 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none- 132 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match... 133 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang 134 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if- 135 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi 136 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since 137 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last 138 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie 139 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc 140 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation... 141 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for 142 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards... 143 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma. 144 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy 145 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent 146 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate... 147 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a 148 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza 149 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion.... 150 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range... 151 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer 152 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr 153 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after. 154 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve 155 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te. 156 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail 157 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr 158 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e 159 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding. 160 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra 161 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us 162 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent 163 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary 164 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via. 165 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni 166 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww 167 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen 168 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate.. 169 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method 170 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get. 171 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu 172 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200 173 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v 174 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion.. 175 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1 176 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur 177 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub 178 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s 179 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki 180 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee 181 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive. 182 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi 183 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012 184 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205 185 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030 186 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043 187 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307 188 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540 189 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084 190 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411 191 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341 192 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164 193 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504 194 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N 195 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho 196 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative 197 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa 198 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204. 199 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte 200 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo 201 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm 202 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4 203 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R 204 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40 205 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth 206 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40 207 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid 208 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N 209 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found 210 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte 211 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser 212 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro 213 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not 214 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme 215 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503. 216 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service. 217 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila 218 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F 219 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A 220 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J 221 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A 222 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept. 223 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov. 224 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0 225 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon 226 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W 227 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu. 228 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa 229 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun.. 230 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk 231 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text. 232 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima 233 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i 234 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg 235 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g 236 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli 237 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x 238 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli 239 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x 240 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml 241 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl 242 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text 243 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr 244 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ 245 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat 246 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age 247 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de 248 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd 249 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse 250 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c 251 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i 252 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859- 253 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-.. 254 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0. 255}; 256const int kV3DictionarySize = arraysize(kV3Dictionary); 257 258// The HTTP/2 connection header prefix, which must be the first bytes 259// sent by the client upon starting an HTTP/2 connection, and which 260// must be followed by a SETTINGS frame. 261// 262// Equivalent to the string "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 263// (without the null terminator). 264const char kHttp2ConnectionHeaderPrefix[] = { 265 0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, // PRI * HT 266 0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a, // TP/2.0.. 267 0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a // ..SM.... 268}; 269const int kHttp2ConnectionHeaderPrefixSize = 270 arraysize(kHttp2ConnectionHeaderPrefix); 271 272// Types of SPDY frames. 273enum SpdyFrameType { 274 DATA = 0, 275 SYN_STREAM = 1, 276 FIRST_CONTROL_TYPE = SYN_STREAM, 277 SYN_REPLY, 278 RST_STREAM, 279 SETTINGS, 280 NOOP, // Because it is valid in SPDY/2, kept for identifiability/enum order. 281 PING, 282 GOAWAY, 283 HEADERS, 284 WINDOW_UPDATE, 285 CREDENTIAL, // No longer valid. Kept for identifiability/enum order. 286 BLOCKED, 287 PUSH_PROMISE, 288 CONTINUATION, 289 LAST_CONTROL_TYPE = CONTINUATION 290}; 291 292// Flags on data packets. 293enum SpdyDataFlags { 294DATA_FLAG_NONE = 0x00, 295 DATA_FLAG_FIN = 0x01, 296 DATA_FLAG_END_SEGMENT = 0x02, 297 DATA_FLAG_PAD_LOW = 0x10, 298 DATA_FLAG_PAD_HIGH = 0x20 299}; 300 301// Flags on control packets 302enum SpdyControlFlags { 303 CONTROL_FLAG_NONE = 0, 304 CONTROL_FLAG_FIN = 1, 305 CONTROL_FLAG_UNIDIRECTIONAL = 2 306}; 307 308enum SpdyPingFlags { 309 PING_FLAG_ACK = 0x1, 310}; 311 312enum SpdyHeadersFlags { 313 HEADERS_FLAG_END_HEADERS = 0x4, 314 HEADERS_FLAG_PRIORITY = 0x8 315}; 316 317enum SpdyPushPromiseFlags { 318 PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x4 319}; 320 321// Flags on the SETTINGS control frame. 322enum SpdySettingsControlFlags { 323 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1 324}; 325 326enum Http2SettingsControlFlags { 327 SETTINGS_FLAG_ACK = 0x1, 328}; 329 330// Flags for settings within a SETTINGS frame. 331enum SpdySettingsFlags { 332 SETTINGS_FLAG_NONE = 0x0, 333 SETTINGS_FLAG_PLEASE_PERSIST = 0x1, 334 SETTINGS_FLAG_PERSISTED = 0x2 335}; 336 337// List of known settings. 338enum SpdySettingsIds { 339 SETTINGS_UPLOAD_BANDWIDTH, 340 SETTINGS_DOWNLOAD_BANDWIDTH, 341 // Network round trip time in milliseconds. 342 SETTINGS_ROUND_TRIP_TIME, 343 // The maximum number of simultaneous live streams in each direction. 344 SETTINGS_MAX_CONCURRENT_STREAMS, 345 // TCP congestion window in packets. 346 SETTINGS_CURRENT_CWND, 347 // Downstream byte retransmission rate in percentage. 348 SETTINGS_DOWNLOAD_RETRANS_RATE, 349 // Initial window size in bytes 350 SETTINGS_INITIAL_WINDOW_SIZE, 351 // HPACK header table maximum size. 352 SETTINGS_HEADER_TABLE_SIZE, 353 // Whether or not server push (PUSH_PROMISE) is enabled. 354 SETTINGS_ENABLE_PUSH, 355}; 356 357// Status codes for RST_STREAM frames. 358enum SpdyRstStreamStatus { 359 RST_STREAM_INVALID = 0, 360 RST_STREAM_PROTOCOL_ERROR = 1, 361 RST_STREAM_INVALID_STREAM = 2, 362 RST_STREAM_REFUSED_STREAM = 3, 363 RST_STREAM_UNSUPPORTED_VERSION = 4, 364 RST_STREAM_CANCEL = 5, 365 RST_STREAM_INTERNAL_ERROR = 6, 366 RST_STREAM_FLOW_CONTROL_ERROR = 7, 367 RST_STREAM_STREAM_IN_USE = 8, 368 RST_STREAM_STREAM_ALREADY_CLOSED = 9, 369 RST_STREAM_INVALID_CREDENTIALS = 10, 370 RST_STREAM_FRAME_TOO_LARGE = 11, 371 RST_STREAM_NUM_STATUS_CODES = 12 372}; 373 374// Status codes for GOAWAY frames. 375enum SpdyGoAwayStatus { 376 GOAWAY_INVALID = -1, 377 GOAWAY_OK = 0, 378 GOAWAY_PROTOCOL_ERROR = 1, 379 GOAWAY_INTERNAL_ERROR = 2, 380 GOAWAY_NUM_STATUS_CODES = 3 // Must be last. 381}; 382 383// A SPDY priority is a number between 0 and 7 (inclusive). 384// SPDY priority range is version-dependent. For SPDY 2 and below, priority is a 385// number between 0 and 3. 386typedef uint8 SpdyPriority; 387 388typedef std::map<std::string, std::string> SpdyNameValueBlock; 389 390typedef uint64 SpdyPingId; 391 392// TODO(hkhalil): Add direct testing for this? It won't increase coverage any, 393// but is good to do anyway. 394class NET_EXPORT_PRIVATE SpdyConstants { 395 public: 396 // Returns true if a given on-the-wire enumeration of a frame type is valid 397 // for a given protocol version, false otherwise. 398 static bool IsValidFrameType(SpdyMajorVersion version, int frame_type_field); 399 400 // Parses a frame type from an on-the-wire enumeration of a given protocol 401 // version. 402 // Behavior is undefined for invalid frame type fields; consumers should first 403 // use IsValidFrameType() to verify validity of frame type fields. 404 static SpdyFrameType ParseFrameType(SpdyMajorVersion version, 405 int frame_type_field); 406 407 // Serializes a given frame type to the on-the-wire enumeration value for the 408 // given protocol version. 409 // Returns -1 on failure (I.E. Invalid frame type for the given version). 410 static int SerializeFrameType(SpdyMajorVersion version, 411 SpdyFrameType frame_type); 412 413 // Returns true if a given on-the-wire enumeration of a setting id is valid 414 // for a given protocol version, false otherwise. 415 static bool IsValidSettingId(SpdyMajorVersion version, int setting_id_field); 416 417 // Parses a setting id from an on-the-wire enumeration of a given protocol 418 // version. 419 // Behavior is undefined for invalid setting id fields; consumers should first 420 // use IsValidSettingId() to verify validity of setting id fields. 421 static SpdySettingsIds ParseSettingId(SpdyMajorVersion version, 422 int setting_id_field); 423 424 // Serializes a given setting id to the on-the-wire enumeration value for the 425 // given protocol version. 426 // Returns -1 on failure (I.E. Invalid setting id for the given version). 427 static int SerializeSettingId(SpdyMajorVersion version, SpdySettingsIds id); 428}; 429 430class SpdyFrame; 431typedef SpdyFrame SpdySerializedFrame; 432 433class SpdyFrameVisitor; 434 435// Intermediate representation for SPDY frames. 436// TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is 437// gone. 438class NET_EXPORT_PRIVATE SpdyFrameIR { 439 public: 440 virtual ~SpdyFrameIR() {} 441 442 virtual void Visit(SpdyFrameVisitor* visitor) const = 0; 443 444 protected: 445 SpdyFrameIR() {} 446 447 private: 448 DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR); 449}; 450 451// Abstract class intended to be inherited by IRs that have a stream associated 452// to them. 453class NET_EXPORT_PRIVATE SpdyFrameWithStreamIdIR : public SpdyFrameIR { 454 public: 455 virtual ~SpdyFrameWithStreamIdIR() {} 456 SpdyStreamId stream_id() const { return stream_id_; } 457 void set_stream_id(SpdyStreamId stream_id) { 458 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 459 stream_id_ = stream_id; 460 } 461 462 protected: 463 explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) { 464 set_stream_id(stream_id); 465 } 466 467 private: 468 SpdyStreamId stream_id_; 469 470 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR); 471}; 472 473// Abstract class intended to be inherited by IRs that have the option of a FIN 474// flag. Implies SpdyFrameWithStreamIdIR. 475class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR { 476 public: 477 virtual ~SpdyFrameWithFinIR() {} 478 bool fin() const { return fin_; } 479 void set_fin(bool fin) { fin_ = fin; } 480 481 protected: 482 explicit SpdyFrameWithFinIR(SpdyStreamId stream_id) 483 : SpdyFrameWithStreamIdIR(stream_id), 484 fin_(false) {} 485 486 private: 487 bool fin_; 488 489 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR); 490}; 491 492// Abstract class intended to be inherited by IRs that contain a name-value 493// block. Implies SpdyFrameWithFinIR. 494class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR 495 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { 496 public: 497 const SpdyNameValueBlock& name_value_block() const { 498 return name_value_block_; 499 } 500 void set_name_value_block(const SpdyNameValueBlock& name_value_block) { 501 // Deep copy. 502 name_value_block_ = name_value_block; 503 } 504 void SetHeader(const base::StringPiece& name, 505 const base::StringPiece& value) { 506 name_value_block_[name.as_string()] = value.as_string(); 507 } 508 509 protected: 510 explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id); 511 virtual ~SpdyFrameWithNameValueBlockIR(); 512 513 private: 514 SpdyNameValueBlock name_value_block_; 515 516 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR); 517}; 518 519class NET_EXPORT_PRIVATE SpdyDataIR 520 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { 521 public: 522 // Performs deep copy on data. 523 SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data); 524 525 // Use in conjunction with SetDataShallow() for shallow-copy on data. 526 explicit SpdyDataIR(SpdyStreamId stream_id); 527 528 virtual ~SpdyDataIR(); 529 530 base::StringPiece data() const { return data_; } 531 532 bool pad_low() const { return pad_low_; } 533 534 bool pad_high() const { return pad_high_; } 535 536 int padding_payload_len() const { return padding_payload_len_; } 537 538 void set_padding_len(int padding_len) { 539 // The padding_len should be in (0, 65535 + 2]. 540 // Note that SpdyFramer::GetDataFrameMaximumPayload() enforces the overall 541 // payload size later so we actually can't pad more than 16375 bytes. 542 DCHECK_GT(padding_len, 0); 543 DCHECK_LT(padding_len, 65537); 544 545 if (padding_len <= 256) { 546 pad_low_ = true; 547 --padding_len; 548 } else { 549 pad_low_ = pad_high_ = true; 550 padding_len -= 2; 551 } 552 padding_payload_len_ = padding_len; 553 } 554 555 // Deep-copy of data (keep private copy). 556 void SetDataDeep(const base::StringPiece& data) { 557 data_store_.reset(new std::string(data.data(), data.length())); 558 data_ = *(data_store_.get()); 559 } 560 561 // Shallow-copy of data (do not keep private copy). 562 void SetDataShallow(const base::StringPiece& data) { 563 data_store_.reset(); 564 data_ = data; 565 } 566 567 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 568 569 private: 570 // Used to store data that this SpdyDataIR should own. 571 scoped_ptr<std::string> data_store_; 572 base::StringPiece data_; 573 574 bool pad_low_; 575 bool pad_high_; 576 // padding_payload_len_ = desired padding length - len(padding length field). 577 int padding_payload_len_; 578 579 DISALLOW_COPY_AND_ASSIGN(SpdyDataIR); 580}; 581 582class NET_EXPORT_PRIVATE SpdySynStreamIR 583 : public SpdyFrameWithNameValueBlockIR { 584 public: 585 explicit SpdySynStreamIR(SpdyStreamId stream_id) 586 : SpdyFrameWithNameValueBlockIR(stream_id), 587 associated_to_stream_id_(0), 588 priority_(0), 589 unidirectional_(false) {} 590 SpdyStreamId associated_to_stream_id() const { 591 return associated_to_stream_id_; 592 } 593 void set_associated_to_stream_id(SpdyStreamId stream_id) { 594 associated_to_stream_id_ = stream_id; 595 } 596 SpdyPriority priority() const { return priority_; } 597 void set_priority(SpdyPriority priority) { priority_ = priority; } 598 bool unidirectional() const { return unidirectional_; } 599 void set_unidirectional(bool unidirectional) { 600 unidirectional_ = unidirectional; 601 } 602 603 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 604 605 private: 606 SpdyStreamId associated_to_stream_id_; 607 SpdyPriority priority_; 608 bool unidirectional_; 609 610 DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR); 611}; 612 613class NET_EXPORT_PRIVATE SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR { 614 public: 615 explicit SpdySynReplyIR(SpdyStreamId stream_id) 616 : SpdyFrameWithNameValueBlockIR(stream_id) {} 617 618 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 619 620 private: 621 DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR); 622}; 623 624class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR { 625 public: 626 SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status, 627 base::StringPiece description); 628 629 virtual ~SpdyRstStreamIR(); 630 631 SpdyRstStreamStatus status() const { 632 return status_; 633 } 634 void set_status(SpdyRstStreamStatus status) { 635 DCHECK_NE(status, RST_STREAM_INVALID); 636 DCHECK_LT(status, RST_STREAM_NUM_STATUS_CODES); 637 status_ = status; 638 } 639 640 base::StringPiece description() const { return description_; } 641 642 void set_description(base::StringPiece description) { 643 description_ = description; 644 } 645 646 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 647 648 private: 649 SpdyRstStreamStatus status_; 650 base::StringPiece description_; 651 652 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR); 653}; 654 655class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR { 656 public: 657 // Associates flags with a value. 658 struct Value { 659 Value() : persist_value(false), 660 persisted(false), 661 value(0) {} 662 bool persist_value; 663 bool persisted; 664 int32 value; 665 }; 666 typedef std::map<SpdySettingsIds, Value> ValueMap; 667 668 SpdySettingsIR(); 669 670 virtual ~SpdySettingsIR(); 671 672 // Overwrites as appropriate. 673 const ValueMap& values() const { return values_; } 674 void AddSetting(SpdySettingsIds id, 675 bool persist_value, 676 bool persisted, 677 int32 value) { 678 values_[id].persist_value = persist_value; 679 values_[id].persisted = persisted; 680 values_[id].value = value; 681 } 682 683 bool clear_settings() const { return clear_settings_; } 684 void set_clear_settings(bool clear_settings) { 685 clear_settings_ = clear_settings; 686 } 687 bool is_ack() const { return is_ack_; } 688 void set_is_ack(bool is_ack) { 689 is_ack_ = is_ack; 690 } 691 692 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 693 694 private: 695 ValueMap values_; 696 bool clear_settings_; 697 bool is_ack_; 698 699 DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR); 700}; 701 702class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR { 703 public: 704 explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {} 705 SpdyPingId id() const { return id_; } 706 707 // ACK logic is valid only for SPDY versions 4 and above. 708 bool is_ack() const { return is_ack_; } 709 void set_is_ack(bool is_ack) { is_ack_ = is_ack; } 710 711 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 712 713 private: 714 SpdyPingId id_; 715 bool is_ack_; 716 717 DISALLOW_COPY_AND_ASSIGN(SpdyPingIR); 718}; 719 720class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR { 721 public: 722 SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status, 723 const base::StringPiece& description); 724 virtual ~SpdyGoAwayIR(); 725 SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; } 726 void set_last_good_stream_id(SpdyStreamId last_good_stream_id) { 727 DCHECK_LE(0u, last_good_stream_id); 728 DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask); 729 last_good_stream_id_ = last_good_stream_id; 730 } 731 SpdyGoAwayStatus status() const { return status_; } 732 void set_status(SpdyGoAwayStatus status) { 733 // TODO(hkhalil): Check valid ranges of status? 734 status_ = status; 735 } 736 737 const base::StringPiece& description() const; 738 739 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 740 741 private: 742 SpdyStreamId last_good_stream_id_; 743 SpdyGoAwayStatus status_; 744 const base::StringPiece description_; 745 746 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR); 747}; 748 749class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR { 750 public: 751 explicit SpdyHeadersIR(SpdyStreamId stream_id) 752 : SpdyFrameWithNameValueBlockIR(stream_id), 753 end_headers_(true), 754 has_priority_(false), 755 priority_(0) {} 756 757 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 758 759 bool end_headers() const { return end_headers_; } 760 void set_end_headers(bool end_headers) {end_headers_ = end_headers;} 761 bool has_priority() const { return has_priority_; } 762 void set_has_priority(bool has_priority) { has_priority_ = has_priority; } 763 uint32 priority() const { return priority_; } 764 void set_priority(SpdyPriority priority) { priority_ = priority; } 765 766 private: 767 bool end_headers_; 768 bool has_priority_; 769 // 31-bit priority. 770 uint32 priority_; 771 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR); 772}; 773 774class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR { 775 public: 776 SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta) 777 : SpdyFrameWithStreamIdIR(stream_id) { 778 set_delta(delta); 779 } 780 int32 delta() const { return delta_; } 781 void set_delta(int32 delta) { 782 DCHECK_LT(0, delta); 783 DCHECK_LE(delta, kSpdyMaximumWindowSize); 784 delta_ = delta; 785 } 786 787 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 788 789 private: 790 int32 delta_; 791 792 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR); 793}; 794 795class NET_EXPORT_PRIVATE SpdyBlockedIR 796 : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR) { 797 public: 798 explicit SpdyBlockedIR(SpdyStreamId stream_id) 799 : SpdyFrameWithStreamIdIR(stream_id) {} 800 801 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 802 803 private: 804 DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR); 805}; 806 807class NET_EXPORT_PRIVATE SpdyPushPromiseIR 808 : public SpdyFrameWithNameValueBlockIR { 809 public: 810 SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id) 811 : SpdyFrameWithNameValueBlockIR(stream_id), 812 promised_stream_id_(promised_stream_id), 813 end_push_promise_(true) {} 814 SpdyStreamId promised_stream_id() const { return promised_stream_id_; } 815 void set_promised_stream_id(SpdyStreamId id) { promised_stream_id_ = id; } 816 bool end_push_promise() const { return end_push_promise_; } 817 void set_end_push_promise(bool end_push_promise) { 818 end_push_promise_ = end_push_promise; 819 } 820 821 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 822 823 private: 824 SpdyStreamId promised_stream_id_; 825 bool end_push_promise_; 826 DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR); 827}; 828 829// TODO(jgraettinger): This representation needs review. SpdyContinuationIR 830// needs to frame a portion of a single, arbitrarily-broken encoded buffer. 831class NET_EXPORT_PRIVATE SpdyContinuationIR 832 : public SpdyFrameWithNameValueBlockIR { 833 public: 834 explicit SpdyContinuationIR(SpdyStreamId stream_id) 835 : SpdyFrameWithNameValueBlockIR(stream_id), 836 end_headers_(false) {} 837 838 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 839 840 bool end_headers() const { return end_headers_; } 841 void set_end_headers(bool end_headers) {end_headers_ = end_headers;} 842 843 private: 844 bool end_headers_; 845 DISALLOW_COPY_AND_ASSIGN(SpdyContinuationIR); 846}; 847 848// ------------------------------------------------------------------------- 849// Wrapper classes for various SPDY frames. 850 851// All Spdy Frame types derive from this SpdyFrame class. 852class SpdyFrame { 853 public: 854 // Create a SpdyFrame using a pre-created buffer. 855 // If |owns_buffer| is true, this class takes ownership of the buffer 856 // and will delete it on cleanup. The buffer must have been created using 857 // new char[]. 858 // If |owns_buffer| is false, the caller retains ownership of the buffer and 859 // is responsible for making sure the buffer outlives this frame. In other 860 // words, this class does NOT create a copy of the buffer. 861 SpdyFrame(char* data, size_t size, bool owns_buffer) 862 : frame_(data), 863 size_(size), 864 owns_buffer_(owns_buffer) { 865 DCHECK(frame_); 866 } 867 868 ~SpdyFrame() { 869 if (owns_buffer_) { 870 delete [] frame_; 871 } 872 frame_ = NULL; 873 } 874 875 // Provides access to the frame bytes, which is a buffer containing 876 // the frame packed as expected for sending over the wire. 877 char* data() const { return frame_; } 878 879 // Returns the actual size of the underlying buffer. 880 size_t size() const { return size_; } 881 882 protected: 883 char* frame_; 884 885 private: 886 size_t size_; 887 bool owns_buffer_; 888 DISALLOW_COPY_AND_ASSIGN(SpdyFrame); 889}; 890 891// This interface is for classes that want to process SpdyFrameIRs without 892// having to know what type they are. An instance of this interface can be 893// passed to a SpdyFrameIR's Visit method, and the appropriate type-specific 894// method of this class will be called. 895class SpdyFrameVisitor { 896 public: 897 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) = 0; 898 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) = 0; 899 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0; 900 virtual void VisitSettings(const SpdySettingsIR& settings) = 0; 901 virtual void VisitPing(const SpdyPingIR& ping) = 0; 902 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0; 903 virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0; 904 virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0; 905 virtual void VisitBlocked(const SpdyBlockedIR& blocked) = 0; 906 virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0; 907 virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0; 908 virtual void VisitData(const SpdyDataIR& data) = 0; 909 910 protected: 911 SpdyFrameVisitor() {} 912 virtual ~SpdyFrameVisitor() {} 913 914 private: 915 DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor); 916}; 917 918} // namespace net 919 920#endif // NET_SPDY_SPDY_PROTOCOL_H_ 921