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 |