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