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