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 // Initial window size for a Spdy session in bytes. 53 const int32 kSpdySessionInitialWindowSize = 64 * 1024; // 64 KBytes 54 55 // Maximum window size for a Spdy stream or session. 56 const 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. 60 const 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"; 74 const int kV2DictionarySize = arraysize(kV2Dictionary); 75 76 // SPDY 3 dictionary. 77 const 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 }; 257 const 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). 265 const 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 }; 270 const int kHttp2ConnectionHeaderPrefixSize = 271 arraysize(kHttp2ConnectionHeaderPrefix); 272 273 // Types of SPDY frames. 274 enum 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 ALTSVC, 291 PRIORITY, 292 LAST_CONTROL_TYPE = PRIORITY 293 }; 294 295 // Flags on data packets. 296 enum SpdyDataFlags { 297 DATA_FLAG_NONE = 0x00, 298 DATA_FLAG_FIN = 0x01, 299 DATA_FLAG_END_SEGMENT = 0x02, 300 DATA_FLAG_PAD_LOW = 0x08, 301 DATA_FLAG_PAD_HIGH = 0x10, 302 DATA_FLAG_COMPRESSED = 0x20, 303 }; 304 305 // Flags on control packets 306 enum SpdyControlFlags { 307 CONTROL_FLAG_NONE = 0x00, 308 CONTROL_FLAG_FIN = 0x01, 309 CONTROL_FLAG_UNIDIRECTIONAL = 0x02, 310 }; 311 312 enum SpdyPingFlags { 313 PING_FLAG_ACK = 0x01, 314 }; 315 316 // Used by HEADERS, PUSH_PROMISE, and CONTINUATION. 317 enum SpdyHeadersFlags { 318 HEADERS_FLAG_END_SEGMENT = 0x02, 319 HEADERS_FLAG_END_HEADERS = 0x04, 320 HEADERS_FLAG_PAD_LOW = 0x08, 321 HEADERS_FLAG_PAD_HIGH = 0x10, 322 HEADERS_FLAG_PRIORITY = 0x20, 323 }; 324 325 enum SpdyPushPromiseFlags { 326 PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x04, 327 }; 328 329 // Flags on the SETTINGS control frame. 330 enum SpdySettingsControlFlags { 331 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x01, 332 }; 333 334 enum Http2SettingsControlFlags { 335 SETTINGS_FLAG_ACK = 0x01, 336 }; 337 338 // Flags for settings within a SETTINGS frame. 339 enum SpdySettingsFlags { 340 SETTINGS_FLAG_NONE = 0x00, 341 SETTINGS_FLAG_PLEASE_PERSIST = 0x01, 342 SETTINGS_FLAG_PERSISTED = 0x02, 343 }; 344 345 // List of known settings. Avoid changing these enum values, as persisted 346 // settings are keyed on them, and they are also exposed in net-internals. 347 enum SpdySettingsIds { 348 SETTINGS_UPLOAD_BANDWIDTH = 0x1, 349 SETTINGS_DOWNLOAD_BANDWIDTH = 0x2, 350 // Network round trip time in milliseconds. 351 SETTINGS_ROUND_TRIP_TIME = 0x3, 352 // The maximum number of simultaneous live streams in each direction. 353 SETTINGS_MAX_CONCURRENT_STREAMS = 0x4, 354 // TCP congestion window in packets. 355 SETTINGS_CURRENT_CWND = 0x5, 356 // Downstream byte retransmission rate in percentage. 357 SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6, 358 // Initial window size in bytes 359 SETTINGS_INITIAL_WINDOW_SIZE = 0x7, 360 // HPACK header table maximum size. 361 SETTINGS_HEADER_TABLE_SIZE = 0x8, 362 // Whether or not server push (PUSH_PROMISE) is enabled. 363 SETTINGS_ENABLE_PUSH = 0x9, 364 // Whether or not to enable GZip compression of DATA frames. 365 SETTINGS_COMPRESS_DATA = 0xa, 366 }; 367 368 // Status codes for RST_STREAM frames. 369 enum SpdyRstStreamStatus { 370 RST_STREAM_INVALID = 0, 371 RST_STREAM_PROTOCOL_ERROR = 1, 372 RST_STREAM_INVALID_STREAM = 2, 373 RST_STREAM_STREAM_CLOSED = 2, // Equivalent to INVALID_STREAM 374 RST_STREAM_REFUSED_STREAM = 3, 375 RST_STREAM_UNSUPPORTED_VERSION = 4, 376 RST_STREAM_CANCEL = 5, 377 RST_STREAM_INTERNAL_ERROR = 6, 378 RST_STREAM_FLOW_CONTROL_ERROR = 7, 379 RST_STREAM_STREAM_IN_USE = 8, 380 RST_STREAM_STREAM_ALREADY_CLOSED = 9, 381 RST_STREAM_INVALID_CREDENTIALS = 10, 382 // FRAME_TOO_LARGE (defined by SPDY versions 3.1 and below), and 383 // FRAME_SIZE_ERROR (defined by HTTP/2) are mapped to the same internal 384 // reset status. 385 RST_STREAM_FRAME_TOO_LARGE = 11, 386 RST_STREAM_FRAME_SIZE_ERROR = 11, 387 RST_STREAM_SETTINGS_TIMEOUT = 12, 388 RST_STREAM_CONNECT_ERROR = 13, 389 RST_STREAM_ENHANCE_YOUR_CALM = 14, 390 RST_STREAM_NUM_STATUS_CODES = 15 391 }; 392 393 // Status codes for GOAWAY frames. 394 enum SpdyGoAwayStatus { 395 GOAWAY_OK = 0, 396 GOAWAY_NO_ERROR = GOAWAY_OK, 397 GOAWAY_PROTOCOL_ERROR = 1, 398 GOAWAY_INTERNAL_ERROR = 2, 399 GOAWAY_FLOW_CONTROL_ERROR = 3, 400 GOAWAY_SETTINGS_TIMEOUT = 4, 401 GOAWAY_STREAM_CLOSED = 5, 402 GOAWAY_FRAME_SIZE_ERROR = 6, 403 GOAWAY_REFUSED_STREAM = 7, 404 GOAWAY_CANCEL = 8, 405 GOAWAY_COMPRESSION_ERROR = 9, 406 GOAWAY_CONNECT_ERROR = 10, 407 GOAWAY_ENHANCE_YOUR_CALM = 11, 408 GOAWAY_INADEQUATE_SECURITY = 12 409 }; 410 411 // A SPDY priority is a number between 0 and 7 (inclusive). 412 // SPDY priority range is version-dependent. For SPDY 2 and below, priority is a 413 // number between 0 and 3. 414 typedef uint8 SpdyPriority; 415 416 typedef std::map<std::string, std::string> SpdyNameValueBlock; 417 418 typedef uint64 SpdyPingId; 419 420 typedef std::string SpdyProtocolId; 421 422 // TODO(hkhalil): Add direct testing for this? It won't increase coverage any, 423 // but is good to do anyway. 424 class NET_EXPORT_PRIVATE SpdyConstants { 425 public: 426 // Returns true if a given on-the-wire enumeration of a frame type is valid 427 // for a given protocol version, false otherwise. 428 static bool IsValidFrameType(SpdyMajorVersion version, int frame_type_field); 429 430 // Parses a frame type from an on-the-wire enumeration of a given protocol 431 // version. 432 // Behavior is undefined for invalid frame type fields; consumers should first 433 // use IsValidFrameType() to verify validity of frame type fields. 434 static SpdyFrameType ParseFrameType(SpdyMajorVersion version, 435 int frame_type_field); 436 437 // Serializes a given frame type to the on-the-wire enumeration value for the 438 // given protocol version. 439 // Returns -1 on failure (I.E. Invalid frame type for the given version). 440 static int SerializeFrameType(SpdyMajorVersion version, 441 SpdyFrameType frame_type); 442 443 // Returns true if a given on-the-wire enumeration of a setting id is valid 444 // for a given protocol version, false otherwise. 445 static bool IsValidSettingId(SpdyMajorVersion version, int setting_id_field); 446 447 // Parses a setting id from an on-the-wire enumeration of a given protocol 448 // version. 449 // Behavior is undefined for invalid setting id fields; consumers should first 450 // use IsValidSettingId() to verify validity of setting id fields. 451 static SpdySettingsIds ParseSettingId(SpdyMajorVersion version, 452 int setting_id_field); 453 454 // Serializes a given setting id to the on-the-wire enumeration value for the 455 // given protocol version. 456 // Returns -1 on failure (I.E. Invalid setting id for the given version). 457 static int SerializeSettingId(SpdyMajorVersion version, SpdySettingsIds id); 458 459 // Returns true if a given on-the-wire enumeration of a RST_STREAM status code 460 // is valid for a given protocol version, false otherwise. 461 static bool IsValidRstStreamStatus(SpdyMajorVersion version, 462 int rst_stream_status_field); 463 464 // Parses a RST_STREAM status code from an on-the-wire enumeration of a given 465 // protocol version. 466 // Behavior is undefined for invalid RST_STREAM status code fields; consumers 467 // should first use IsValidRstStreamStatus() to verify validity of RST_STREAM 468 // status code fields.. 469 static SpdyRstStreamStatus ParseRstStreamStatus(SpdyMajorVersion version, 470 int rst_stream_status_field); 471 472 // Serializes a given RST_STREAM status code to the on-the-wire enumeration 473 // value for the given protocol version. 474 // Returns -1 on failure (I.E. Invalid RST_STREAM status code for the given 475 // version). 476 static int SerializeRstStreamStatus(SpdyMajorVersion version, 477 SpdyRstStreamStatus rst_stream_status); 478 479 // Returns true if a given on-the-wire enumeration of a GOAWAY status code is 480 // valid for the given protocol version, false otherwise. 481 static bool IsValidGoAwayStatus(SpdyMajorVersion version, 482 int goaway_status_field); 483 484 // Parses a GOAWAY status from an on-the-wire enumeration of a given protocol 485 // version. 486 // Behavior is undefined for invalid GOAWAY status fields; consumers should 487 // first use IsValidGoAwayStatus() to verify validity of GOAWAY status fields. 488 static SpdyGoAwayStatus ParseGoAwayStatus(SpdyMajorVersion version, 489 int goaway_status_field); 490 491 // Serializes a given GOAWAY status to the on-the-wire enumeration value for 492 // the given protocol version. 493 // Returns -1 on failure (I.E. Invalid GOAWAY status for the given version). 494 static int SerializeGoAwayStatus(SpdyMajorVersion version, 495 SpdyGoAwayStatus status); 496 497 // Size, in bytes, of the data frame header. Future versions of SPDY 498 // will likely vary this, so we allow for the flexibility of a function call 499 // for this value as opposed to a constant. 500 static size_t GetDataFrameMinimumSize(); 501 502 // Size, in bytes, of the control frame header. 503 static size_t GetControlFrameHeaderSize(SpdyMajorVersion version); 504 505 static size_t GetPrefixLength(SpdyFrameType type, SpdyMajorVersion version); 506 507 static size_t GetFrameMaximumSize(SpdyMajorVersion version); 508 509 // Returns the size of a header block size field. Valid only for SPDY 510 // versions <= 3. 511 static size_t GetSizeOfSizeField(SpdyMajorVersion version); 512 513 static SpdyMajorVersion ParseMajorVersion(int version_number); 514 515 static int SerializeMajorVersion(SpdyMajorVersion version); 516 517 static std::string GetVersionString(SpdyMajorVersion version); 518 }; 519 520 class SpdyFrame; 521 typedef SpdyFrame SpdySerializedFrame; 522 523 class SpdyFrameVisitor; 524 525 // Intermediate representation for SPDY frames. 526 // TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is 527 // gone. 528 class NET_EXPORT_PRIVATE SpdyFrameIR { 529 public: ~SpdyFrameIR()530 virtual ~SpdyFrameIR() {} 531 532 virtual void Visit(SpdyFrameVisitor* visitor) const = 0; 533 534 protected: SpdyFrameIR()535 SpdyFrameIR() {} 536 537 private: 538 DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR); 539 }; 540 541 // Abstract class intended to be inherited by IRs that have a stream associated 542 // to them. 543 class NET_EXPORT_PRIVATE SpdyFrameWithStreamIdIR : public SpdyFrameIR { 544 public: ~SpdyFrameWithStreamIdIR()545 virtual ~SpdyFrameWithStreamIdIR() {} stream_id()546 SpdyStreamId stream_id() const { return stream_id_; } set_stream_id(SpdyStreamId stream_id)547 void set_stream_id(SpdyStreamId stream_id) { 548 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 549 stream_id_ = stream_id; 550 } 551 552 protected: SpdyFrameWithStreamIdIR(SpdyStreamId stream_id)553 explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) { 554 set_stream_id(stream_id); 555 } 556 557 private: 558 SpdyStreamId stream_id_; 559 560 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR); 561 }; 562 563 // Abstract class intended to be inherited by IRs that have the option of a FIN 564 // flag. Implies SpdyFrameWithStreamIdIR. 565 class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR { 566 public: ~SpdyFrameWithFinIR()567 virtual ~SpdyFrameWithFinIR() {} fin()568 bool fin() const { return fin_; } set_fin(bool fin)569 void set_fin(bool fin) { fin_ = fin; } 570 571 protected: SpdyFrameWithFinIR(SpdyStreamId stream_id)572 explicit SpdyFrameWithFinIR(SpdyStreamId stream_id) 573 : SpdyFrameWithStreamIdIR(stream_id), 574 fin_(false) {} 575 576 private: 577 bool fin_; 578 579 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR); 580 }; 581 582 // Abstract class intended to be inherited by IRs that contain a name-value 583 // block. Implies SpdyFrameWithFinIR. 584 class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR NON_EXPORTED_BASE(SpdyFrameWithFinIR)585 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { 586 public: 587 const SpdyNameValueBlock& name_value_block() const { 588 return name_value_block_; 589 } 590 void set_name_value_block(const SpdyNameValueBlock& name_value_block) { 591 // Deep copy. 592 name_value_block_ = name_value_block; 593 } 594 void SetHeader(const base::StringPiece& name, 595 const base::StringPiece& value) { 596 name_value_block_[name.as_string()] = value.as_string(); 597 } 598 SpdyNameValueBlock* mutable_name_value_block() { 599 return &name_value_block_; 600 } 601 602 protected: 603 explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id); 604 virtual ~SpdyFrameWithNameValueBlockIR(); 605 606 private: 607 SpdyNameValueBlock name_value_block_; 608 609 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR); 610 }; 611 612 class NET_EXPORT_PRIVATE SpdyDataIR NON_EXPORTED_BASE(SpdyFrameWithFinIR)613 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { 614 public: 615 // Performs deep copy on data. 616 SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data); 617 618 // Use in conjunction with SetDataShallow() for shallow-copy on data. 619 explicit SpdyDataIR(SpdyStreamId stream_id); 620 621 virtual ~SpdyDataIR(); 622 623 base::StringPiece data() const { return data_; } 624 625 bool pad_low() const { return pad_low_; } 626 627 bool pad_high() const { return pad_high_; } 628 629 int padding_payload_len() const { return padding_payload_len_; } 630 631 void set_padding_len(int padding_len) { 632 // The padding_len should be in (0, 65535 + 2]. 633 // Note that SpdyFramer::GetDataFrameMaximumPayload() enforces the overall 634 // payload size later so we actually can't pad more than 16375 bytes. 635 DCHECK_GT(padding_len, 0); 636 DCHECK_LT(padding_len, 65537); 637 638 if (padding_len <= 256) { 639 pad_low_ = true; 640 --padding_len; 641 } else { 642 pad_low_ = pad_high_ = true; 643 padding_len -= 2; 644 } 645 padding_payload_len_ = padding_len; 646 } 647 648 // Deep-copy of data (keep private copy). 649 void SetDataDeep(const base::StringPiece& data) { 650 data_store_.reset(new std::string(data.data(), data.length())); 651 data_ = *(data_store_.get()); 652 } 653 654 // Shallow-copy of data (do not keep private copy). 655 void SetDataShallow(const base::StringPiece& data) { 656 data_store_.reset(); 657 data_ = data; 658 } 659 660 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 661 662 private: 663 // Used to store data that this SpdyDataIR should own. 664 scoped_ptr<std::string> data_store_; 665 base::StringPiece data_; 666 667 bool pad_low_; 668 bool pad_high_; 669 // padding_payload_len_ = desired padding length - len(padding length field). 670 int padding_payload_len_; 671 672 DISALLOW_COPY_AND_ASSIGN(SpdyDataIR); 673 }; 674 675 class NET_EXPORT_PRIVATE SpdySynStreamIR 676 : public SpdyFrameWithNameValueBlockIR { 677 public: SpdySynStreamIR(SpdyStreamId stream_id)678 explicit SpdySynStreamIR(SpdyStreamId stream_id) 679 : SpdyFrameWithNameValueBlockIR(stream_id), 680 associated_to_stream_id_(0), 681 priority_(0), 682 unidirectional_(false) {} associated_to_stream_id()683 SpdyStreamId associated_to_stream_id() const { 684 return associated_to_stream_id_; 685 } set_associated_to_stream_id(SpdyStreamId stream_id)686 void set_associated_to_stream_id(SpdyStreamId stream_id) { 687 associated_to_stream_id_ = stream_id; 688 } priority()689 SpdyPriority priority() const { return priority_; } set_priority(SpdyPriority priority)690 void set_priority(SpdyPriority priority) { priority_ = priority; } unidirectional()691 bool unidirectional() const { return unidirectional_; } set_unidirectional(bool unidirectional)692 void set_unidirectional(bool unidirectional) { 693 unidirectional_ = unidirectional; 694 } 695 696 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 697 698 private: 699 SpdyStreamId associated_to_stream_id_; 700 SpdyPriority priority_; 701 bool unidirectional_; 702 703 DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR); 704 }; 705 706 class NET_EXPORT_PRIVATE SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR { 707 public: SpdySynReplyIR(SpdyStreamId stream_id)708 explicit SpdySynReplyIR(SpdyStreamId stream_id) 709 : SpdyFrameWithNameValueBlockIR(stream_id) {} 710 711 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 712 713 private: 714 DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR); 715 }; 716 717 class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR { 718 public: 719 SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status, 720 base::StringPiece description); 721 722 virtual ~SpdyRstStreamIR(); 723 status()724 SpdyRstStreamStatus status() const { 725 return status_; 726 } set_status(SpdyRstStreamStatus status)727 void set_status(SpdyRstStreamStatus status) { 728 status_ = status; 729 } 730 description()731 base::StringPiece description() const { return description_; } 732 set_description(base::StringPiece description)733 void set_description(base::StringPiece description) { 734 description_ = description; 735 } 736 737 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 738 739 private: 740 SpdyRstStreamStatus status_; 741 base::StringPiece description_; 742 743 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR); 744 }; 745 746 class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR { 747 public: 748 // Associates flags with a value. 749 struct Value { ValueValue750 Value() : persist_value(false), 751 persisted(false), 752 value(0) {} 753 bool persist_value; 754 bool persisted; 755 int32 value; 756 }; 757 typedef std::map<SpdySettingsIds, Value> ValueMap; 758 759 SpdySettingsIR(); 760 761 virtual ~SpdySettingsIR(); 762 763 // Overwrites as appropriate. values()764 const ValueMap& values() const { return values_; } AddSetting(SpdySettingsIds id,bool persist_value,bool persisted,int32 value)765 void AddSetting(SpdySettingsIds id, 766 bool persist_value, 767 bool persisted, 768 int32 value) { 769 values_[id].persist_value = persist_value; 770 values_[id].persisted = persisted; 771 values_[id].value = value; 772 } 773 clear_settings()774 bool clear_settings() const { return clear_settings_; } set_clear_settings(bool clear_settings)775 void set_clear_settings(bool clear_settings) { 776 clear_settings_ = clear_settings; 777 } is_ack()778 bool is_ack() const { return is_ack_; } set_is_ack(bool is_ack)779 void set_is_ack(bool is_ack) { 780 is_ack_ = is_ack; 781 } 782 783 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 784 785 private: 786 ValueMap values_; 787 bool clear_settings_; 788 bool is_ack_; 789 790 DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR); 791 }; 792 793 class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR { 794 public: SpdyPingIR(SpdyPingId id)795 explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {} id()796 SpdyPingId id() const { return id_; } 797 798 // ACK logic is valid only for SPDY versions 4 and above. is_ack()799 bool is_ack() const { return is_ack_; } set_is_ack(bool is_ack)800 void set_is_ack(bool is_ack) { is_ack_ = is_ack; } 801 802 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 803 804 private: 805 SpdyPingId id_; 806 bool is_ack_; 807 808 DISALLOW_COPY_AND_ASSIGN(SpdyPingIR); 809 }; 810 811 class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR { 812 public: 813 SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status, 814 const base::StringPiece& description); 815 virtual ~SpdyGoAwayIR(); last_good_stream_id()816 SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; } set_last_good_stream_id(SpdyStreamId last_good_stream_id)817 void set_last_good_stream_id(SpdyStreamId last_good_stream_id) { 818 DCHECK_LE(0u, last_good_stream_id); 819 DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask); 820 last_good_stream_id_ = last_good_stream_id; 821 } status()822 SpdyGoAwayStatus status() const { return status_; } set_status(SpdyGoAwayStatus status)823 void set_status(SpdyGoAwayStatus status) { 824 // TODO(hkhalil): Check valid ranges of status? 825 status_ = status; 826 } 827 828 const base::StringPiece& description() const; 829 830 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 831 832 private: 833 SpdyStreamId last_good_stream_id_; 834 SpdyGoAwayStatus status_; 835 const base::StringPiece description_; 836 837 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR); 838 }; 839 840 class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR { 841 public: SpdyHeadersIR(SpdyStreamId stream_id)842 explicit SpdyHeadersIR(SpdyStreamId stream_id) 843 : SpdyFrameWithNameValueBlockIR(stream_id), 844 has_priority_(false), 845 priority_(0) {} 846 847 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 848 has_priority()849 bool has_priority() const { return has_priority_; } set_has_priority(bool has_priority)850 void set_has_priority(bool has_priority) { has_priority_ = has_priority; } priority()851 uint32 priority() const { return priority_; } set_priority(SpdyPriority priority)852 void set_priority(SpdyPriority priority) { priority_ = priority; } 853 854 private: 855 bool has_priority_; 856 // 31-bit priority. 857 uint32 priority_; 858 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR); 859 }; 860 861 class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR { 862 public: SpdyWindowUpdateIR(SpdyStreamId stream_id,int32 delta)863 SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta) 864 : SpdyFrameWithStreamIdIR(stream_id) { 865 set_delta(delta); 866 } delta()867 int32 delta() const { return delta_; } set_delta(int32 delta)868 void set_delta(int32 delta) { 869 DCHECK_LT(0, delta); 870 DCHECK_LE(delta, kSpdyMaximumWindowSize); 871 delta_ = delta; 872 } 873 874 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 875 876 private: 877 int32 delta_; 878 879 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR); 880 }; 881 882 class NET_EXPORT_PRIVATE SpdyBlockedIR NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR)883 : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR) { 884 public: 885 explicit SpdyBlockedIR(SpdyStreamId stream_id) 886 : SpdyFrameWithStreamIdIR(stream_id) {} 887 888 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 889 890 private: 891 DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR); 892 }; 893 894 class NET_EXPORT_PRIVATE SpdyPushPromiseIR 895 : public SpdyFrameWithNameValueBlockIR { 896 public: SpdyPushPromiseIR(SpdyStreamId stream_id,SpdyStreamId promised_stream_id)897 SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id) 898 : SpdyFrameWithNameValueBlockIR(stream_id), 899 promised_stream_id_(promised_stream_id) {} promised_stream_id()900 SpdyStreamId promised_stream_id() const { return promised_stream_id_; } set_promised_stream_id(SpdyStreamId id)901 void set_promised_stream_id(SpdyStreamId id) { promised_stream_id_ = id; } 902 903 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 904 905 private: 906 SpdyStreamId promised_stream_id_; 907 DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR); 908 }; 909 910 // TODO(jgraettinger): This representation needs review. SpdyContinuationIR 911 // needs to frame a portion of a single, arbitrarily-broken encoded buffer. 912 class NET_EXPORT_PRIVATE SpdyContinuationIR 913 : public SpdyFrameWithNameValueBlockIR { 914 public: SpdyContinuationIR(SpdyStreamId stream_id)915 explicit SpdyContinuationIR(SpdyStreamId stream_id) 916 : SpdyFrameWithNameValueBlockIR(stream_id), 917 end_headers_(false) {} 918 919 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 920 end_headers()921 bool end_headers() const { return end_headers_; } set_end_headers(bool end_headers)922 void set_end_headers(bool end_headers) {end_headers_ = end_headers;} 923 924 private: 925 bool end_headers_; 926 DISALLOW_COPY_AND_ASSIGN(SpdyContinuationIR); 927 }; 928 929 class NET_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameWithStreamIdIR { 930 public: 931 explicit SpdyAltSvcIR(SpdyStreamId stream_id); 932 max_age()933 uint32 max_age() const { return max_age_; } port()934 uint16 port() const { return port_; } protocol_id()935 SpdyProtocolId protocol_id() const { 936 return protocol_id_; 937 } host()938 std::string host() const { return host_; } origin()939 std::string origin() const { return origin_; } 940 set_max_age(uint32 max_age)941 void set_max_age(uint32 max_age) { max_age_ = max_age; } set_port(uint16 port)942 void set_port(uint16 port) { port_ = port; } set_protocol_id(SpdyProtocolId protocol_id)943 void set_protocol_id(SpdyProtocolId protocol_id) { 944 protocol_id_ = protocol_id; 945 } set_host(std::string host)946 void set_host(std::string host) { 947 host_ = host; 948 } set_origin(std::string origin)949 void set_origin(std::string origin) { 950 origin_ = origin; 951 } 952 953 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 954 955 private: 956 uint32 max_age_; 957 uint16 port_; 958 SpdyProtocolId protocol_id_; 959 std::string host_; 960 std::string origin_; 961 DISALLOW_COPY_AND_ASSIGN(SpdyAltSvcIR); 962 }; 963 964 // ------------------------------------------------------------------------- 965 // Wrapper classes for various SPDY frames. 966 967 // All Spdy Frame types derive from this SpdyFrame class. 968 class SpdyFrame { 969 public: 970 // Create a SpdyFrame using a pre-created buffer. 971 // If |owns_buffer| is true, this class takes ownership of the buffer 972 // and will delete it on cleanup. The buffer must have been created using 973 // new char[]. 974 // If |owns_buffer| is false, the caller retains ownership of the buffer and 975 // is responsible for making sure the buffer outlives this frame. In other 976 // words, this class does NOT create a copy of the buffer. SpdyFrame(char * data,size_t size,bool owns_buffer)977 SpdyFrame(char* data, size_t size, bool owns_buffer) 978 : frame_(data), 979 size_(size), 980 owns_buffer_(owns_buffer) { 981 DCHECK(frame_); 982 } 983 ~SpdyFrame()984 ~SpdyFrame() { 985 if (owns_buffer_) { 986 delete [] frame_; 987 } 988 frame_ = NULL; 989 } 990 991 // Provides access to the frame bytes, which is a buffer containing 992 // the frame packed as expected for sending over the wire. data()993 char* data() const { return frame_; } 994 995 // Returns the actual size of the underlying buffer. size()996 size_t size() const { return size_; } 997 998 protected: 999 char* frame_; 1000 1001 private: 1002 size_t size_; 1003 bool owns_buffer_; 1004 DISALLOW_COPY_AND_ASSIGN(SpdyFrame); 1005 }; 1006 1007 // This interface is for classes that want to process SpdyFrameIRs without 1008 // having to know what type they are. An instance of this interface can be 1009 // passed to a SpdyFrameIR's Visit method, and the appropriate type-specific 1010 // method of this class will be called. 1011 class SpdyFrameVisitor { 1012 public: 1013 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) = 0; 1014 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) = 0; 1015 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0; 1016 virtual void VisitSettings(const SpdySettingsIR& settings) = 0; 1017 virtual void VisitPing(const SpdyPingIR& ping) = 0; 1018 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0; 1019 virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0; 1020 virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0; 1021 virtual void VisitBlocked(const SpdyBlockedIR& blocked) = 0; 1022 virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0; 1023 virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0; 1024 virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) = 0; 1025 virtual void VisitData(const SpdyDataIR& data) = 0; 1026 1027 protected: SpdyFrameVisitor()1028 SpdyFrameVisitor() {} ~SpdyFrameVisitor()1029 virtual ~SpdyFrameVisitor() {} 1030 1031 private: 1032 DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor); 1033 }; 1034 1035 } // namespace net 1036 1037 #endif // NET_SPDY_SPDY_PROTOCOL_H_ 1038