Cast: Skip receiver log messages with time delta that can't be encoded.
[chromium-blink-merge.git] / net / spdy / spdy_protocol.h
bloba2358e7256c8b9e639ee8dfc3f507d4a39c4b9be
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_
14 #include <map>
15 #include <string>
16 #include <vector>
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"
27 namespace net {
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 {
34 SPDY2 = 2,
35 SPDY_MIN_VERSION = SPDY2,
36 SPDY3 = 3,
37 SPDY4 = 4,
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
45 // flow control).
46 const SpdyStreamId kSessionFlowControlStreamId = 0;
48 // Initial window size for a Spdy stream in bytes.
49 const int32 kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes
51 // Initial window size for a Spdy session in bytes.
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
57 // SPDY 2 dictionary.
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"
72 ".1statusversionurl";
73 const int kV2DictionarySize = arraysize(kV2Dictionary);
75 // SPDY 3 dictionary.
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.
273 enum SpdyFrameType {
274 DATA = 0,
275 SYN_STREAM = 1,
276 FIRST_CONTROL_TYPE = SYN_STREAM,
277 SYN_REPLY,
278 RST_STREAM,
279 SETTINGS,
280 NOOP, // Because it is valid in SPDY/2, kept for identifiability/enum order.
281 PING,
282 GOAWAY,
283 HEADERS,
284 WINDOW_UPDATE,
285 CREDENTIAL, // No longer valid. Kept for identifiability/enum order.
286 BLOCKED,
287 PUSH_PROMISE,
288 CONTINUATION,
289 LAST_CONTROL_TYPE = CONTINUATION
292 // Flags on data packets.
293 enum SpdyDataFlags {
294 DATA_FLAG_NONE = 0,
295 DATA_FLAG_FIN = 1,
298 // Flags on control packets
299 enum SpdyControlFlags {
300 CONTROL_FLAG_NONE = 0,
301 CONTROL_FLAG_FIN = 1,
302 CONTROL_FLAG_UNIDIRECTIONAL = 2
305 enum SpdyPingFlags {
306 PING_FLAG_ACK = 0x1,
309 enum SpdyHeadersFlags {
310 HEADERS_FLAG_END_HEADERS = 0x4,
311 HEADERS_FLAG_PRIORITY = 0x8
314 enum SpdyPushPromiseFlags {
315 PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x4
318 // Flags on the SETTINGS control frame.
319 enum SpdySettingsControlFlags {
320 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1
323 enum Http2SettingsControlFlags {
324 SETTINGS_FLAG_ACK = 0x1,
327 // Flags for settings within a SETTINGS frame.
328 enum SpdySettingsFlags {
329 SETTINGS_FLAG_NONE = 0x0,
330 SETTINGS_FLAG_PLEASE_PERSIST = 0x1,
331 SETTINGS_FLAG_PERSISTED = 0x2
334 // List of known settings.
335 enum SpdySettingsIds {
336 SETTINGS_UPLOAD_BANDWIDTH = 0x1,
337 SETTINGS_DOWNLOAD_BANDWIDTH = 0x2,
338 // Network round trip time in milliseconds.
339 SETTINGS_ROUND_TRIP_TIME = 0x3,
340 SETTINGS_MAX_CONCURRENT_STREAMS = 0x4,
341 // TCP congestion window in packets.
342 SETTINGS_CURRENT_CWND = 0x5,
343 // Downstream byte retransmission rate in percentage.
344 SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6,
345 // Initial window size in bytes
346 SETTINGS_INITIAL_WINDOW_SIZE = 0x7
349 // Status codes for RST_STREAM frames.
350 enum SpdyRstStreamStatus {
351 RST_STREAM_INVALID = 0,
352 RST_STREAM_PROTOCOL_ERROR = 1,
353 RST_STREAM_INVALID_STREAM = 2,
354 RST_STREAM_REFUSED_STREAM = 3,
355 RST_STREAM_UNSUPPORTED_VERSION = 4,
356 RST_STREAM_CANCEL = 5,
357 RST_STREAM_INTERNAL_ERROR = 6,
358 RST_STREAM_FLOW_CONTROL_ERROR = 7,
359 RST_STREAM_STREAM_IN_USE = 8,
360 RST_STREAM_STREAM_ALREADY_CLOSED = 9,
361 RST_STREAM_INVALID_CREDENTIALS = 10,
362 RST_STREAM_FRAME_TOO_LARGE = 11,
363 RST_STREAM_NUM_STATUS_CODES = 12
366 // Status codes for GOAWAY frames.
367 enum SpdyGoAwayStatus {
368 GOAWAY_INVALID = -1,
369 GOAWAY_OK = 0,
370 GOAWAY_PROTOCOL_ERROR = 1,
371 GOAWAY_INTERNAL_ERROR = 2,
372 GOAWAY_NUM_STATUS_CODES = 3 // Must be last.
375 // A SPDY priority is a number between 0 and 7 (inclusive).
376 // SPDY priority range is version-dependent. For SPDY 2 and below, priority is a
377 // number between 0 and 3.
378 typedef uint8 SpdyPriority;
380 typedef std::map<std::string, std::string> SpdyNameValueBlock;
382 typedef uint64 SpdyPingId;
384 class SpdyFrame;
385 typedef SpdyFrame SpdySerializedFrame;
387 class SpdyFrameVisitor;
389 // Intermediate representation for SPDY frames.
390 // TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
391 // gone.
392 class NET_EXPORT_PRIVATE SpdyFrameIR {
393 public:
394 virtual ~SpdyFrameIR() {}
396 virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
398 protected:
399 SpdyFrameIR() {}
401 private:
402 DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR);
405 // Abstract class intended to be inherited by IRs that have a stream associated
406 // to them.
407 class NET_EXPORT_PRIVATE SpdyFrameWithStreamIdIR : public SpdyFrameIR {
408 public:
409 virtual ~SpdyFrameWithStreamIdIR() {}
410 SpdyStreamId stream_id() const { return stream_id_; }
411 void set_stream_id(SpdyStreamId stream_id) {
412 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
413 stream_id_ = stream_id;
416 protected:
417 explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) {
418 set_stream_id(stream_id);
421 private:
422 SpdyStreamId stream_id_;
424 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR);
427 // Abstract class intended to be inherited by IRs that have the option of a FIN
428 // flag. Implies SpdyFrameWithStreamIdIR.
429 class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR {
430 public:
431 virtual ~SpdyFrameWithFinIR() {}
432 bool fin() const { return fin_; }
433 void set_fin(bool fin) { fin_ = fin; }
435 protected:
436 explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
437 : SpdyFrameWithStreamIdIR(stream_id),
438 fin_(false) {}
440 private:
441 bool fin_;
443 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR);
446 // Abstract class intended to be inherited by IRs that contain a name-value
447 // block. Implies SpdyFrameWithFinIR.
448 class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR
449 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
450 public:
451 const SpdyNameValueBlock& name_value_block() const {
452 return name_value_block_;
454 void set_name_value_block(const SpdyNameValueBlock& name_value_block) {
455 // Deep copy.
456 name_value_block_ = name_value_block;
458 void SetHeader(const base::StringPiece& name,
459 const base::StringPiece& value) {
460 name_value_block_[name.as_string()] = value.as_string();
463 protected:
464 explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id);
465 virtual ~SpdyFrameWithNameValueBlockIR();
467 private:
468 SpdyNameValueBlock name_value_block_;
470 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR);
473 class NET_EXPORT_PRIVATE SpdyDataIR
474 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
475 public:
476 // Performs deep copy on data.
477 SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data);
479 // Use in conjunction with SetDataShallow() for shallow-copy on data.
480 explicit SpdyDataIR(SpdyStreamId stream_id);
482 virtual ~SpdyDataIR();
484 base::StringPiece data() const { return data_; }
486 // Deep-copy of data (keep private copy).
487 void SetDataDeep(const base::StringPiece& data) {
488 data_store_.reset(new std::string(data.data(), data.length()));
489 data_ = *(data_store_.get());
492 // Shallow-copy of data (do not keep private copy).
493 void SetDataShallow(const base::StringPiece& data) {
494 data_store_.reset();
495 data_ = data;
498 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
500 private:
501 // Used to store data that this SpdyDataIR should own.
502 scoped_ptr<std::string> data_store_;
503 base::StringPiece data_;
505 DISALLOW_COPY_AND_ASSIGN(SpdyDataIR);
508 class NET_EXPORT_PRIVATE SpdySynStreamIR
509 : public SpdyFrameWithNameValueBlockIR {
510 public:
511 explicit SpdySynStreamIR(SpdyStreamId stream_id)
512 : SpdyFrameWithNameValueBlockIR(stream_id),
513 associated_to_stream_id_(0),
514 priority_(0),
515 unidirectional_(false) {}
516 SpdyStreamId associated_to_stream_id() const {
517 return associated_to_stream_id_;
519 void set_associated_to_stream_id(SpdyStreamId stream_id) {
520 associated_to_stream_id_ = stream_id;
522 SpdyPriority priority() const { return priority_; }
523 void set_priority(SpdyPriority priority) { priority_ = priority; }
524 bool unidirectional() const { return unidirectional_; }
525 void set_unidirectional(bool unidirectional) {
526 unidirectional_ = unidirectional;
529 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
531 private:
532 SpdyStreamId associated_to_stream_id_;
533 SpdyPriority priority_;
534 bool unidirectional_;
536 DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR);
539 class NET_EXPORT_PRIVATE SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR {
540 public:
541 explicit SpdySynReplyIR(SpdyStreamId stream_id)
542 : SpdyFrameWithNameValueBlockIR(stream_id) {}
544 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
546 private:
547 DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR);
550 class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
551 public:
552 SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status,
553 base::StringPiece description);
555 virtual ~SpdyRstStreamIR();
557 SpdyRstStreamStatus status() const {
558 return status_;
560 void set_status(SpdyRstStreamStatus status) {
561 DCHECK_NE(status, RST_STREAM_INVALID);
562 DCHECK_LT(status, RST_STREAM_NUM_STATUS_CODES);
563 status_ = status;
566 base::StringPiece description() const { return description_; }
568 void set_description(base::StringPiece description) {
569 description_ = description;
572 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
574 private:
575 SpdyRstStreamStatus status_;
576 base::StringPiece description_;
578 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
581 class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
582 public:
583 // Associates flags with a value.
584 struct Value {
585 Value() : persist_value(false),
586 persisted(false),
587 value(0) {}
588 bool persist_value;
589 bool persisted;
590 int32 value;
592 typedef std::map<SpdySettingsIds, Value> ValueMap;
594 SpdySettingsIR();
596 virtual ~SpdySettingsIR();
598 // Overwrites as appropriate.
599 const ValueMap& values() const { return values_; }
600 void AddSetting(SpdySettingsIds id,
601 bool persist_value,
602 bool persisted,
603 int32 value) {
604 // TODO(hkhalil): DCHECK_LE(SETTINGS_UPLOAD_BANDWIDTH, id);
605 // TODO(hkhalil): DCHECK_GE(SETTINGS_INITIAL_WINDOW_SIZE, id);
606 values_[id].persist_value = persist_value;
607 values_[id].persisted = persisted;
608 values_[id].value = value;
611 bool clear_settings() const { return clear_settings_; }
612 void set_clear_settings(bool clear_settings) {
613 clear_settings_ = clear_settings;
615 bool is_ack() const { return is_ack_; }
616 void set_is_ack(bool is_ack) {
617 is_ack_ = is_ack;
620 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
622 private:
623 ValueMap values_;
624 bool clear_settings_;
625 bool is_ack_;
627 DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR);
630 class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
631 public:
632 explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
633 SpdyPingId id() const { return id_; }
635 // ACK logic is valid only for SPDY versions 4 and above.
636 bool is_ack() const { return is_ack_; }
637 void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
639 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
641 private:
642 SpdyPingId id_;
643 bool is_ack_;
645 DISALLOW_COPY_AND_ASSIGN(SpdyPingIR);
648 class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
649 public:
650 SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status,
651 const base::StringPiece& description);
652 virtual ~SpdyGoAwayIR();
653 SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
654 void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
655 DCHECK_LE(0u, last_good_stream_id);
656 DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
657 last_good_stream_id_ = last_good_stream_id;
659 SpdyGoAwayStatus status() const { return status_; }
660 void set_status(SpdyGoAwayStatus status) {
661 // TODO(hkhalil): Check valid ranges of status?
662 status_ = status;
665 const base::StringPiece& description() const;
667 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
669 private:
670 SpdyStreamId last_good_stream_id_;
671 SpdyGoAwayStatus status_;
672 const base::StringPiece description_;
674 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR);
677 class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR {
678 public:
679 explicit SpdyHeadersIR(SpdyStreamId stream_id)
680 : SpdyFrameWithNameValueBlockIR(stream_id),
681 end_headers_(true),
682 has_priority_(false),
683 priority_(0) {}
685 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
687 bool end_headers() const { return end_headers_; }
688 void set_end_headers(bool end_headers) {end_headers_ = end_headers;}
689 bool has_priority() const { return has_priority_; }
690 void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
691 uint32 priority() const { return priority_; }
692 void set_priority(SpdyPriority priority) { priority_ = priority; }
694 private:
695 bool end_headers_;
696 bool has_priority_;
697 // 31-bit priority.
698 uint32 priority_;
699 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
702 class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
703 public:
704 SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta)
705 : SpdyFrameWithStreamIdIR(stream_id) {
706 set_delta(delta);
708 int32 delta() const { return delta_; }
709 void set_delta(int32 delta) {
710 DCHECK_LT(0, delta);
711 DCHECK_LE(delta, kSpdyMaximumWindowSize);
712 delta_ = delta;
715 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
717 private:
718 int32 delta_;
720 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR);
723 class NET_EXPORT_PRIVATE SpdyBlockedIR
724 : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR) {
725 public:
726 explicit SpdyBlockedIR(SpdyStreamId stream_id)
727 : SpdyFrameWithStreamIdIR(stream_id) {}
729 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
731 private:
732 DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR);
735 class NET_EXPORT_PRIVATE SpdyPushPromiseIR
736 : public SpdyFrameWithNameValueBlockIR {
737 public:
738 SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
739 : SpdyFrameWithNameValueBlockIR(stream_id),
740 promised_stream_id_(promised_stream_id),
741 end_push_promise_(true) {}
742 SpdyStreamId promised_stream_id() const { return promised_stream_id_; }
743 void set_promised_stream_id(SpdyStreamId id) { promised_stream_id_ = id; }
744 bool end_push_promise() const { return end_push_promise_; }
745 void set_end_push_promise(bool end_push_promise) {
746 end_push_promise_ = end_push_promise;
749 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
751 private:
752 SpdyStreamId promised_stream_id_;
753 bool end_push_promise_;
754 DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR);
757 class NET_EXPORT_PRIVATE SpdyContinuationIR
758 : public SpdyFrameWithNameValueBlockIR {
759 public:
760 explicit SpdyContinuationIR(SpdyStreamId stream_id)
761 : SpdyFrameWithNameValueBlockIR(stream_id),
762 end_headers_(false) {}
764 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
766 bool end_headers() const { return end_headers_; }
767 void set_end_headers(bool end_headers) {end_headers_ = end_headers;}
769 private:
770 bool end_headers_;
771 DISALLOW_COPY_AND_ASSIGN(SpdyContinuationIR);
774 // -------------------------------------------------------------------------
775 // Wrapper classes for various SPDY frames.
777 // All Spdy Frame types derive from this SpdyFrame class.
778 class SpdyFrame {
779 public:
780 // Create a SpdyFrame using a pre-created buffer.
781 // If |owns_buffer| is true, this class takes ownership of the buffer
782 // and will delete it on cleanup. The buffer must have been created using
783 // new char[].
784 // If |owns_buffer| is false, the caller retains ownership of the buffer and
785 // is responsible for making sure the buffer outlives this frame. In other
786 // words, this class does NOT create a copy of the buffer.
787 SpdyFrame(char* data, size_t size, bool owns_buffer)
788 : frame_(data),
789 size_(size),
790 owns_buffer_(owns_buffer) {
791 DCHECK(frame_);
794 ~SpdyFrame() {
795 if (owns_buffer_) {
796 delete [] frame_;
798 frame_ = NULL;
801 // Provides access to the frame bytes, which is a buffer containing
802 // the frame packed as expected for sending over the wire.
803 char* data() const { return frame_; }
805 // Returns the actual size of the underlying buffer.
806 size_t size() const { return size_; }
808 protected:
809 char* frame_;
811 private:
812 size_t size_;
813 bool owns_buffer_;
814 DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
817 // This interface is for classes that want to process SpdyFrameIRs without
818 // having to know what type they are. An instance of this interface can be
819 // passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
820 // method of this class will be called.
821 class SpdyFrameVisitor {
822 public:
823 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) = 0;
824 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) = 0;
825 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
826 virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
827 virtual void VisitPing(const SpdyPingIR& ping) = 0;
828 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
829 virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
830 virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
831 virtual void VisitBlocked(const SpdyBlockedIR& blocked) = 0;
832 virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0;
833 virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0;
834 virtual void VisitData(const SpdyDataIR& data) = 0;
836 protected:
837 SpdyFrameVisitor() {}
838 virtual ~SpdyFrameVisitor() {}
840 private:
841 DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor);
844 } // namespace net
846 #endif // NET_SPDY_SPDY_PROTOCOL_H_