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