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