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