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