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