Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: net/spdy/spdy_protocol.h

Issue 9618002: SPDY - integration of spdy/3 code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains some protocol structures for use with Spdy. 5 // This file contains some protocol structures for use with Spdy.
6 6
7 #ifndef NET_SPDY_SPDY_PROTOCOL_H_ 7 #ifndef NET_SPDY_SPDY_PROTOCOL_H_
8 #define NET_SPDY_SPDY_PROTOCOL_H_ 8 #define NET_SPDY_SPDY_PROTOCOL_H_
9 #pragma once 9 #pragma once
10 10
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // +-----------------+ | 134 // +-----------------+ |
135 // | Proof Length (32 bits) | 135 // | Proof Length (32 bits) |
136 // +----------------------------------+ 136 // +----------------------------------+
137 // | Proof | 137 // | Proof |
138 // +----------------------------------+ <+ 138 // +----------------------------------+ <+
139 // | Certificate Length (32 bits) | | 139 // | Certificate Length (32 bits) | |
140 // +----------------------------------+ | Repeated until end of frame 140 // +----------------------------------+ | Repeated until end of frame
141 // | Certificate | | 141 // | Certificate | |
142 // +----------------------------------+ <+ 142 // +----------------------------------+ <+
143 // 143 //
144
145 namespace {
146
147 // Default SPDY version for unit tests.
148 const int SPDY_VERSION_FOR_TESTS = 2;
Ryan Hamilton 2012/03/09 19:09:58 Oh, now I see where this is defined. This does no
ramant (doing other things) 2012/03/10 01:14:09 Moved this to forked versions for spdy_framer_test
149
150 } // namespace
151
144 namespace spdy { 152 namespace spdy {
145 153
146 // This implementation of Spdy is version 2; It's like version 1, with some 154 // Default SPDY version.
147 // minor tweaks. 155 // TODO(hkhalil): Remove gfe_spdy::kSpdyProtocolVersion
148 const int kSpdyProtocolVersion = 2; 156 const int kSpdyProtocolVersion = 2;
Ryan Hamilton 2012/03/09 19:09:58 Where is this used?
ramant (doing other things) 2012/03/10 01:14:09 Deleted it (and changed all uses of it). Will upst
149 157
150 // Initial window size for a Spdy stream 158 // Initial window size for a Spdy stream
151 const size_t kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes 159 const int32 kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes
152 160
153 // Maximum window size for a Spdy stream 161 // Maximum window size for a Spdy stream
154 const size_t kSpdyStreamMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int 162 const int32 kSpdyStreamMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int
155 163
156 // HTTP-over-SPDY header constants 164 // HTTP-over-SPDY header constants
157 const char kMethod[] = "method"; 165 const char kMethod[] = "method";
158 const char kStatus[] = "status"; 166 const char kStatus[] = "status";
159 const char kUrl[] = "url"; 167 const char kUrl[] = "url";
160 const char kVersion[] = "version"; 168 const char kVersion[] = "version";
161 // When we server push, we will add [path: fully/qualified/url] to the server 169 // When we server push, we will add [path: fully/qualified/url] to the server
162 // push headers so that the client will know what url the data corresponds to. 170 // push headers so that the client will know what url the data corresponds to.
163 const char kPath[] = "path"; 171 const char kPath[] = "path";
164 172
173 // SPDY 2 dictionary.
174 // This is just a hacked dictionary to use for shrinking HTTP-like headers.
175 const char kV2Dictionary[] =
176 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
177 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
178 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
179 "-agent10010120020120220320420520630030130230330430530630740040140240340440"
180 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
181 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
182 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
183 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
184 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
185 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
186 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
187 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
188 ".1statusversionurl";
189 const int kV2DictionarySize = arraysize(kV2Dictionary);
190
191 // SPDY 3 dictionary.
192 const char kV3Dictionary[] = {
193 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti
194 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h
195 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p
196 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p
197 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de
198 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete....
199 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace...
200 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept.
201 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
202 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse
203 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc
204 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco
205 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding....
206 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l
207 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage.
208 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
209 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges
210 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age.
211 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow
212 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth
213 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio
214 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac
215 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr
216 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co
217 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection
218 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont
219 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base
220 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont
221 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco
222 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding....
223 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content-
224 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language
225 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont
226 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng
227 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co
228 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo
229 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation..
230 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
231 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5...
232 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content
233 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range..
234 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
235 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type..
236 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date..
237 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag..
238 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect
239 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi
240 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f
241 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h
242 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i
243 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match.
244 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo
245 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s
246 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince....
247 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none-
248 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match...
249 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang
250 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if-
251 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi
252 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since
253 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last
254 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie
255 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc
256 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation...
257 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for
258 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards...
259 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma.
260 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy
261 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent
262 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate...
263 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a
264 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza
265 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion....
266 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range...
267 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer
268 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr
269 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after.
270 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve
271 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te.
272 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail
273 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr
274 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e
275 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding.
276 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra
277 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us
278 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent
279 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary
280 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via.
281 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni
282 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww
283 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen
284 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate..
285 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method
286 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get.
287 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu
288 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200
289 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v
290 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion..
291 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1
292 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur
293 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub
294 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s
295 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki
296 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee
297 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive.
298 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi
299 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012
300 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205
301 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030
302 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043
303 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307
304 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540
305 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084
306 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411
307 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341
308 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164
309 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504
310 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N
311 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho
312 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative
313 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa
314 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204.
315 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte
316 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo
317 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm
318 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4
319 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R
320 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40
321 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth
322 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40
323 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid
324 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N
325 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found
326 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte
327 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser
328 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro
329 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not
330 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme
331 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503.
332 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service.
333 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila
334 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F
335 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A
336 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J
337 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A
338 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept.
339 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov.
340 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0
341 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon
342 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W
343 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu.
344 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa
345 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun..
346 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk
347 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text.
348 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima
349 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i
350 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg
351 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g
352 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli
353 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
354 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli
355 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
356 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml
357 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl
358 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text
359 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr
360 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ
361 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat
362 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age
363 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de
364 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd
365 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse
366 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c
367 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i
368 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859-
369 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-..
370 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0.
371 };
372 const int kV3DictionarySize = arraysize(kV3Dictionary);
373
165 // Note: all protocol data structures are on-the-wire format. That means that 374 // Note: all protocol data structures are on-the-wire format. That means that
166 // data is stored in network-normalized order. Readers must use the 375 // data is stored in network-normalized order. Readers must use the
167 // accessors provided or call ntohX() functions. 376 // accessors provided or call ntohX() functions.
168 377
169 // Types of Spdy Control Frames. 378 // Types of Spdy Control Frames.
170 enum SpdyControlType { 379 enum SpdyControlType {
171 SYN_STREAM = 1, 380 SYN_STREAM = 1,
172 SYN_REPLY, 381 SYN_REPLY,
173 RST_STREAM, 382 RST_STREAM,
174 SETTINGS, 383 SETTINGS,
175 NOOP, 384 NOOP, // No longer valid kept for identifiability/enum order.
Ryan Hamilton 2012/03/09 19:09:58 This class is shared between spdy 2 and spdy 3, so
ramant (doing other things) 2012/03/10 01:14:09 Done.
176 PING, 385 PING,
177 GOAWAY, 386 GOAWAY,
178 HEADERS, 387 HEADERS,
179 WINDOW_UPDATE, 388 WINDOW_UPDATE,
180 CREDENTIAL, 389 CREDENTIAL,
181 NUM_CONTROL_FRAME_TYPES 390 NUM_CONTROL_FRAME_TYPES
182 }; 391 };
183 392
184 // Flags on data packets. 393 // Flags on data packets.
185 enum SpdyDataFlags { 394 enum SpdyDataFlags {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 CANCEL = 5, 441 CANCEL = 5,
233 INTERNAL_ERROR = 6, 442 INTERNAL_ERROR = 6,
234 FLOW_CONTROL_ERROR = 7, 443 FLOW_CONTROL_ERROR = 7,
235 INVALID_ASSOCIATED_STREAM = 8, 444 INVALID_ASSOCIATED_STREAM = 8,
236 NUM_STATUS_CODES = 9 445 NUM_STATUS_CODES = 9
237 }; 446 };
238 447
239 // A SPDY stream id is a 31 bit entity. 448 // A SPDY stream id is a 31 bit entity.
240 typedef uint32 SpdyStreamId; 449 typedef uint32 SpdyStreamId;
241 450
242 // A SPDY priority is a number between 0 and 3 (inclusive). 451 // A SPDY priority is a number between 0 and 7 (inclusive).
452 // SPDY priority range is version-dependant. For SPDY 2 and below, priority is a
453 // number between 0 and 3.
243 typedef uint8 SpdyPriority; 454 typedef uint8 SpdyPriority;
244 455
245 // SPDY Priorities. (there are only 2 bits) 456 // SPDY Priorities. (there are only 2 bits)
246 #define SPDY_PRIORITY_LOWEST 3 457 #define SPDY_PRIORITY_LOWEST 3
247 #define SPDY_PRIORITY_HIGHEST 0 458 #define SPDY_PRIORITY_HIGHEST 0
248 459
249 // ------------------------------------------------------------------------- 460 // -------------------------------------------------------------------------
250 // These structures mirror the protocol structure definitions. 461 // These structures mirror the protocol structure definitions.
251 462
252 // For the control data structures, we pack so that sizes match the 463 // For the control data structures, we pack so that sizes match the
(...skipping 25 matching lines...) Expand all
278 struct SpdySynStreamControlFrameBlock : SpdyFrameBlock { 489 struct SpdySynStreamControlFrameBlock : SpdyFrameBlock {
279 SpdyStreamId stream_id_; 490 SpdyStreamId stream_id_;
280 SpdyStreamId associated_stream_id_; 491 SpdyStreamId associated_stream_id_;
281 SpdyPriority priority_; 492 SpdyPriority priority_;
282 uint8 unused_; 493 uint8 unused_;
283 }; 494 };
284 495
285 // A SYN_REPLY Control Frame structure. 496 // A SYN_REPLY Control Frame structure.
286 struct SpdySynReplyControlFrameBlock : SpdyFrameBlock { 497 struct SpdySynReplyControlFrameBlock : SpdyFrameBlock {
287 SpdyStreamId stream_id_; 498 SpdyStreamId stream_id_;
288 uint16 unused_;
289 }; 499 };
290 500
291 // A RST_STREAM Control Frame structure. 501 // A RST_STREAM Control Frame structure.
292 struct SpdyRstStreamControlFrameBlock : SpdyFrameBlock { 502 struct SpdyRstStreamControlFrameBlock : SpdyFrameBlock {
293 SpdyStreamId stream_id_; 503 SpdyStreamId stream_id_;
294 uint32 status_; 504 uint32 status_;
295 }; 505 };
296 506
297 // A SETTINGS Control Frame structure. 507 // A SETTINGS Control Frame structure.
298 struct SpdySettingsControlFrameBlock : SpdyFrameBlock { 508 struct SpdySettingsControlFrameBlock : SpdyFrameBlock {
299 uint32 num_entries_; 509 uint32 num_entries_;
300 // Variable data here. 510 // Variable data here.
301 }; 511 };
302 512
303 // A NOOP Control Frame structure.
304 struct SpdyNoopControlFrameBlock : SpdyFrameBlock {
305 };
306
307 // A PING Control Frame structure. 513 // A PING Control Frame structure.
308 struct SpdyPingControlFrameBlock : SpdyFrameBlock { 514 struct SpdyPingControlFrameBlock : SpdyFrameBlock {
309 uint32 unique_id_; 515 uint32 unique_id_;
310 }; 516 };
311 517
518 // TODO(avd): remove this struct
312 // A CREDENTIAL Control Frame structure. 519 // A CREDENTIAL Control Frame structure.
313 struct SpdyCredentialControlFrameBlock : SpdyFrameBlock { 520 struct SpdyCredentialControlFrameBlock : SpdyFrameBlock {
314 uint16 slot_; 521 uint16 slot_;
315 uint32 proof_len_; 522 uint32 proof_len_;
316 // Variable data here. 523 // Variable data here.
317 // proof data 524 // proof data
318 // for each certificate: unit32 certificate_len + certificate_data[i] 525 // for each certificate: unit32 certificate_len + certificate_data[i]
319 }; 526 };
320 527
321 // A GOAWAY Control Frame structure. 528 // A GOAWAY Control Frame structure.
322 struct SpdyGoAwayControlFrameBlock : SpdyFrameBlock { 529 struct SpdyGoAwayControlFrameBlock : SpdyFrameBlock {
323 SpdyStreamId last_accepted_stream_id_; 530 SpdyStreamId last_accepted_stream_id_;
324 }; 531 };
325 532
326 // A HEADERS Control Frame structure. 533 // A HEADERS Control Frame structure.
327 struct SpdyHeadersControlFrameBlock : SpdyFrameBlock { 534 struct SpdyHeadersControlFrameBlock : SpdyFrameBlock {
328 SpdyStreamId stream_id_; 535 SpdyStreamId stream_id_;
329 uint16 unused_;
330 }; 536 };
331 537
332 // A WINDOW_UPDATE Control Frame structure 538 // A WINDOW_UPDATE Control Frame structure
333 struct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock { 539 struct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock {
334 SpdyStreamId stream_id_; 540 SpdyStreamId stream_id_;
335 uint32 delta_window_size_; 541 uint32 delta_window_size_;
336 }; 542 };
337 543
338 // A structure for the 8 bit flags and 24 bit ID fields.
339 union SettingsFlagsAndId {
340 // Sets both flags and id to the value for flags-and-id as sent over the wire
341 SettingsFlagsAndId(uint32 val) : id_(val) {}
342 uint8 flags() const { return flags_[0]; }
343 void set_flags(uint8 flags) { flags_[0] = flags; }
344 uint32 id() const { return (ntohl(id_) & kSettingsIdMask); }
345 void set_id(uint32 id) {
346 DCHECK_EQ(0u, (id & ~kSettingsIdMask));
347 id_ = htonl((flags() << 24) | (id & kSettingsIdMask));
348 }
349
350 uint8 flags_[4]; // 8 bits
351 uint32 id_; // 24 bits
352 };
353
354 #pragma pack(pop) 544 #pragma pack(pop)
355 545
356 // ------------------------------------------------------------------------- 546 // -------------------------------------------------------------------------
357 // Wrapper classes for various SPDY frames. 547 // Wrapper classes for various SPDY frames.
358 548
359 // All Spdy Frame types derive from this SpdyFrame class. 549 // All Spdy Frame types derive from this SpdyFrame class.
360 class SpdyFrame { 550 class SpdyFrame {
361 public: 551 public:
362 // Create a SpdyFrame for a given sized buffer. 552 // Create a SpdyFrame for a given sized buffer.
363 explicit SpdyFrame(size_t size) : frame_(NULL), owns_buffer_(true) { 553 explicit SpdyFrame(size_t size) : frame_(NULL), owns_buffer_(true) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 public: 650 public:
461 explicit SpdyControlFrame(size_t size) : SpdyFrame(size) {} 651 explicit SpdyControlFrame(size_t size) : SpdyFrame(size) {}
462 SpdyControlFrame(char* data, bool owns_buffer) 652 SpdyControlFrame(char* data, bool owns_buffer)
463 : SpdyFrame(data, owns_buffer) {} 653 : SpdyFrame(data, owns_buffer) {}
464 654
465 // Callers can use this method to check if the frame appears to be a valid 655 // Callers can use this method to check if the frame appears to be a valid
466 // frame. Does not guarantee that there are no errors. 656 // frame. Does not guarantee that there are no errors.
467 bool AppearsToBeAValidControlFrame() const { 657 bool AppearsToBeAValidControlFrame() const {
468 // Right now we only check if the frame has an out-of-bounds type. 658 // Right now we only check if the frame has an out-of-bounds type.
469 uint16 type = ntohs(block()->control_.type_); 659 uint16 type = ntohs(block()->control_.type_);
470 return (type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 660 return type >= SYN_STREAM &&
661 type < NUM_CONTROL_FRAME_TYPES &&
662 type != NOOP; // NOOP is not a 'valid' control frame.
Ryan Hamilton 2012/03/09 19:09:58 NOOP is valid in SPDY/2
ramant (doing other things) 2012/03/10 01:14:09 Will do the "type != NOOP" test if version !=2. Th
471 } 663 }
472 664
473 uint16 version() const { 665 uint16 version() const {
474 const int kVersionMask = 0x7fff; 666 const int kVersionMask = 0x7fff;
475 return ntohs(block()->control_.version_) & kVersionMask; 667 return ntohs(block()->control_.version_) & kVersionMask;
476 } 668 }
477 669
478 void set_version(uint16 version) { 670 void set_version(uint16 version) {
479 DCHECK_EQ(0u, version & kControlFlagMask); 671 const uint16 kControlBit = 0x80;
480 mutable_block()->control_.version_ = htons(kControlFlagMask | version); 672 DCHECK_EQ(0, version & kControlBit);
673 mutable_block()->control_.version_ = kControlBit | htons(version);
481 } 674 }
482 675
483 SpdyControlType type() const { 676 SpdyControlType type() const {
484 uint16 type = ntohs(block()->control_.type_); 677 uint16 type = ntohs(block()->control_.type_);
485 DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 678 LOG_IF(DFATAL, type < SYN_STREAM || type >= NUM_CONTROL_FRAME_TYPES)
679 << "Invalid control frame type " << type;
486 return static_cast<SpdyControlType>(type); 680 return static_cast<SpdyControlType>(type);
487 } 681 }
488 682
489 void set_type(SpdyControlType type) { 683 void set_type(SpdyControlType type) {
490 DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 684 DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES);
491 mutable_block()->control_.type_ = htons(type); 685 mutable_block()->control_.type_ = htons(type);
492 } 686 }
493 687
494 // Returns true if this control frame is of a type that has a header block, 688 // Returns true if this control frame is of a type that has a header block,
495 // otherwise it returns false. 689 // otherwise it returns false.
496 bool has_header_block() const { 690 bool has_header_block() const {
497 return type() == SYN_STREAM || type() == SYN_REPLY || type() == HEADERS; 691 return type() == SYN_STREAM || type() == SYN_REPLY || type() == HEADERS;
498 } 692 }
499 693
500 // The size of the 'Number of Name/Value pairs' field in a Name/Value block.
501 static const size_t kNumNameValuePairsSize = 2;
502
503 // The size of the 'Length of a name' field in a Name/Value block.
504 static const size_t kLengthOfNameSize = 2;
505
506 // The size of the 'Length of a value' field in a Name/Value block.
507 static const size_t kLengthOfValueSize = 2;
508
509 private: 694 private:
510 const struct SpdyFrameBlock* block() const { 695 const struct SpdyFrameBlock* block() const {
511 return frame_; 696 return frame_;
512 } 697 }
513 struct SpdyFrameBlock* mutable_block() { 698 struct SpdyFrameBlock* mutable_block() {
514 return frame_; 699 return frame_;
515 } 700 }
516 DISALLOW_COPY_AND_ASSIGN(SpdyControlFrame); 701 DISALLOW_COPY_AND_ASSIGN(SpdyControlFrame);
517 }; 702 };
518 703
(...skipping 14 matching lines...) Expand all
533 718
534 SpdyStreamId associated_stream_id() const { 719 SpdyStreamId associated_stream_id() const {
535 return ntohl(block()->associated_stream_id_) & kStreamIdMask; 720 return ntohl(block()->associated_stream_id_) & kStreamIdMask;
536 } 721 }
537 722
538 void set_associated_stream_id(SpdyStreamId id) { 723 void set_associated_stream_id(SpdyStreamId id) {
539 mutable_block()->associated_stream_id_ = htonl(id & kStreamIdMask); 724 mutable_block()->associated_stream_id_ = htonl(id & kStreamIdMask);
540 } 725 }
541 726
542 SpdyPriority priority() const { 727 SpdyPriority priority() const {
543 return (block()->priority_ & kPriorityMask) >> 6; 728 if (version() < 3) {
729 return (block()->priority_ & kSpdy2PriorityMask) >> 6;
730 } else {
731 return (block()->priority_ & kSpdy3PriorityMask) >> 5;
732 }
544 } 733 }
545 734
546 // The number of bytes in the header block beyond the frame header length. 735 // The number of bytes in the header block beyond the frame header length.
547 int header_block_len() const { 736 int header_block_len() const {
548 return length() - (size() - SpdyFrame::kHeaderSize); 737 return length() - (size() - SpdyFrame::kHeaderSize);
549 } 738 }
550 739
551 const char* header_block() const { 740 const char* header_block() const {
552 return reinterpret_cast<const char*>(block()) + size(); 741 return reinterpret_cast<const char*>(block()) + size();
553 } 742 }
(...skipping 21 matching lines...) Expand all
575 764
576 SpdyStreamId stream_id() const { 765 SpdyStreamId stream_id() const {
577 return ntohl(block()->stream_id_) & kStreamIdMask; 766 return ntohl(block()->stream_id_) & kStreamIdMask;
578 } 767 }
579 768
580 void set_stream_id(SpdyStreamId id) { 769 void set_stream_id(SpdyStreamId id) {
581 mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 770 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
582 } 771 }
583 772
584 int header_block_len() const { 773 int header_block_len() const {
585 return length() - (size() - SpdyFrame::kHeaderSize); 774 size_t header_block_len = length() - (size() - SpdyFrame::kHeaderSize);
775 // SPDY 2 had 2 bytes of unused space preceeding the header block.
776 if (version() < 3) {
777 header_block_len -= 2;
778 }
779 return header_block_len;
586 } 780 }
587 781
588 const char* header_block() const { 782 const char* header_block() const {
589 return reinterpret_cast<const char*>(block()) + size(); 783 const char* header_block = reinterpret_cast<const char*>(block()) + size();
784 // SPDY 2 had 2 bytes of unused space preceeding the header block.
785 if (version() < 3) {
786 header_block += 2;
787 }
788 return header_block;
590 } 789 }
591 790
592 // Returns the size of the SpdySynReplyControlFrameBlock structure. 791 // Returns the size of the SpdySynReplyControlFrameBlock structure.
593 // Note: this is not the size of the SpdySynReplyControlFrame class. 792 // Note: this is not the size of the SpdySynReplyControlFrame class.
594 static size_t size() { return sizeof(SpdySynReplyControlFrameBlock); } 793 static size_t size() { return sizeof(SpdySynReplyControlFrameBlock); }
595 794
596 private: 795 private:
597 const struct SpdySynReplyControlFrameBlock* block() const { 796 const struct SpdySynReplyControlFrameBlock* block() const {
598 return static_cast<SpdySynReplyControlFrameBlock*>(frame_); 797 return static_cast<SpdySynReplyControlFrameBlock*>(frame_);
599 } 798 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 private: 872 private:
674 const struct SpdySettingsControlFrameBlock* block() const { 873 const struct SpdySettingsControlFrameBlock* block() const {
675 return static_cast<SpdySettingsControlFrameBlock*>(frame_); 874 return static_cast<SpdySettingsControlFrameBlock*>(frame_);
676 } 875 }
677 struct SpdySettingsControlFrameBlock* mutable_block() { 876 struct SpdySettingsControlFrameBlock* mutable_block() {
678 return static_cast<SpdySettingsControlFrameBlock*>(frame_); 877 return static_cast<SpdySettingsControlFrameBlock*>(frame_);
679 } 878 }
680 DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame); 879 DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame);
681 }; 880 };
682 881
683 class SpdyNoOpControlFrame : public SpdyControlFrame {
684 public:
685 SpdyNoOpControlFrame() : SpdyControlFrame(size()) {}
686 SpdyNoOpControlFrame(char* data, bool owns_buffer)
687 : SpdyControlFrame(data, owns_buffer) {}
688
689 static size_t size() { return sizeof(SpdyNoopControlFrameBlock); }
690 };
691
692 class SpdyPingControlFrame : public SpdyControlFrame { 882 class SpdyPingControlFrame : public SpdyControlFrame {
693 public: 883 public:
694 SpdyPingControlFrame() : SpdyControlFrame(size()) {} 884 SpdyPingControlFrame() : SpdyControlFrame(size()) {}
695 SpdyPingControlFrame(char* data, bool owns_buffer) 885 SpdyPingControlFrame(char* data, bool owns_buffer)
696 : SpdyControlFrame(data, owns_buffer) {} 886 : SpdyControlFrame(data, owns_buffer) {}
697 887
698 uint32 unique_id() const { 888 uint32 unique_id() const {
699 return ntohl(block()->unique_id_); 889 return ntohl(block()->unique_id_);
700 } 890 }
701 891
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 SpdyStreamId stream_id() const { 959 SpdyStreamId stream_id() const {
770 return ntohl(block()->stream_id_) & kStreamIdMask; 960 return ntohl(block()->stream_id_) & kStreamIdMask;
771 } 961 }
772 962
773 void set_stream_id(SpdyStreamId id) { 963 void set_stream_id(SpdyStreamId id) {
774 mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 964 mutable_block()->stream_id_ = htonl(id & kStreamIdMask);
775 } 965 }
776 966
777 // The number of bytes in the header block beyond the frame header length. 967 // The number of bytes in the header block beyond the frame header length.
778 int header_block_len() const { 968 int header_block_len() const {
779 return length() - (size() - SpdyFrame::kHeaderSize); 969 size_t header_block_len = length() - (size() - SpdyFrame::kHeaderSize);
970 // SPDY 2 had 2 bytes of unused space preceeding the header block.
971 if (version() < 3) {
972 header_block_len -= 2;
973 }
974 return header_block_len;
780 } 975 }
781 976
782 const char* header_block() const { 977 const char* header_block() const {
783 return reinterpret_cast<const char*>(block()) + size(); 978 const char* header_block = reinterpret_cast<const char*>(block()) + size();
979 // SPDY 2 had 2 bytes of unused space preceeding the header block.
980 if (version() < 3) {
981 header_block += 2;
982 }
983 return header_block;
784 } 984 }
785 985
786 // Returns the size of the SpdyHeadersControlFrameBlock structure. 986 // Returns the size of the SpdyHeadersControlFrameBlock structure.
787 // Note: this is not the size of the SpdyHeadersControlFrame class. 987 // Note: this is not the size of the SpdyHeadersControlFrame class.
788 static size_t size() { return sizeof(SpdyHeadersControlFrameBlock); } 988 static size_t size() { return sizeof(SpdyHeadersControlFrameBlock); }
789 989
790 private: 990 private:
791 const struct SpdyHeadersControlFrameBlock* block() const { 991 const struct SpdyHeadersControlFrameBlock* block() const {
792 return static_cast<SpdyHeadersControlFrameBlock*>(frame_); 992 return static_cast<SpdyHeadersControlFrameBlock*>(frame_);
793 } 993 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 struct SpdyWindowUpdateControlFrameBlock* mutable_block() { 1031 struct SpdyWindowUpdateControlFrameBlock* mutable_block() {
832 return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); 1032 return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_);
833 } 1033 }
834 1034
835 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame); 1035 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame);
836 }; 1036 };
837 1037
838 } // namespace spdy 1038 } // namespace spdy
839 1039
840 #endif // NET_SPDY_SPDY_PROTOCOL_H_ 1040 #endif // NET_SPDY_SPDY_PROTOCOL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698