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 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
11 #ifndef NET_SPDY_SPDY_PROTOCOL_H_
12 #define NET_SPDY_SPDY_PROTOCOL_H_
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"
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. It is guaranteed
32 // that the enum value SPDYn maps to the integer n.
33 enum SpdyMajorVersion
{
35 SPDY_MIN_VERSION
= SPDY2
,
38 SPDY_MAX_VERSION
= SPDY4
41 // A SPDY stream id is a 31 bit entity.
42 typedef uint32 SpdyStreamId
;
44 // Specifies the stream ID used to denote the current session (for
46 const SpdyStreamId kSessionFlowControlStreamId
= 0;
48 // Initial window size for a Spdy stream.
49 const int32 kSpdyStreamInitialWindowSize
= 64 * 1024; // 64 KBytes
51 // Initial window size for a Spdy session.
52 const int32 kSpdySessionInitialWindowSize
= 64 * 1024; // 64 KBytes
54 // Maximum window size for a Spdy stream or session.
55 const int32 kSpdyMaximumWindowSize
= 0x7FFFFFFF; // Max signed 32bit int
58 // This is just a hacked dictionary to use for shrinking HTTP-like headers.
59 const char kV2Dictionary
[] =
60 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
61 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
62 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
63 "-agent10010120020120220320420520630030130230330430530630740040140240340440"
64 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
65 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
66 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
67 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
68 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
69 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
70 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
71 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
73 const int kV2DictionarySize
= arraysize(kV2Dictionary
);
76 const char kV3Dictionary
[] = {
77 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti
78 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h
79 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p
80 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p
81 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de
82 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete....
83 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace...
84 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept.
85 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
86 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse
87 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc
88 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco
89 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding....
90 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l
91 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage.
92 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
93 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges
94 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age.
95 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow
96 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth
97 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio
98 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac
99 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr
100 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co
101 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection
102 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont
103 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base
104 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont
105 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco
106 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding....
107 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content-
108 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language
109 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont
110 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng
111 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co
112 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo
113 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation..
114 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
115 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5...
116 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content
117 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range..
118 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
119 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type..
120 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date..
121 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag..
122 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect
123 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi
124 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f
125 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h
126 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i
127 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match.
128 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo
129 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s
130 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince....
131 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none-
132 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match...
133 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang
134 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if-
135 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi
136 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since
137 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last
138 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie
139 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc
140 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation...
141 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for
142 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards...
143 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma.
144 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy
145 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent
146 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate...
147 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a
148 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza
149 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion....
150 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range...
151 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer
152 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr
153 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after.
154 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve
155 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te.
156 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail
157 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr
158 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e
159 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding.
160 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra
161 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us
162 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent
163 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary
164 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via.
165 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni
166 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww
167 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen
168 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate..
169 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method
170 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get.
171 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu
172 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200
173 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v
174 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion..
175 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1
176 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur
177 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub
178 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s
179 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki
180 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee
181 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive.
182 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi
183 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012
184 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205
185 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030
186 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043
187 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307
188 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540
189 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084
190 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411
191 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341
192 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164
193 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504
194 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N
195 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho
196 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative
197 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa
198 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204.
199 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte
200 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo
201 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm
202 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4
203 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R
204 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40
205 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth
206 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40
207 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid
208 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N
209 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found
210 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte
211 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser
212 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro
213 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not
214 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme
215 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503.
216 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service.
217 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila
218 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F
219 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A
220 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J
221 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A
222 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept.
223 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov.
224 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0
225 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon
226 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W
227 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu.
228 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa
229 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun..
230 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk
231 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text.
232 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima
233 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i
234 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg
235 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g
236 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli
237 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
238 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli
239 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
240 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml
241 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl
242 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text
243 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr
244 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ
245 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat
246 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age
247 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de
248 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd
249 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse
250 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c
251 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i
252 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859-
253 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-..
254 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0.
256 const int kV3DictionarySize
= arraysize(kV3Dictionary
);
258 // The HTTP/2 connection header prefix, which must be the first bytes
259 // sent by the client upon starting an HTTP/2 connection, and which
260 // must be followed by a SETTINGS frame.
262 // Equivalent to the string "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
263 // (without the null terminator).
264 const char kHttp2ConnectionHeaderPrefix
[] = {
265 0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, // PRI * HT
266 0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a, // TP/2.0..
267 0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a // ..SM....
269 const int kHttp2ConnectionHeaderPrefixSize
=
270 arraysize(kHttp2ConnectionHeaderPrefix
);
272 // Types of SPDY frames.
276 FIRST_CONTROL_TYPE
= SYN_STREAM
,
280 NOOP
, // Because it is valid in SPDY/2, kept for identifiability/enum order.
288 LAST_CONTROL_TYPE
= PUSH_PROMISE
291 // Flags on data packets.
297 // Flags on control packets
298 enum SpdyControlFlags
{
299 CONTROL_FLAG_NONE
= 0,
300 CONTROL_FLAG_FIN
= 1,
301 CONTROL_FLAG_UNIDIRECTIONAL
= 2
304 // Flags on the SETTINGS control frame.
305 enum SpdySettingsControlFlags
{
306 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS
= 0x1
309 // Flags for settings within a SETTINGS frame.
310 enum SpdySettingsFlags
{
311 SETTINGS_FLAG_NONE
= 0x0,
312 SETTINGS_FLAG_PLEASE_PERSIST
= 0x1,
313 SETTINGS_FLAG_PERSISTED
= 0x2
316 // List of known settings.
317 enum SpdySettingsIds
{
318 SETTINGS_UPLOAD_BANDWIDTH
= 0x1,
319 SETTINGS_DOWNLOAD_BANDWIDTH
= 0x2,
320 // Network round trip time in milliseconds.
321 SETTINGS_ROUND_TRIP_TIME
= 0x3,
322 SETTINGS_MAX_CONCURRENT_STREAMS
= 0x4,
323 // TCP congestion window in packets.
324 SETTINGS_CURRENT_CWND
= 0x5,
325 // Downstream byte retransmission rate in percentage.
326 SETTINGS_DOWNLOAD_RETRANS_RATE
= 0x6,
327 // Initial window size in bytes
328 SETTINGS_INITIAL_WINDOW_SIZE
= 0x7
331 // Status codes for RST_STREAM frames.
332 enum SpdyRstStreamStatus
{
333 RST_STREAM_INVALID
= 0,
334 RST_STREAM_PROTOCOL_ERROR
= 1,
335 RST_STREAM_INVALID_STREAM
= 2,
336 RST_STREAM_REFUSED_STREAM
= 3,
337 RST_STREAM_UNSUPPORTED_VERSION
= 4,
338 RST_STREAM_CANCEL
= 5,
339 RST_STREAM_INTERNAL_ERROR
= 6,
340 RST_STREAM_FLOW_CONTROL_ERROR
= 7,
341 RST_STREAM_STREAM_IN_USE
= 8,
342 RST_STREAM_STREAM_ALREADY_CLOSED
= 9,
343 RST_STREAM_INVALID_CREDENTIALS
= 10,
344 RST_STREAM_FRAME_TOO_LARGE
= 11,
345 RST_STREAM_NUM_STATUS_CODES
= 12
348 // Status codes for GOAWAY frames.
349 enum SpdyGoAwayStatus
{
352 GOAWAY_PROTOCOL_ERROR
= 1,
353 GOAWAY_INTERNAL_ERROR
= 2,
354 GOAWAY_NUM_STATUS_CODES
= 3
357 // A SPDY priority is a number between 0 and 7 (inclusive).
358 // SPDY priority range is version-dependant. For SPDY 2 and below, priority is a
359 // number between 0 and 3.
360 typedef uint8 SpdyPriority
;
362 typedef uint8 SpdyCredentialSlot
;
364 typedef std::map
<std::string
, std::string
> SpdyNameValueBlock
;
366 typedef uint32 SpdyPingId
;
369 typedef SpdyFrame SpdySerializedFrame
;
371 class SpdyFrameVisitor
;
373 // Intermediate representation for SPDY frames.
374 // TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
378 virtual ~SpdyFrameIR() {}
380 virtual void Visit(SpdyFrameVisitor
* visitor
) const = 0;
386 DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR
);
389 // Abstract class intended to be inherited by IRs that have a stream associated
391 class SpdyFrameWithStreamIdIR
: public SpdyFrameIR
{
393 virtual ~SpdyFrameWithStreamIdIR() {}
394 SpdyStreamId
stream_id() const { return stream_id_
; }
395 void set_stream_id(SpdyStreamId stream_id
) {
396 DCHECK_EQ(0u, stream_id
& ~kStreamIdMask
);
397 stream_id_
= stream_id
;
401 explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id
) {
402 set_stream_id(stream_id
);
406 SpdyStreamId stream_id_
;
408 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR
);
411 // Abstract class intended to be inherited by IRs that have the option of a FIN
412 // flag. Implies SpdyFrameWithStreamIdIR.
413 class SpdyFrameWithFinIR
: public SpdyFrameWithStreamIdIR
{
415 virtual ~SpdyFrameWithFinIR() {}
416 bool fin() const { return fin_
; }
417 void set_fin(bool fin
) { fin_
= fin
; }
420 explicit SpdyFrameWithFinIR(SpdyStreamId stream_id
)
421 : SpdyFrameWithStreamIdIR(stream_id
),
427 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR
);
430 // Abstract class intended to be inherited by IRs that contain a name-value
431 // block. Implies SpdyFrameWithFinIR.
432 class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR
433 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR
) {
435 const SpdyNameValueBlock
& name_value_block() const {
436 return name_value_block_
;
438 SpdyNameValueBlock
* GetMutableNameValueBlock() { return &name_value_block_
; }
439 void SetHeader(const base::StringPiece
& name
,
440 const base::StringPiece
& value
) {
441 name_value_block_
[name
.as_string()] = value
.as_string();
445 explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id
);
446 virtual ~SpdyFrameWithNameValueBlockIR();
449 SpdyNameValueBlock name_value_block_
;
451 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR
);
454 class NET_EXPORT_PRIVATE SpdyDataIR
455 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR
) {
457 // Performs deep copy on data.
458 SpdyDataIR(SpdyStreamId stream_id
, const base::StringPiece
& data
);
460 // Use in conjunction with SetDataShallow() for shallow-copy on data.
461 explicit SpdyDataIR(SpdyStreamId stream_id
);
463 virtual ~SpdyDataIR();
465 base::StringPiece
data() const { return data_
; }
467 // Deep-copy of data (keep private copy).
468 void SetDataDeep(const base::StringPiece
& data
) {
469 data_store_
.reset(new std::string(data
.data(), data
.length()));
470 data_
= *(data_store_
.get());
473 // Shallow-copy of data (do not keep private copy).
474 void SetDataShallow(const base::StringPiece
& data
) {
479 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
482 // Used to store data that this SpdyDataIR should own.
483 scoped_ptr
<std::string
> data_store_
;
484 base::StringPiece data_
;
486 DISALLOW_COPY_AND_ASSIGN(SpdyDataIR
);
489 class NET_EXPORT_PRIVATE SpdySynStreamIR
490 : public SpdyFrameWithNameValueBlockIR
{
492 explicit SpdySynStreamIR(SpdyStreamId stream_id
)
493 : SpdyFrameWithNameValueBlockIR(stream_id
),
494 associated_to_stream_id_(0),
497 unidirectional_(false) {}
498 SpdyStreamId
associated_to_stream_id() const {
499 return associated_to_stream_id_
;
501 void set_associated_to_stream_id(SpdyStreamId stream_id
) {
502 associated_to_stream_id_
= stream_id
;
504 SpdyPriority
priority() const { return priority_
; }
505 void set_priority(SpdyPriority priority
) { priority_
= priority
; }
506 SpdyCredentialSlot
slot() const { return slot_
; }
507 void set_slot(SpdyCredentialSlot slot
) { slot_
= slot
; }
508 bool unidirectional() const { return unidirectional_
; }
509 void set_unidirectional(bool unidirectional
) {
510 unidirectional_
= unidirectional
;
513 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
516 SpdyStreamId associated_to_stream_id_
;
517 SpdyPriority priority_
;
518 SpdyCredentialSlot slot_
;
519 bool unidirectional_
;
521 DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR
);
524 class SpdySynReplyIR
: public SpdyFrameWithNameValueBlockIR
{
526 explicit SpdySynReplyIR(SpdyStreamId stream_id
)
527 : SpdyFrameWithNameValueBlockIR(stream_id
) {}
529 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
532 DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR
);
535 class SpdyRstStreamIR
: public SpdyFrameWithStreamIdIR
{
537 SpdyRstStreamIR(SpdyStreamId stream_id
, SpdyRstStreamStatus status
)
538 : SpdyFrameWithStreamIdIR(stream_id
) {
541 SpdyRstStreamStatus
status() const {
544 void set_status(SpdyRstStreamStatus status
) {
545 DCHECK_NE(status
, RST_STREAM_INVALID
);
546 DCHECK_LT(status
, RST_STREAM_NUM_STATUS_CODES
);
550 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
553 SpdyRstStreamStatus status_
;
555 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR
);
558 class SpdySettingsIR
: public SpdyFrameIR
{
560 // Associates flags with a value.
562 Value() : persist_value(false),
569 typedef std::map
<SpdySettingsIds
, Value
> ValueMap
;
573 virtual ~SpdySettingsIR();
575 // Overwrites as appropriate.
576 const ValueMap
& values() const { return values_
; }
577 void AddSetting(SpdySettingsIds id
,
581 // TODO(hkhalil): DCHECK_LE(SETTINGS_UPLOAD_BANDWIDTH, id);
582 // TODO(hkhalil): DCHECK_GE(SETTINGS_INITIAL_WINDOW_SIZE, id);
583 values_
[id
].persist_value
= persist_value
;
584 values_
[id
].persisted
= persisted
;
585 values_
[id
].value
= value
;
587 bool clear_settings() const { return clear_settings_
; }
588 void set_clear_settings(bool clear_settings
) {
589 clear_settings_
= clear_settings
;
592 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
596 bool clear_settings_
;
598 DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR
);
601 class SpdyPingIR
: public SpdyFrameIR
{
603 explicit SpdyPingIR(SpdyPingId id
) : id_(id
) {}
604 SpdyPingId
id() const { return id_
; }
606 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
611 DISALLOW_COPY_AND_ASSIGN(SpdyPingIR
);
614 class SpdyGoAwayIR
: public SpdyFrameIR
{
616 SpdyGoAwayIR(SpdyStreamId last_good_stream_id
, SpdyGoAwayStatus status
) {
617 set_last_good_stream_id(last_good_stream_id
);
620 SpdyStreamId
last_good_stream_id() const { return last_good_stream_id_
; }
621 void set_last_good_stream_id(SpdyStreamId last_good_stream_id
) {
622 DCHECK_LE(0u, last_good_stream_id
);
623 DCHECK_EQ(0u, last_good_stream_id
& ~kStreamIdMask
);
624 last_good_stream_id_
= last_good_stream_id
;
626 SpdyGoAwayStatus
status() const { return status_
; }
627 void set_status(SpdyGoAwayStatus status
) {
628 // TODO(hkhalil): Check valid ranges of status?
632 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
635 SpdyStreamId last_good_stream_id_
;
636 SpdyGoAwayStatus status_
;
638 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR
);
641 class SpdyHeadersIR
: public SpdyFrameWithNameValueBlockIR
{
643 explicit SpdyHeadersIR(SpdyStreamId stream_id
)
644 : SpdyFrameWithNameValueBlockIR(stream_id
) {}
646 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
649 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR
);
652 class SpdyWindowUpdateIR
: public SpdyFrameWithStreamIdIR
{
654 SpdyWindowUpdateIR(SpdyStreamId stream_id
, int32 delta
)
655 : SpdyFrameWithStreamIdIR(stream_id
) {
658 int32
delta() const { return delta_
; }
659 void set_delta(int32 delta
) {
661 DCHECK_LE(delta
, kSpdyMaximumWindowSize
);
665 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
670 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR
);
673 class SpdyCredentialIR
: public SpdyFrameIR
{
675 typedef std::vector
<std::string
> CertificateList
;
677 explicit SpdyCredentialIR(int16 slot
);
678 virtual ~SpdyCredentialIR();
680 int16
slot() const { return slot_
; }
681 void set_slot(int16 slot
) {
682 // TODO(hkhalil): Verify valid slot range?
685 base::StringPiece
proof() const { return proof_
; }
686 void set_proof(const base::StringPiece
& proof
) {
687 proof
.CopyToString(&proof_
);
689 const CertificateList
* certificates() const { return &certificates_
; }
690 void AddCertificate(const base::StringPiece
& certificate
) {
691 certificates_
.push_back(certificate
.as_string());
694 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
699 CertificateList certificates_
;
701 DISALLOW_COPY_AND_ASSIGN(SpdyCredentialIR
);
704 class NET_EXPORT_PRIVATE SpdyBlockedIR
705 : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR
) {
707 explicit SpdyBlockedIR(SpdyStreamId stream_id
)
708 : SpdyFrameWithStreamIdIR(stream_id
) {}
710 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
713 DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR
);
716 class SpdyPushPromiseIR
: public SpdyFrameWithNameValueBlockIR
{
718 SpdyPushPromiseIR(SpdyStreamId stream_id
, SpdyStreamId promised_stream_id
)
719 : SpdyFrameWithNameValueBlockIR(stream_id
),
720 promised_stream_id_(promised_stream_id
) {}
721 SpdyStreamId
promised_stream_id() const { return promised_stream_id_
; }
722 void set_promised_stream_id(SpdyStreamId id
) { promised_stream_id_
= id
; }
724 virtual void Visit(SpdyFrameVisitor
* visitor
) const OVERRIDE
;
727 SpdyStreamId promised_stream_id_
;
728 DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR
);
732 // -------------------------------------------------------------------------
733 // Wrapper classes for various SPDY frames.
735 // All Spdy Frame types derive from this SpdyFrame class.
738 // Create a SpdyFrame using a pre-created buffer.
739 // If |owns_buffer| is true, this class takes ownership of the buffer
740 // and will delete it on cleanup. The buffer must have been created using
742 // If |owns_buffer| is false, the caller retains ownership of the buffer and
743 // is responsible for making sure the buffer outlives this frame. In other
744 // words, this class does NOT create a copy of the buffer.
745 SpdyFrame(char* data
, size_t size
, bool owns_buffer
)
748 owns_buffer_(owns_buffer
) {
759 // Provides access to the frame bytes, which is a buffer containing
760 // the frame packed as expected for sending over the wire.
761 char* data() const { return frame_
; }
763 // Returns the actual size of the underlying buffer.
764 size_t size() const { return size_
; }
772 DISALLOW_COPY_AND_ASSIGN(SpdyFrame
);
775 // This interface is for classes that want to process SpdyFrameIRs without
776 // having to know what type they are. An instance of this interface can be
777 // passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
778 // method of this class will be called.
779 class SpdyFrameVisitor
{
781 virtual void VisitSynStream(const SpdySynStreamIR
& syn_stream
) = 0;
782 virtual void VisitSynReply(const SpdySynReplyIR
& syn_reply
) = 0;
783 virtual void VisitRstStream(const SpdyRstStreamIR
& rst_stream
) = 0;
784 virtual void VisitSettings(const SpdySettingsIR
& settings
) = 0;
785 virtual void VisitPing(const SpdyPingIR
& ping
) = 0;
786 virtual void VisitGoAway(const SpdyGoAwayIR
& goaway
) = 0;
787 virtual void VisitHeaders(const SpdyHeadersIR
& headers
) = 0;
788 virtual void VisitWindowUpdate(const SpdyWindowUpdateIR
& window_update
) = 0;
789 virtual void VisitCredential(const SpdyCredentialIR
& credential
) = 0;
790 virtual void VisitBlocked(const SpdyBlockedIR
& blocked
) = 0;
791 virtual void VisitPushPromise(const SpdyPushPromiseIR
& push_promise
) = 0;
792 virtual void VisitData(const SpdyDataIR
& data
) = 0;
795 SpdyFrameVisitor() {}
796 virtual ~SpdyFrameVisitor() {}
799 DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor
);
804 #endif // NET_SPDY_SPDY_PROTOCOL_H_