spdy_protocol.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/string_piece.h"
23#include "base/sys_byteorder.h"
24#include "net/base/net_export.h"
25#include "net/spdy/spdy_bitmasks.h"
26
27namespace net {
28
29const int32 kSpdyVersion2 = 2;
30const int32 kSpdyVersion3 = 3;
31
32// A SPDY stream id is a 31 bit entity.
33typedef uint32 SpdyStreamId;
34
35// Specifies the stream ID used to denote the current session (for
36// flow control).
37const SpdyStreamId kSessionFlowControlStreamId = 0;
38
39// Initial window size for a Spdy stream.
40const int32 kSpdyStreamInitialWindowSize = 64 * 1024;  // 64 KBytes
41
42// Initial window size for a Spdy session.
43const int32 kSpdySessionInitialWindowSize = 64 * 1024;  // 64 KBytes
44
45// Maximum window size for a Spdy stream or session.
46const int32 kSpdyMaximumWindowSize = 0x7FFFFFFF;  // Max signed 32bit int
47
48// SPDY 2 dictionary.
49// This is just a hacked dictionary to use for shrinking HTTP-like headers.
50const char kV2Dictionary[] =
51  "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
52  "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
53  "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
54  "-agent10010120020120220320420520630030130230330430530630740040140240340440"
55  "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
56  "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
57  "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
58  "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
59  "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
60  "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
61  "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
62  "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
63  ".1statusversionurl";
64const int kV2DictionarySize = arraysize(kV2Dictionary);
65
66// SPDY 3 dictionary.
67const char kV3Dictionary[] = {
68  0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69,  // ....opti
69  0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68,  // ons....h
70  0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70,  // ead....p
71  0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70,  // ost....p
72  0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65,  // ut....de
73  0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05,  // lete....
74  0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00,  // trace...
75  0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00,  // .accept.
76  0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70,  // ...accep
77  0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,  // t-charse
78  0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63,  // t....acc
79  0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,  // ept-enco
80  0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f,  // ding....
81  0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c,  // accept-l
82  0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00,  // anguage.
83  0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70,  // ...accep
84  0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73,  // t-ranges
85  0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00,  // ....age.
86  0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77,  // ...allow
87  0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68,  // ....auth
88  0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,  // orizatio
89  0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63,  // n....cac
90  0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72,  // he-contr
91  0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f,  // ol....co
92  0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,  // nnection
93  0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
94  0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65,  // ent-base
95  0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
96  0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,  // ent-enco
97  0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10,  // ding....
98  0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,  // content-
99  0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,  // language
100  0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
101  0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67,  // ent-leng
102  0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f,  // th....co
103  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f,  // ntent-lo
104  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,  // cation..
105  0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,  // ..conten
106  0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00,  // t-md5...
107  0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,  // .content
108  0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00,  // -range..
109  0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,  // ..conten
110  0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00,  // t-type..
111  0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00,  // ..date..
112  0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00,  // ..etag..
113  0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,  // ..expect
114  0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69,  // ....expi
115  0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66,  // res....f
116  0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68,  // rom....h
117  0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69,  // ost....i
118  0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00,  // f-match.
119  0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f,  // ...if-mo
120  0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73,  // dified-s
121  0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d,  // ince....
122  0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d,  // if-none-
123  0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00,  // match...
124  0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67,  // .if-rang
125  0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d,  // e....if-
126  0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,  // unmodifi
127  0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65,  // ed-since
128  0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74,  // ....last
129  0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,  // -modifie
130  0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63,  // d....loc
131  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,  // ation...
132  0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72,  // .max-for
133  0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00,  // wards...
134  0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00,  // .pragma.
135  0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79,  // ...proxy
136  0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,  // -authent
137  0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,  // icate...
138  0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61,  // .proxy-a
139  0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,  // uthoriza
140  0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05,  // tion....
141  0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00,  // range...
142  0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72,  // .referer
143  0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72,  // ....retr
144  0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00,  // y-after.
145  0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,  // ...serve
146  0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00,  // r....te.
147  0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c,  // ...trail
148  0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72,  // er....tr
149  0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65,  // ansfer-e
150  0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00,  // ncoding.
151  0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61,  // ...upgra
152  0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73,  // de....us
153  0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,  // er-agent
154  0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79,  // ....vary
155  0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00,  // ....via.
156  0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69,  // ...warni
157  0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77,  // ng....ww
158  0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,  // w-authen
159  0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00,  // ticate..
160  0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,  // ..method
161  0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00,  // ....get.
162  0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,  // ...statu
163  0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30,  // s....200
164  0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76,  // .OK....v
165  0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00,  // ersion..
166  0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31,  // ..HTTP.1
167  0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72,  // .1....ur
168  0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62,  // l....pub
169  0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73,  // lic....s
170  0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69,  // et-cooki
171  0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65,  // e....kee
172  0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00,  // p-alive.
173  0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69,  // ...origi
174  0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32,  // n1001012
175  0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35,  // 01202205
176  0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30,  // 20630030
177  0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33,  // 23033043
178  0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37,  // 05306307
179  0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30,  // 40240540
180  0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34,  // 64074084
181  0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31,  // 09410411
182  0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31,  // 41241341
183  0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34,  // 44154164
184  0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34,  // 17502504
185  0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e,  // 505203.N
186  0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f,  // on-Autho
187  0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65,  // ritative
188  0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,  // .Informa
189  0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20,  // tion204.
190  0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65,  // No.Conte
191  0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f,  // nt301.Mo
192  0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d,  // ved.Perm
193  0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34,  // anently4
194  0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52,  // 00.Bad.R
195  0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30,  // equest40
196  0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68,  // 1.Unauth
197  0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30,  // orized40
198  0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64,  // 3.Forbid
199  0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e,  // den404.N
200  0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64,  // ot.Found
201  0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65,  // 500.Inte
202  0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,  // rnal.Ser
203  0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f,  // ver.Erro
204  0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74,  // r501.Not
205  0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65,  // .Impleme
206  0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20,  // nted503.
207  0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20,  // Service.
208  0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,  // Unavaila
209  0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46,  // bleJan.F
210  0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41,  // eb.Mar.A
211  0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a,  // pr.May.J
212  0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41,  // un.Jul.A
213  0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20,  // ug.Sept.
214  0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20,  // Oct.Nov.
215  0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30,  // Dec.00.0
216  0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e,  // 0.00.Mon
217  0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57,  // ..Tue..W
218  0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c,  // ed..Thu.
219  0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61,  // .Fri..Sa
220  0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20,  // t..Sun..
221  0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b,  // GMTchunk
222  0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f,  // ed.text.
223  0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61,  // html.ima
224  0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69,  // ge.png.i
225  0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67,  // mage.jpg
226  0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67,  // .image.g
227  0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,  // if.appli
228  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,  // cation.x
229  0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,  // ml.appli
230  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,  // cation.x
231  0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c,  // html.xml
232  0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c,  // .text.pl
233  0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74,  // ain.text
234  0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72,  // .javascr
235  0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c,  // ipt.publ
236  0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,  // icprivat
237  0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65,  // emax-age
238  0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65,  // .gzip.de
239  0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64,  // flate.sd
240  0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,  // chcharse
241  0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63,  // t.utf-8c
242  0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69,  // harset.i
243  0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d,  // so-8859-
244  0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a,  // 1.utf-..
245  0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e         // .enq.0.
246};
247const int kV3DictionarySize = arraysize(kV3Dictionary);
248
249// Note: all protocol data structures are on-the-wire format.  That means that
250//       data is stored in network-normalized order.  Readers must use the
251//       accessors provided or call base::NetworkToHostX() functions.
252// TODO(hkhalil): remove above note.
253
254// Types of Spdy Control Frames.
255enum SpdyControlType {
256  SYN_STREAM = 1,
257  SYN_REPLY,
258  RST_STREAM,
259  SETTINGS,
260  NOOP,  // Because it is valid in SPDY/2, kept for identifiability/enum order.
261  PING,
262  GOAWAY,
263  HEADERS,
264  WINDOW_UPDATE,
265  CREDENTIAL,
266  NUM_CONTROL_FRAME_TYPES
267};
268
269// Flags on data packets.
270enum SpdyDataFlags {
271  DATA_FLAG_NONE = 0,
272  DATA_FLAG_FIN = 1,
273};
274
275// Flags on control packets
276enum SpdyControlFlags {
277  CONTROL_FLAG_NONE = 0,
278  CONTROL_FLAG_FIN = 1,
279  CONTROL_FLAG_UNIDIRECTIONAL = 2
280};
281
282// Flags on the SETTINGS control frame.
283enum SpdySettingsControlFlags {
284  SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1
285};
286
287// Flags for settings within a SETTINGS frame.
288enum SpdySettingsFlags {
289  SETTINGS_FLAG_NONE = 0x0,
290  SETTINGS_FLAG_PLEASE_PERSIST = 0x1,
291  SETTINGS_FLAG_PERSISTED = 0x2
292};
293
294// List of known settings.
295enum SpdySettingsIds {
296  SETTINGS_UPLOAD_BANDWIDTH = 0x1,
297  SETTINGS_DOWNLOAD_BANDWIDTH = 0x2,
298  // Network round trip time in milliseconds.
299  SETTINGS_ROUND_TRIP_TIME = 0x3,
300  SETTINGS_MAX_CONCURRENT_STREAMS = 0x4,
301  // TCP congestion window in packets.
302  SETTINGS_CURRENT_CWND = 0x5,
303  // Downstream byte retransmission rate in percentage.
304  SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6,
305  // Initial window size in bytes
306  SETTINGS_INITIAL_WINDOW_SIZE = 0x7
307};
308
309// Status codes for RST_STREAM frames.
310enum SpdyRstStreamStatus {
311  RST_STREAM_INVALID = 0,
312  RST_STREAM_PROTOCOL_ERROR = 1,
313  RST_STREAM_INVALID_STREAM = 2,
314  RST_STREAM_REFUSED_STREAM = 3,
315  RST_STREAM_UNSUPPORTED_VERSION = 4,
316  RST_STREAM_CANCEL = 5,
317  RST_STREAM_INTERNAL_ERROR = 6,
318  RST_STREAM_FLOW_CONTROL_ERROR = 7,
319  RST_STREAM_STREAM_IN_USE = 8,
320  RST_STREAM_STREAM_ALREADY_CLOSED = 9,
321  RST_STREAM_INVALID_CREDENTIALS = 10,
322  RST_STREAM_FRAME_TOO_LARGE = 11,
323  RST_STREAM_NUM_STATUS_CODES = 12
324};
325
326// Status codes for GOAWAY frames.
327enum SpdyGoAwayStatus {
328  GOAWAY_INVALID = -1,
329  GOAWAY_OK = 0,
330  GOAWAY_PROTOCOL_ERROR = 1,
331  GOAWAY_INTERNAL_ERROR = 2,
332  GOAWAY_NUM_STATUS_CODES = 3
333};
334
335// A SPDY priority is a number between 0 and 7 (inclusive).
336// SPDY priority range is version-dependant. For SPDY 2 and below, priority is a
337// number between 0 and 3.
338typedef uint8 SpdyPriority;
339
340typedef uint8 SpdyCredentialSlot;
341
342typedef std::map<std::string, std::string> SpdyNameValueBlock;
343
344typedef uint32 SpdyPingId;
345
346class SpdyFrame;
347typedef SpdyFrame SpdySerializedFrame;
348
349class SpdyFramer;
350class SpdyFrameBuilder;
351
352// Intermediate representation for SPDY frames.
353// TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
354// gone.
355class SpdyFrameIR {
356 public:
357  virtual ~SpdyFrameIR() {}
358
359 protected:
360  SpdyFrameIR() {}
361
362 private:
363  DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR);
364};
365
366// Abstract class intended to be inherited by IRs that have a stream associated
367// to them.
368class SpdyFrameWithStreamIdIR : public SpdyFrameIR {
369 public:
370  virtual ~SpdyFrameWithStreamIdIR() {}
371  SpdyStreamId stream_id() const { return stream_id_; }
372  void set_stream_id(SpdyStreamId stream_id) {
373    // TODO(hkhalil): DCHECK_LT(0u, stream_id);
374    DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
375    stream_id_ = stream_id;
376  }
377
378 protected:
379  explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) {
380    set_stream_id(stream_id);
381  }
382
383 private:
384  SpdyStreamId stream_id_;
385
386  DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR);
387};
388
389// Abstract class intended to be inherited by IRs that have the option of a FIN
390// flag. Implies SpdyFrameWithStreamIdIR.
391class SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR {
392 public:
393  virtual ~SpdyFrameWithFinIR() {}
394  bool fin() const { return fin_; }
395  void set_fin(bool fin) { fin_ = fin; }
396
397 protected:
398  explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
399      : SpdyFrameWithStreamIdIR(stream_id),
400        fin_(false) {}
401
402 private:
403  bool fin_;
404
405  DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR);
406};
407
408// Abstract class intended to be inherited by IRs that contain a name-value
409// block. Implies SpdyFrameWithFinIR.
410class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR
411    : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
412 public:
413  const SpdyNameValueBlock& name_value_block() const {
414    return name_value_block_;
415  }
416  SpdyNameValueBlock* GetMutableNameValueBlock() { return &name_value_block_; }
417  void SetHeader(const base::StringPiece& name,
418                 const base::StringPiece& value) {
419    name_value_block_[name.as_string()] = value.as_string();
420  }
421
422 protected:
423  explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id);
424  virtual ~SpdyFrameWithNameValueBlockIR();
425
426 private:
427  SpdyNameValueBlock name_value_block_;
428
429  DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR);
430};
431
432class NET_EXPORT_PRIVATE SpdyDataIR
433    : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
434 public:
435  // Performs deep copy on data.
436  SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data);
437
438  // Use in conjunction with SetDataShallow() for shallow-copy on data.
439  explicit SpdyDataIR(SpdyStreamId stream_id);
440
441  virtual ~SpdyDataIR();
442
443  base::StringPiece data() const { return data_; }
444
445  // Deep-copy of data (keep private copy).
446  void SetDataDeep(const base::StringPiece& data) {
447    data_store_.reset(new std::string(data.data(), data.length()));
448    data_ = *(data_store_.get());
449  }
450
451  // Shallow-copy of data (do not keep private copy).
452  void SetDataShallow(const base::StringPiece& data) {
453    data_store_.reset();
454    data_ = data;
455  }
456
457 private:
458  // Used to store data that this SpdyDataIR should own.
459  scoped_ptr<std::string> data_store_;
460  base::StringPiece data_;
461
462  DISALLOW_COPY_AND_ASSIGN(SpdyDataIR);
463};
464
465class SpdySynStreamIR : public SpdyFrameWithNameValueBlockIR {
466 public:
467  explicit SpdySynStreamIR(SpdyStreamId stream_id)
468      : SpdyFrameWithNameValueBlockIR(stream_id),
469        associated_to_stream_id_(0),
470        priority_(0),
471        slot_(0),
472        unidirectional_(false) {}
473  SpdyStreamId associated_to_stream_id() const {
474    return associated_to_stream_id_;
475  }
476  void set_associated_to_stream_id(SpdyStreamId stream_id) {
477    associated_to_stream_id_ = stream_id;
478  }
479  SpdyPriority priority() const { return priority_; }
480  void set_priority(SpdyPriority priority) { priority_ = priority; }
481  SpdyCredentialSlot slot() const { return slot_; }
482  void set_slot(SpdyCredentialSlot slot) { slot_ = slot; }
483  bool unidirectional() const { return unidirectional_; }
484  void set_unidirectional(bool unidirectional) {
485    unidirectional_ = unidirectional;
486  }
487
488 private:
489  SpdyStreamId associated_to_stream_id_;
490  SpdyPriority priority_;
491  SpdyCredentialSlot slot_;
492  bool unidirectional_;
493
494  DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR);
495};
496
497class SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR {
498 public:
499  explicit SpdySynReplyIR(SpdyStreamId stream_id)
500      : SpdyFrameWithNameValueBlockIR(stream_id) {}
501
502 private:
503  DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR);
504};
505
506class SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
507 public:
508  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status)
509      : SpdyFrameWithStreamIdIR(stream_id) {
510    set_status(status);
511  }
512  SpdyRstStreamStatus status() const {
513    return status_;
514  }
515  void set_status(SpdyRstStreamStatus status) {
516    DCHECK_NE(status, RST_STREAM_INVALID);
517    DCHECK_LT(status, RST_STREAM_NUM_STATUS_CODES);
518    status_ = status;
519  }
520
521 private:
522  SpdyRstStreamStatus status_;
523
524  DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
525};
526
527class SpdySettingsIR : public SpdyFrameIR {
528 public:
529  // Associates flags with a value.
530  struct Value {
531    Value() : persist_value(false),
532              persisted(false),
533              value(0) {}
534    bool persist_value;
535    bool persisted;
536    int32 value;
537  };
538  typedef std::map<SpdySettingsIds, Value> ValueMap;
539
540  SpdySettingsIR();
541
542  virtual ~SpdySettingsIR();
543
544  // Overwrites as appropriate.
545  const ValueMap& values() const { return values_; }
546  void AddSetting(SpdySettingsIds id,
547                  bool persist_value,
548                  bool persisted,
549                  int32 value) {
550    // TODO(hkhalil): DCHECK_LE(SETTINGS_UPLOAD_BANDWIDTH, id);
551    // TODO(hkhalil): DCHECK_GE(SETTINGS_INITIAL_WINDOW_SIZE, id);
552    values_[id].persist_value = persist_value;
553    values_[id].persisted = persisted;
554    values_[id].value = value;
555  }
556  bool clear_settings() const { return clear_settings_; }
557  void set_clear_settings(bool clear_settings) {
558    clear_settings_ = clear_settings;
559  }
560
561 private:
562  ValueMap values_;
563  bool clear_settings_;
564
565  DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR);
566};
567
568class SpdyPingIR : public SpdyFrameIR {
569 public:
570  explicit SpdyPingIR(SpdyPingId id) : id_(id) {}
571  SpdyPingId id() const { return id_; }
572
573 private:
574  SpdyPingId id_;
575
576  DISALLOW_COPY_AND_ASSIGN(SpdyPingIR);
577};
578
579class SpdyGoAwayIR : public SpdyFrameIR {
580 public:
581  SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status) {
582    set_last_good_stream_id(last_good_stream_id);
583    set_status(status);
584  }
585  SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
586  void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
587    DCHECK_LE(0u, last_good_stream_id);
588    DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
589    last_good_stream_id_ = last_good_stream_id;
590  }
591  SpdyGoAwayStatus status() const { return status_; }
592  void set_status(SpdyGoAwayStatus status) {
593    // TODO(hkhalil): Check valid ranges of status?
594    status_ = status;
595  }
596
597 private:
598  SpdyStreamId last_good_stream_id_;
599  SpdyGoAwayStatus status_;
600
601  DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR);
602};
603
604class SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR {
605 public:
606  explicit SpdyHeadersIR(SpdyStreamId stream_id)
607      : SpdyFrameWithNameValueBlockIR(stream_id) {}
608
609 private:
610  DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
611};
612
613class SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
614 public:
615  SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta)
616      : SpdyFrameWithStreamIdIR(stream_id) {
617    set_delta(delta);
618  }
619  int32 delta() const { return delta_; }
620  void set_delta(int32 delta) {
621    DCHECK_LT(0, delta);
622    DCHECK_LE(delta, kSpdyMaximumWindowSize);
623    delta_ = delta;
624  }
625
626 private:
627  int32 delta_;
628
629  DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR);
630};
631
632class SpdyCredentialIR : public SpdyFrameIR {
633 public:
634  typedef std::vector<std::string> CertificateList;
635
636  explicit SpdyCredentialIR(int16 slot);
637  virtual ~SpdyCredentialIR();
638
639  int16 slot() const { return slot_; }
640  void set_slot(int16 slot) {
641    // TODO(hkhalil): Verify valid slot range?
642    slot_ = slot;
643  }
644  base::StringPiece proof() const { return proof_; }
645  void set_proof(const base::StringPiece& proof) {
646    proof.CopyToString(&proof_);
647  }
648  const CertificateList* certificates() const { return &certificates_; }
649  void AddCertificate(const base::StringPiece& certificate) {
650    certificates_.push_back(certificate.as_string());
651  }
652
653 private:
654  int16 slot_;
655  std::string proof_;
656  CertificateList certificates_;
657
658  DISALLOW_COPY_AND_ASSIGN(SpdyCredentialIR);
659};
660
661// -------------------------------------------------------------------------
662// Wrapper classes for various SPDY frames.
663
664// All Spdy Frame types derive from this SpdyFrame class.
665class SpdyFrame {
666 public:
667  // Create a SpdyFrame using a pre-created buffer.
668  // If |owns_buffer| is true, this class takes ownership of the buffer
669  // and will delete it on cleanup.  The buffer must have been created using
670  // new char[].
671  // If |owns_buffer| is false, the caller retains ownership of the buffer and
672  // is responsible for making sure the buffer outlives this frame.  In other
673  // words, this class does NOT create a copy of the buffer.
674  SpdyFrame(char* data, size_t size, bool owns_buffer)
675      : frame_(data),
676        size_(size),
677        owns_buffer_(owns_buffer) {
678    DCHECK(frame_);
679  }
680
681  ~SpdyFrame() {
682    if (owns_buffer_) {
683      delete [] frame_;
684    }
685    frame_ = NULL;
686  }
687
688  // Provides access to the frame bytes, which is a buffer containing
689  // the frame packed as expected for sending over the wire.
690  char* data() const { return frame_; }
691
692  // Returns the actual size of the underlying buffer.
693  size_t size() const { return size_; }
694
695 protected:
696  char* frame_;
697
698 private:
699  size_t size_;
700  bool owns_buffer_;
701  DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
702};
703
704}  // namespace net
705
706#endif  // NET_SPDY_SPDY_PROTOCOL_H_
707