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