Enables compositing support for webview.
[chromium-blink-merge.git] / net / spdy / spdy_protocol.h
blob7f2521cfc5f35acb02eec5bacd4c5c8f65d8af23
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.
5 // This file contains some protocol structures for use with Spdy.
7 #ifndef NET_SPDY_SPDY_PROTOCOL_H_
8 #define NET_SPDY_SPDY_PROTOCOL_H_
10 #include <limits>
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/sys_byteorder.h"
15 #include "net/spdy/spdy_bitmasks.h"
17 // Data Frame Format
18 // +----------------------------------+
19 // |0| Stream-ID (31bits) |
20 // +----------------------------------+
21 // | flags (8) | Length (24 bits) |
22 // +----------------------------------+
23 // | Data |
24 // +----------------------------------+
26 // Control Frame Format
27 // +----------------------------------+
28 // |1| Version(15bits) | Type(16bits) |
29 // +----------------------------------+
30 // | flags (8) | Length (24 bits) |
31 // +----------------------------------+
32 // | Data |
33 // +----------------------------------+
35 // Control Frame: SYN_STREAM
36 // +----------------------------------+
37 // |1|000000000000001|0000000000000001|
38 // +----------------------------------+
39 // | flags (8) | Length (24 bits) | >= 12
40 // +----------------------------------+
41 // |X| Stream-ID(31bits) |
42 // +----------------------------------+
43 // |X|Associated-To-Stream-ID (31bits)|
44 // +----------------------------------+
45 // |Pri| unused | Length (16bits)|
46 // +----------------------------------+
48 // Control Frame: SYN_REPLY
49 // +----------------------------------+
50 // |1|000000000000001|0000000000000010|
51 // +----------------------------------+
52 // | flags (8) | Length (24 bits) | >= 8
53 // +----------------------------------+
54 // |X| Stream-ID(31bits) |
55 // +----------------------------------+
56 // | unused (16 bits)| Length (16bits)|
57 // +----------------------------------+
59 // Control Frame: RST_STREAM
60 // +----------------------------------+
61 // |1|000000000000001|0000000000000011|
62 // +----------------------------------+
63 // | flags (8) | Length (24 bits) | >= 4
64 // +----------------------------------+
65 // |X| Stream-ID(31bits) |
66 // +----------------------------------+
67 // | Status code (32 bits) |
68 // +----------------------------------+
70 // Control Frame: SETTINGS
71 // +----------------------------------+
72 // |1|000000000000001|0000000000000100|
73 // +----------------------------------+
74 // | flags (8) | Length (24 bits) |
75 // +----------------------------------+
76 // | # of entries (32) |
77 // +----------------------------------+
79 // Control Frame: NOOP
80 // +----------------------------------+
81 // |1|000000000000001|0000000000000101|
82 // +----------------------------------+
83 // | flags (8) | Length (24 bits) | = 0
84 // +----------------------------------+
86 // Control Frame: PING
87 // +----------------------------------+
88 // |1|000000000000001|0000000000000110|
89 // +----------------------------------+
90 // | flags (8) | Length (24 bits) | = 4
91 // +----------------------------------+
92 // | Unique id (32 bits) |
93 // +----------------------------------+
95 // Control Frame: GOAWAY
96 // +----------------------------------+
97 // |1|000000000000001|0000000000000111|
98 // +----------------------------------+
99 // | flags (8) | Length (24 bits) | = 4
100 // +----------------------------------+
101 // |X| Last-accepted-stream-id |
102 // +----------------------------------+
104 // Control Frame: HEADERS
105 // +----------------------------------+
106 // |1|000000000000001|0000000000001000|
107 // +----------------------------------+
108 // | flags (8) | Length (24 bits) | >= 8
109 // +----------------------------------+
110 // |X| Stream-ID (31 bits) |
111 // +----------------------------------+
112 // | unused (16 bits)| Length (16bits)|
113 // +----------------------------------+
115 // Control Frame: WINDOW_UPDATE
116 // +----------------------------------+
117 // |1|000000000000001|0000000000001001|
118 // +----------------------------------+
119 // | flags (8) | Length (24 bits) | = 8
120 // +----------------------------------+
121 // |X| Stream-ID (31 bits) |
122 // +----------------------------------+
123 // | Delta-Window-Size (32 bits) |
124 // +----------------------------------+
126 // Control Frame: CREDENTIAL
127 // +----------------------------------+
128 // |1|000000000000001|0000000000001010|
129 // +----------------------------------+
130 // | flags (8) | Length (24 bits) | >= 12
131 // +----------------------------------+
132 // | Slot (16 bits) | |
133 // +-----------------+ |
134 // | Proof Length (32 bits) |
135 // +----------------------------------+
136 // | Proof |
137 // +----------------------------------+ <+
138 // | Certificate Length (32 bits) | |
139 // +----------------------------------+ | Repeated until end of frame
140 // | Certificate | |
141 // +----------------------------------+ <+
144 namespace net {
146 // Initial window size for a Spdy stream
147 const int32 kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes
149 // Maximum window size for a Spdy stream
150 const int32 kSpdyStreamMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int
152 // SPDY 2 dictionary.
153 // This is just a hacked dictionary to use for shrinking HTTP-like headers.
154 const char kV2Dictionary[] =
155 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
156 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
157 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
158 "-agent10010120020120220320420520630030130230330430530630740040140240340440"
159 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
160 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
161 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
162 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
163 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
164 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
165 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
166 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
167 ".1statusversionurl";
168 const int kV2DictionarySize = arraysize(kV2Dictionary);
170 // SPDY 3 dictionary.
171 const char kV3Dictionary[] = {
172 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti
173 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h
174 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p
175 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p
176 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de
177 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete....
178 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace...
179 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept.
180 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
181 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse
182 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc
183 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco
184 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding....
185 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l
186 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage.
187 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
188 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges
189 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age.
190 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow
191 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth
192 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio
193 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac
194 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr
195 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co
196 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection
197 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont
198 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base
199 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont
200 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco
201 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding....
202 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content-
203 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language
204 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont
205 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng
206 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co
207 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo
208 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation..
209 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
210 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5...
211 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content
212 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range..
213 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
214 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type..
215 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date..
216 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag..
217 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect
218 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi
219 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f
220 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h
221 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i
222 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match.
223 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo
224 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s
225 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince....
226 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none-
227 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match...
228 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang
229 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if-
230 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi
231 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since
232 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last
233 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie
234 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc
235 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation...
236 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for
237 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards...
238 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma.
239 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy
240 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent
241 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate...
242 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a
243 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza
244 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion....
245 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range...
246 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer
247 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr
248 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after.
249 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve
250 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te.
251 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail
252 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr
253 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e
254 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding.
255 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra
256 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us
257 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent
258 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary
259 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via.
260 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni
261 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww
262 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen
263 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate..
264 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method
265 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get.
266 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu
267 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200
268 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v
269 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion..
270 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1
271 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur
272 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub
273 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s
274 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki
275 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee
276 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive.
277 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi
278 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012
279 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205
280 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030
281 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043
282 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307
283 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540
284 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084
285 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411
286 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341
287 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164
288 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504
289 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N
290 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho
291 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative
292 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa
293 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204.
294 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte
295 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo
296 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm
297 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4
298 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R
299 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40
300 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth
301 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40
302 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid
303 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N
304 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found
305 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte
306 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser
307 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro
308 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not
309 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme
310 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503.
311 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service.
312 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila
313 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F
314 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A
315 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J
316 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A
317 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept.
318 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov.
319 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0
320 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon
321 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W
322 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu.
323 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa
324 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun..
325 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk
326 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text.
327 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima
328 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i
329 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg
330 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g
331 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli
332 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
333 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli
334 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
335 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml
336 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl
337 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text
338 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr
339 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ
340 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat
341 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age
342 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de
343 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd
344 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse
345 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c
346 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i
347 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859-
348 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-..
349 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0.
351 const int kV3DictionarySize = arraysize(kV3Dictionary);
353 // Note: all protocol data structures are on-the-wire format. That means that
354 // data is stored in network-normalized order. Readers must use the
355 // accessors provided or call ntohX() functions.
357 // Types of Spdy Control Frames.
358 enum SpdyControlType {
359 SYN_STREAM = 1,
360 SYN_REPLY,
361 RST_STREAM,
362 SETTINGS,
363 NOOP, // Because it is valid in SPDY/2, kept for identifiability/enum order.
364 PING,
365 GOAWAY,
366 HEADERS,
367 WINDOW_UPDATE,
368 CREDENTIAL,
369 NUM_CONTROL_FRAME_TYPES
372 // Flags on data packets.
373 enum SpdyDataFlags {
374 DATA_FLAG_NONE = 0,
375 DATA_FLAG_FIN = 1,
378 // Flags on control packets
379 enum SpdyControlFlags {
380 CONTROL_FLAG_NONE = 0,
381 CONTROL_FLAG_FIN = 1,
382 CONTROL_FLAG_UNIDIRECTIONAL = 2
385 // Flags on the SETTINGS control frame.
386 enum SpdySettingsControlFlags {
387 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1
390 // Flags for settings within a SETTINGS frame.
391 enum SpdySettingsFlags {
392 SETTINGS_FLAG_NONE = 0x0,
393 SETTINGS_FLAG_PLEASE_PERSIST = 0x1,
394 SETTINGS_FLAG_PERSISTED = 0x2
397 // List of known settings.
398 enum SpdySettingsIds {
399 SETTINGS_UPLOAD_BANDWIDTH = 0x1,
400 SETTINGS_DOWNLOAD_BANDWIDTH = 0x2,
401 // Network round trip time in milliseconds.
402 SETTINGS_ROUND_TRIP_TIME = 0x3,
403 SETTINGS_MAX_CONCURRENT_STREAMS = 0x4,
404 // TCP congestion window in packets.
405 SETTINGS_CURRENT_CWND = 0x5,
406 // Downstream byte retransmission rate in percentage.
407 SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6,
408 // Initial window size in bytes
409 SETTINGS_INITIAL_WINDOW_SIZE = 0x7
412 // Status codes, as used in control frames (primarily RST_STREAM).
413 // TODO(hkhalil): Rename to SpdyRstStreamStatus
414 enum SpdyStatusCodes {
415 INVALID = 0,
416 PROTOCOL_ERROR = 1,
417 INVALID_STREAM = 2,
418 REFUSED_STREAM = 3,
419 UNSUPPORTED_VERSION = 4,
420 CANCEL = 5,
421 INTERNAL_ERROR = 6,
422 FLOW_CONTROL_ERROR = 7,
423 STREAM_IN_USE = 8,
424 STREAM_ALREADY_CLOSED = 9,
425 INVALID_CREDENTIALS = 10,
426 FRAME_TOO_LARGE = 11,
427 NUM_STATUS_CODES = 12
430 enum SpdyGoAwayStatus {
431 GOAWAY_INVALID = -1,
432 GOAWAY_OK = 0,
433 GOAWAY_PROTOCOL_ERROR = 1,
434 GOAWAY_INTERNAL_ERROR = 2,
435 GOAWAY_NUM_STATUS_CODES = 3
438 // A SPDY stream id is a 31 bit entity.
439 typedef uint32 SpdyStreamId;
441 // A SPDY priority is a number between 0 and 7 (inclusive).
442 // SPDY priority range is version-dependant. For SPDY 2 and below, priority is a
443 // number between 0 and 3.
444 typedef uint8 SpdyPriority;
446 // -------------------------------------------------------------------------
447 // These structures mirror the protocol structure definitions.
449 // For the control data structures, we pack so that sizes match the
450 // protocol over-the-wire sizes.
451 #pragma pack(push)
452 #pragma pack(1)
454 // A special structure for the 8 bit flags and 24 bit length fields.
455 union FlagsAndLength {
456 uint8 flags_[4]; // 8 bits
457 uint32 length_; // 24 bits
460 // The basic SPDY Frame structure.
461 struct SpdyFrameBlock {
462 union {
463 struct {
464 uint16 version_;
465 uint16 type_;
466 } control_;
467 struct {
468 SpdyStreamId stream_id_;
469 } data_;
471 FlagsAndLength flags_length_;
474 // A SYN_STREAM Control Frame structure.
475 struct SpdySynStreamControlFrameBlock : SpdyFrameBlock {
476 SpdyStreamId stream_id_;
477 SpdyStreamId associated_stream_id_;
478 SpdyPriority priority_;
479 uint8 credential_slot_;
482 // A SYN_REPLY Control Frame structure.
483 struct SpdySynReplyControlFrameBlock : SpdyFrameBlock {
484 SpdyStreamId stream_id_;
487 // A RST_STREAM Control Frame structure.
488 struct SpdyRstStreamControlFrameBlock : SpdyFrameBlock {
489 SpdyStreamId stream_id_;
490 uint32 status_;
493 // A SETTINGS Control Frame structure.
494 struct SpdySettingsControlFrameBlock : SpdyFrameBlock {
495 uint32 num_entries_;
496 // Variable data here.
499 // A PING Control Frame structure.
500 struct SpdyPingControlFrameBlock : SpdyFrameBlock {
501 uint32 unique_id_;
504 // TODO(avd): remove this struct
505 // A CREDENTIAL Control Frame structure.
506 struct SpdyCredentialControlFrameBlock : SpdyFrameBlock {
507 uint16 slot_;
508 uint32 proof_len_;
509 // Variable data here.
510 // proof data
511 // for each certificate: unit32 certificate_len + certificate_data[i]
514 // A GOAWAY Control Frame structure.
515 struct SpdyGoAwayControlFrameBlock : SpdyFrameBlock {
516 SpdyStreamId last_accepted_stream_id_;
517 SpdyGoAwayStatus status_;
520 // A HEADERS Control Frame structure.
521 struct SpdyHeadersControlFrameBlock : SpdyFrameBlock {
522 SpdyStreamId stream_id_;
525 // A WINDOW_UPDATE Control Frame structure
526 struct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock {
527 SpdyStreamId stream_id_;
528 uint32 delta_window_size_;
531 #pragma pack(pop)
533 // -------------------------------------------------------------------------
534 // Wrapper classes for various SPDY frames.
536 // All Spdy Frame types derive from this SpdyFrame class.
537 class SpdyFrame {
538 public:
539 // Create a SpdyFrame for a given sized buffer.
540 explicit SpdyFrame(size_t size) : frame_(NULL), owns_buffer_(true) {
541 DCHECK_GE(size, sizeof(struct SpdyFrameBlock));
542 char* buffer = new char[size];
543 memset(buffer, 0, size);
544 frame_ = reinterpret_cast<struct SpdyFrameBlock*>(buffer);
547 // Create a SpdyFrame using a pre-created buffer.
548 // If |owns_buffer| is true, this class takes ownership of the buffer
549 // and will delete it on cleanup. The buffer must have been created using
550 // new char[].
551 // If |owns_buffer| is false, the caller retains ownership of the buffer and
552 // is responsible for making sure the buffer outlives this frame. In other
553 // words, this class does NOT create a copy of the buffer.
554 SpdyFrame(char* data, bool owns_buffer)
555 : frame_(reinterpret_cast<struct SpdyFrameBlock*>(data)),
556 owns_buffer_(owns_buffer) {
557 DCHECK(frame_);
560 ~SpdyFrame() {
561 if (owns_buffer_) {
562 char* buffer = reinterpret_cast<char*>(frame_);
563 delete [] buffer;
565 frame_ = NULL;
568 // Provides access to the frame bytes, which is a buffer containing
569 // the frame packed as expected for sending over the wire.
570 char* data() const { return reinterpret_cast<char*>(frame_); }
572 uint8 flags() const { return frame_->flags_length_.flags_[0]; }
573 void set_flags(uint8 flags) { frame_->flags_length_.flags_[0] = flags; }
575 uint32 length() const {
576 return ntohl(frame_->flags_length_.length_) & kLengthMask;
579 void set_length(uint32 length) {
580 DCHECK_EQ(0u, (length & ~kLengthMask));
581 length = htonl(length & kLengthMask);
582 frame_->flags_length_.length_ = flags() | length;
585 bool is_control_frame() const {
586 return (ntohs(frame_->control_.version_) & kControlFlagMask) ==
587 kControlFlagMask;
590 // The size of the SpdyFrameBlock structure.
591 // Every SpdyFrame* class has a static size() method for accessing
592 // the size of the data structure which will be sent over the wire.
593 // Note: this is not the same as sizeof(SpdyFrame).
594 enum { kHeaderSize = sizeof(struct SpdyFrameBlock) };
596 protected:
597 SpdyFrameBlock* frame_;
599 private:
600 bool owns_buffer_;
601 DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
604 // A Data Frame.
605 class SpdyDataFrame : public SpdyFrame {
606 public:
607 SpdyDataFrame() : SpdyFrame(size()) {}
608 SpdyDataFrame(char* data, bool owns_buffer)
609 : SpdyFrame(data, owns_buffer) {}
611 SpdyStreamId stream_id() const {
612 return ntohl(frame_->data_.stream_id_) & kStreamIdMask;
615 // Note that setting the stream id sets the control bit to false.
616 // As stream id should always be set, this means the control bit
617 // should always be set correctly.
618 void set_stream_id(SpdyStreamId id) {
619 DCHECK_EQ(0u, (id & ~kStreamIdMask));
620 frame_->data_.stream_id_ = htonl(id & kStreamIdMask);
623 // Returns the size of the SpdyFrameBlock structure.
624 // Note: this is not the size of the SpdyDataFrame class.
625 static size_t size() { return SpdyFrame::kHeaderSize; }
627 const char* payload() const {
628 return reinterpret_cast<const char*>(frame_) + size();
631 private:
632 DISALLOW_COPY_AND_ASSIGN(SpdyDataFrame);
635 // A Control Frame.
636 class SpdyControlFrame : public SpdyFrame {
637 public:
638 explicit SpdyControlFrame(size_t size) : SpdyFrame(size) {}
639 SpdyControlFrame(char* data, bool owns_buffer)
640 : SpdyFrame(data, owns_buffer) {}
642 // Callers can use this method to check if the frame appears to be a valid
643 // frame. Does not guarantee that there are no errors.
644 bool AppearsToBeAValidControlFrame() const {
645 // Right now we only check if the frame has an out-of-bounds type.
646 uint16 type = ntohs(block()->control_.type_);
647 // NOOP is not a 'valid' control frame in SPDY/3 and beyond.
648 return type >= SYN_STREAM &&
649 type < NUM_CONTROL_FRAME_TYPES &&
650 (version() == 2 || type != NOOP);
653 uint16 version() const {
654 const int kVersionMask = 0x7fff;
655 return ntohs(block()->control_.version_) & kVersionMask;
658 void set_version(uint16 version) {
659 const uint16 kControlBit = 0x80;
660 DCHECK_EQ(0, version & kControlBit);
661 mutable_block()->control_.version_ = kControlBit | htons(version);
664 SpdyControlType type() const {
665 uint16 type = ntohs(block()->control_.type_);
666 LOG_IF(DFATAL, type < SYN_STREAM || type >= NUM_CONTROL_FRAME_TYPES)
667 << "Invalid control frame type " << type;
668 return static_cast<SpdyControlType>(type);
671 void set_type(SpdyControlType type) {
672 DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES);
673 mutable_block()->control_.type_ = htons(type);
676 // Returns true if this control frame is of a type that has a header block,
677 // otherwise it returns false.
678 bool has_header_block() const {
679 return type() == SYN_STREAM || type() == SYN_REPLY || type() == HEADERS;
682 private:
683 const struct SpdyFrameBlock* block() const {
684 return frame_;
686 struct SpdyFrameBlock* mutable_block() {
687 return frame_;
689 DISALLOW_COPY_AND_ASSIGN(SpdyControlFrame);
692 // A SYN_STREAM frame.
693 class SpdySynStreamControlFrame : public SpdyControlFrame {
694 public:
695 SpdySynStreamControlFrame() : SpdyControlFrame(size()) {}
696 SpdySynStreamControlFrame(char* data, bool owns_buffer)
697 : SpdyControlFrame(data, owns_buffer) {}
699 SpdyStreamId stream_id() const {
700 return ntohl(block()->stream_id_) & kStreamIdMask;
703 void set_stream_id(SpdyStreamId id) {
704 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
707 SpdyStreamId associated_stream_id() const {
708 return ntohl(block()->associated_stream_id_) & kStreamIdMask;
711 void set_associated_stream_id(SpdyStreamId id) {
712 mutable_block()->associated_stream_id_ = htonl(id & kStreamIdMask);
715 SpdyPriority priority() const {
716 if (version() < 3) {
717 return (block()->priority_ & kSpdy2PriorityMask) >> 6;
718 } else {
719 return (block()->priority_ & kSpdy3PriorityMask) >> 5;
723 uint8 credential_slot() const {
724 if (version() < 3) {
725 return 0;
726 } else {
727 return block()->credential_slot_;
731 void set_credential_slot(uint8 credential_slot) {
732 DCHECK(version() >= 3);
733 mutable_block()->credential_slot_ = credential_slot;
736 // The number of bytes in the header block beyond the frame header length.
737 int header_block_len() const {
738 return length() - (size() - SpdyFrame::kHeaderSize);
741 const char* header_block() const {
742 return reinterpret_cast<const char*>(block()) + size();
745 // Returns the size of the SpdySynStreamControlFrameBlock structure.
746 // Note: this is not the size of the SpdySynStreamControlFrame class.
747 static size_t size() { return sizeof(SpdySynStreamControlFrameBlock); }
749 private:
750 const struct SpdySynStreamControlFrameBlock* block() const {
751 return static_cast<SpdySynStreamControlFrameBlock*>(frame_);
753 struct SpdySynStreamControlFrameBlock* mutable_block() {
754 return static_cast<SpdySynStreamControlFrameBlock*>(frame_);
756 DISALLOW_COPY_AND_ASSIGN(SpdySynStreamControlFrame);
759 // A SYN_REPLY frame.
760 class SpdySynReplyControlFrame : public SpdyControlFrame {
761 public:
762 SpdySynReplyControlFrame() : SpdyControlFrame(size()) {}
763 SpdySynReplyControlFrame(char* data, bool owns_buffer)
764 : SpdyControlFrame(data, owns_buffer) {}
766 SpdyStreamId stream_id() const {
767 return ntohl(block()->stream_id_) & kStreamIdMask;
770 void set_stream_id(SpdyStreamId id) {
771 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
774 int header_block_len() const {
775 size_t header_block_len = length() - (size() - SpdyFrame::kHeaderSize);
776 // SPDY 2 had 2 bytes of unused space preceeding the header block.
777 if (version() < 3) {
778 header_block_len -= 2;
780 return header_block_len;
783 const char* header_block() const {
784 const char* header_block = reinterpret_cast<const char*>(block()) + size();
785 // SPDY 2 had 2 bytes of unused space preceeding the header block.
786 if (version() < 3) {
787 header_block += 2;
789 return header_block;
792 // Returns the size of the SpdySynReplyControlFrameBlock structure.
793 // Note: this is not the size of the SpdySynReplyControlFrame class.
794 static size_t size() { return sizeof(SpdySynReplyControlFrameBlock); }
796 private:
797 const struct SpdySynReplyControlFrameBlock* block() const {
798 return static_cast<SpdySynReplyControlFrameBlock*>(frame_);
800 struct SpdySynReplyControlFrameBlock* mutable_block() {
801 return static_cast<SpdySynReplyControlFrameBlock*>(frame_);
803 DISALLOW_COPY_AND_ASSIGN(SpdySynReplyControlFrame);
806 // A RST_STREAM frame.
807 class SpdyRstStreamControlFrame : public SpdyControlFrame {
808 public:
809 SpdyRstStreamControlFrame() : SpdyControlFrame(size()) {}
810 SpdyRstStreamControlFrame(char* data, bool owns_buffer)
811 : SpdyControlFrame(data, owns_buffer) {}
813 SpdyStreamId stream_id() const {
814 return ntohl(block()->stream_id_) & kStreamIdMask;
817 void set_stream_id(SpdyStreamId id) {
818 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
821 SpdyStatusCodes status() const {
822 SpdyStatusCodes status =
823 static_cast<SpdyStatusCodes>(ntohl(block()->status_));
824 if (status < INVALID || status >= NUM_STATUS_CODES) {
825 status = INVALID;
827 return status;
829 void set_status(SpdyStatusCodes status) {
830 mutable_block()->status_ = htonl(static_cast<uint32>(status));
833 // Returns the size of the SpdyRstStreamControlFrameBlock structure.
834 // Note: this is not the size of the SpdyRstStreamControlFrame class.
835 static size_t size() { return sizeof(SpdyRstStreamControlFrameBlock); }
837 private:
838 const struct SpdyRstStreamControlFrameBlock* block() const {
839 return static_cast<SpdyRstStreamControlFrameBlock*>(frame_);
841 struct SpdyRstStreamControlFrameBlock* mutable_block() {
842 return static_cast<SpdyRstStreamControlFrameBlock*>(frame_);
844 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamControlFrame);
847 class SpdySettingsControlFrame : public SpdyControlFrame {
848 public:
849 SpdySettingsControlFrame() : SpdyControlFrame(size()) {}
850 SpdySettingsControlFrame(char* data, bool owns_buffer)
851 : SpdyControlFrame(data, owns_buffer) {}
853 uint32 num_entries() const {
854 return ntohl(block()->num_entries_);
857 void set_num_entries(int val) {
858 mutable_block()->num_entries_ = htonl(val);
861 int header_block_len() const {
862 return length() - (size() - SpdyFrame::kHeaderSize);
865 const char* header_block() const {
866 return reinterpret_cast<const char*>(block()) + size();
869 // Returns the size of the SpdySettingsControlFrameBlock structure.
870 // Note: this is not the size of the SpdySettingsControlFrameBlock class.
871 static size_t size() { return sizeof(SpdySettingsControlFrameBlock); }
873 private:
874 const struct SpdySettingsControlFrameBlock* block() const {
875 return static_cast<SpdySettingsControlFrameBlock*>(frame_);
877 struct SpdySettingsControlFrameBlock* mutable_block() {
878 return static_cast<SpdySettingsControlFrameBlock*>(frame_);
880 DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame);
883 class SpdyPingControlFrame : public SpdyControlFrame {
884 public:
885 SpdyPingControlFrame() : SpdyControlFrame(size()) {}
886 SpdyPingControlFrame(char* data, bool owns_buffer)
887 : SpdyControlFrame(data, owns_buffer) {}
889 uint32 unique_id() const {
890 return ntohl(block()->unique_id_);
893 void set_unique_id(uint32 unique_id) {
894 mutable_block()->unique_id_ = htonl(unique_id);
897 static size_t size() { return sizeof(SpdyPingControlFrameBlock); }
899 private:
900 const struct SpdyPingControlFrameBlock* block() const {
901 return static_cast<SpdyPingControlFrameBlock*>(frame_);
903 struct SpdyPingControlFrameBlock* mutable_block() {
904 return static_cast<SpdyPingControlFrameBlock*>(frame_);
908 class SpdyCredentialControlFrame : public SpdyControlFrame {
909 public:
910 SpdyCredentialControlFrame() : SpdyControlFrame(size()) {}
911 SpdyCredentialControlFrame(char* data, bool owns_buffer)
912 : SpdyControlFrame(data, owns_buffer) {}
914 const char* payload() const {
915 return reinterpret_cast<const char*>(block()) + SpdyFrame::kHeaderSize;
918 static size_t size() { return sizeof(SpdyCredentialControlFrameBlock); }
920 private:
921 const struct SpdyCredentialControlFrameBlock* block() const {
922 return static_cast<SpdyCredentialControlFrameBlock*>(frame_);
924 DISALLOW_COPY_AND_ASSIGN(SpdyCredentialControlFrame);
927 class SpdyGoAwayControlFrame : public SpdyControlFrame {
928 public:
929 SpdyGoAwayControlFrame() : SpdyControlFrame(size()) {}
930 SpdyGoAwayControlFrame(char* data, bool owns_buffer)
931 : SpdyControlFrame(data, owns_buffer) {}
933 SpdyStreamId last_accepted_stream_id() const {
934 return ntohl(block()->last_accepted_stream_id_) & kStreamIdMask;
937 SpdyGoAwayStatus status() const {
938 if (version() < 3) {
939 LOG(DFATAL) << "Attempted to access status of SPDY 2 GOAWAY.";
940 return GOAWAY_INVALID;
941 } else {
942 uint32 status = ntohl(block()->status_);
943 if (status >= GOAWAY_NUM_STATUS_CODES) {
944 return GOAWAY_INVALID;
945 } else {
946 return static_cast<SpdyGoAwayStatus>(status);
951 void set_last_accepted_stream_id(SpdyStreamId id) {
952 mutable_block()->last_accepted_stream_id_ = htonl(id & kStreamIdMask);
955 static size_t size() { return sizeof(SpdyGoAwayControlFrameBlock); }
957 private:
958 const struct SpdyGoAwayControlFrameBlock* block() const {
959 return static_cast<SpdyGoAwayControlFrameBlock*>(frame_);
961 struct SpdyGoAwayControlFrameBlock* mutable_block() {
962 return static_cast<SpdyGoAwayControlFrameBlock*>(frame_);
964 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayControlFrame);
967 // A HEADERS frame.
968 class SpdyHeadersControlFrame : public SpdyControlFrame {
969 public:
970 SpdyHeadersControlFrame() : SpdyControlFrame(size()) {}
971 SpdyHeadersControlFrame(char* data, bool owns_buffer)
972 : SpdyControlFrame(data, owns_buffer) {}
974 SpdyStreamId stream_id() const {
975 return ntohl(block()->stream_id_) & kStreamIdMask;
978 void set_stream_id(SpdyStreamId id) {
979 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
982 // The number of bytes in the header block beyond the frame header length.
983 int header_block_len() const {
984 size_t header_block_len = length() - (size() - SpdyFrame::kHeaderSize);
985 // SPDY 2 had 2 bytes of unused space preceeding the header block.
986 if (version() < 3) {
987 header_block_len -= 2;
989 return header_block_len;
992 const char* header_block() const {
993 const char* header_block = reinterpret_cast<const char*>(block()) + size();
994 // SPDY 2 had 2 bytes of unused space preceeding the header block.
995 if (version() < 3) {
996 header_block += 2;
998 return header_block;
1001 // Returns the size of the SpdyHeadersControlFrameBlock structure.
1002 // Note: this is not the size of the SpdyHeadersControlFrame class.
1003 static size_t size() { return sizeof(SpdyHeadersControlFrameBlock); }
1005 private:
1006 const struct SpdyHeadersControlFrameBlock* block() const {
1007 return static_cast<SpdyHeadersControlFrameBlock*>(frame_);
1009 struct SpdyHeadersControlFrameBlock* mutable_block() {
1010 return static_cast<SpdyHeadersControlFrameBlock*>(frame_);
1012 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersControlFrame);
1015 // A WINDOW_UPDATE frame.
1016 class SpdyWindowUpdateControlFrame : public SpdyControlFrame {
1017 public:
1018 SpdyWindowUpdateControlFrame() : SpdyControlFrame(size()) {}
1019 SpdyWindowUpdateControlFrame(char* data, bool owns_buffer)
1020 : SpdyControlFrame(data, owns_buffer) {}
1022 SpdyStreamId stream_id() const {
1023 return ntohl(block()->stream_id_) & kStreamIdMask;
1026 void set_stream_id(SpdyStreamId id) {
1027 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
1030 uint32 delta_window_size() const {
1031 return ntohl(block()->delta_window_size_);
1034 void set_delta_window_size(uint32 delta_window_size) {
1035 mutable_block()->delta_window_size_ = htonl(delta_window_size);
1038 // Returns the size of the SpdyWindowUpdateControlFrameBlock structure.
1039 // Note: this is not the size of the SpdyWindowUpdateControlFrame class.
1040 static size_t size() { return sizeof(SpdyWindowUpdateControlFrameBlock); }
1042 private:
1043 const struct SpdyWindowUpdateControlFrameBlock* block() const {
1044 return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_);
1046 struct SpdyWindowUpdateControlFrameBlock* mutable_block() {
1047 return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_);
1050 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame);
1053 } // namespace net
1055 #endif // NET_SPDY_SPDY_PROTOCOL_H_