spdy_protocol.h revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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 CONTINUATION, 289 LAST_CONTROL_TYPE = CONTINUATION 290}; 291 292// Flags on data packets. 293enum SpdyDataFlags { 294 DATA_FLAG_NONE = 0, 295 DATA_FLAG_FIN = 1, 296}; 297 298// Flags on control packets 299enum SpdyControlFlags { 300 CONTROL_FLAG_NONE = 0, 301 CONTROL_FLAG_FIN = 1, 302 CONTROL_FLAG_UNIDIRECTIONAL = 2 303}; 304 305enum SpdyPingFlags { 306 PING_FLAG_ACK = 0x1, 307}; 308 309enum SpdyHeadersFlags { 310 HEADERS_FLAG_END_HEADERS = 0x4, 311 HEADERS_FLAG_PRIORITY = 0x8 312}; 313 314enum SpdyPushPromiseFlags { 315 PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x4 316}; 317 318// Flags on the SETTINGS control frame. 319enum SpdySettingsControlFlags { 320 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1 321}; 322 323enum Http2SettingsControlFlags { 324 SETTINGS_FLAG_ACK = 0x1, 325}; 326 327// Flags for settings within a SETTINGS frame. 328enum SpdySettingsFlags { 329 SETTINGS_FLAG_NONE = 0x0, 330 SETTINGS_FLAG_PLEASE_PERSIST = 0x1, 331 SETTINGS_FLAG_PERSISTED = 0x2 332}; 333 334// List of known settings. 335enum SpdySettingsIds { 336 SETTINGS_UPLOAD_BANDWIDTH = 0x1, 337 SETTINGS_DOWNLOAD_BANDWIDTH = 0x2, 338 // Network round trip time in milliseconds. 339 SETTINGS_ROUND_TRIP_TIME = 0x3, 340 SETTINGS_MAX_CONCURRENT_STREAMS = 0x4, 341 // TCP congestion window in packets. 342 SETTINGS_CURRENT_CWND = 0x5, 343 // Downstream byte retransmission rate in percentage. 344 SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6, 345 // Initial window size in bytes 346 SETTINGS_INITIAL_WINDOW_SIZE = 0x7 347}; 348 349// Status codes for RST_STREAM frames. 350enum SpdyRstStreamStatus { 351 RST_STREAM_INVALID = 0, 352 RST_STREAM_PROTOCOL_ERROR = 1, 353 RST_STREAM_INVALID_STREAM = 2, 354 RST_STREAM_REFUSED_STREAM = 3, 355 RST_STREAM_UNSUPPORTED_VERSION = 4, 356 RST_STREAM_CANCEL = 5, 357 RST_STREAM_INTERNAL_ERROR = 6, 358 RST_STREAM_FLOW_CONTROL_ERROR = 7, 359 RST_STREAM_STREAM_IN_USE = 8, 360 RST_STREAM_STREAM_ALREADY_CLOSED = 9, 361 RST_STREAM_INVALID_CREDENTIALS = 10, 362 RST_STREAM_FRAME_TOO_LARGE = 11, 363 RST_STREAM_NUM_STATUS_CODES = 12 364}; 365 366// Status codes for GOAWAY frames. 367enum SpdyGoAwayStatus { 368 GOAWAY_INVALID = -1, 369 GOAWAY_OK = 0, 370 GOAWAY_PROTOCOL_ERROR = 1, 371 GOAWAY_INTERNAL_ERROR = 2, 372 GOAWAY_NUM_STATUS_CODES = 3 // Must be last. 373}; 374 375// A SPDY priority is a number between 0 and 7 (inclusive). 376// SPDY priority range is version-dependent. For SPDY 2 and below, priority is a 377// number between 0 and 3. 378typedef uint8 SpdyPriority; 379 380typedef std::map<std::string, std::string> SpdyNameValueBlock; 381 382typedef uint64 SpdyPingId; 383 384class SpdyFrame; 385typedef SpdyFrame SpdySerializedFrame; 386 387class SpdyFrameVisitor; 388 389// Intermediate representation for SPDY frames. 390// TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is 391// gone. 392class NET_EXPORT_PRIVATE SpdyFrameIR { 393 public: 394 virtual ~SpdyFrameIR() {} 395 396 virtual void Visit(SpdyFrameVisitor* visitor) const = 0; 397 398 protected: 399 SpdyFrameIR() {} 400 401 private: 402 DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR); 403}; 404 405// Abstract class intended to be inherited by IRs that have a stream associated 406// to them. 407class NET_EXPORT_PRIVATE SpdyFrameWithStreamIdIR : public SpdyFrameIR { 408 public: 409 virtual ~SpdyFrameWithStreamIdIR() {} 410 SpdyStreamId stream_id() const { return stream_id_; } 411 void set_stream_id(SpdyStreamId stream_id) { 412 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 413 stream_id_ = stream_id; 414 } 415 416 protected: 417 explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) { 418 set_stream_id(stream_id); 419 } 420 421 private: 422 SpdyStreamId stream_id_; 423 424 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR); 425}; 426 427// Abstract class intended to be inherited by IRs that have the option of a FIN 428// flag. Implies SpdyFrameWithStreamIdIR. 429class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR { 430 public: 431 virtual ~SpdyFrameWithFinIR() {} 432 bool fin() const { return fin_; } 433 void set_fin(bool fin) { fin_ = fin; } 434 435 protected: 436 explicit SpdyFrameWithFinIR(SpdyStreamId stream_id) 437 : SpdyFrameWithStreamIdIR(stream_id), 438 fin_(false) {} 439 440 private: 441 bool fin_; 442 443 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR); 444}; 445 446// Abstract class intended to be inherited by IRs that contain a name-value 447// block. Implies SpdyFrameWithFinIR. 448class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR 449 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { 450 public: 451 const SpdyNameValueBlock& name_value_block() const { 452 return name_value_block_; 453 } 454 void set_name_value_block(const SpdyNameValueBlock& name_value_block) { 455 // Deep copy. 456 name_value_block_ = name_value_block; 457 } 458 void SetHeader(const base::StringPiece& name, 459 const base::StringPiece& value) { 460 name_value_block_[name.as_string()] = value.as_string(); 461 } 462 463 protected: 464 explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id); 465 virtual ~SpdyFrameWithNameValueBlockIR(); 466 467 private: 468 SpdyNameValueBlock name_value_block_; 469 470 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR); 471}; 472 473class NET_EXPORT_PRIVATE SpdyDataIR 474 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { 475 public: 476 // Performs deep copy on data. 477 SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data); 478 479 // Use in conjunction with SetDataShallow() for shallow-copy on data. 480 explicit SpdyDataIR(SpdyStreamId stream_id); 481 482 virtual ~SpdyDataIR(); 483 484 base::StringPiece data() const { return data_; } 485 486 // Deep-copy of data (keep private copy). 487 void SetDataDeep(const base::StringPiece& data) { 488 data_store_.reset(new std::string(data.data(), data.length())); 489 data_ = *(data_store_.get()); 490 } 491 492 // Shallow-copy of data (do not keep private copy). 493 void SetDataShallow(const base::StringPiece& data) { 494 data_store_.reset(); 495 data_ = data; 496 } 497 498 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 499 500 private: 501 // Used to store data that this SpdyDataIR should own. 502 scoped_ptr<std::string> data_store_; 503 base::StringPiece data_; 504 505 DISALLOW_COPY_AND_ASSIGN(SpdyDataIR); 506}; 507 508class NET_EXPORT_PRIVATE SpdySynStreamIR 509 : public SpdyFrameWithNameValueBlockIR { 510 public: 511 explicit SpdySynStreamIR(SpdyStreamId stream_id) 512 : SpdyFrameWithNameValueBlockIR(stream_id), 513 associated_to_stream_id_(0), 514 priority_(0), 515 unidirectional_(false) {} 516 SpdyStreamId associated_to_stream_id() const { 517 return associated_to_stream_id_; 518 } 519 void set_associated_to_stream_id(SpdyStreamId stream_id) { 520 associated_to_stream_id_ = stream_id; 521 } 522 SpdyPriority priority() const { return priority_; } 523 void set_priority(SpdyPriority priority) { priority_ = priority; } 524 bool unidirectional() const { return unidirectional_; } 525 void set_unidirectional(bool unidirectional) { 526 unidirectional_ = unidirectional; 527 } 528 529 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 530 531 private: 532 SpdyStreamId associated_to_stream_id_; 533 SpdyPriority priority_; 534 bool unidirectional_; 535 536 DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR); 537}; 538 539class NET_EXPORT_PRIVATE SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR { 540 public: 541 explicit SpdySynReplyIR(SpdyStreamId stream_id) 542 : SpdyFrameWithNameValueBlockIR(stream_id) {} 543 544 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 545 546 private: 547 DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR); 548}; 549 550class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR { 551 public: 552 SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status, 553 base::StringPiece description); 554 555 virtual ~SpdyRstStreamIR(); 556 557 SpdyRstStreamStatus status() const { 558 return status_; 559 } 560 void set_status(SpdyRstStreamStatus status) { 561 DCHECK_NE(status, RST_STREAM_INVALID); 562 DCHECK_LT(status, RST_STREAM_NUM_STATUS_CODES); 563 status_ = status; 564 } 565 566 base::StringPiece description() const { return description_; } 567 568 void set_description(base::StringPiece description) { 569 description_ = description; 570 } 571 572 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 573 574 private: 575 SpdyRstStreamStatus status_; 576 base::StringPiece description_; 577 578 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR); 579}; 580 581class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR { 582 public: 583 // Associates flags with a value. 584 struct Value { 585 Value() : persist_value(false), 586 persisted(false), 587 value(0) {} 588 bool persist_value; 589 bool persisted; 590 int32 value; 591 }; 592 typedef std::map<SpdySettingsIds, Value> ValueMap; 593 594 SpdySettingsIR(); 595 596 virtual ~SpdySettingsIR(); 597 598 // Overwrites as appropriate. 599 const ValueMap& values() const { return values_; } 600 void AddSetting(SpdySettingsIds id, 601 bool persist_value, 602 bool persisted, 603 int32 value) { 604 // TODO(hkhalil): DCHECK_LE(SETTINGS_UPLOAD_BANDWIDTH, id); 605 // TODO(hkhalil): DCHECK_GE(SETTINGS_INITIAL_WINDOW_SIZE, id); 606 values_[id].persist_value = persist_value; 607 values_[id].persisted = persisted; 608 values_[id].value = value; 609 } 610 611 bool clear_settings() const { return clear_settings_; } 612 void set_clear_settings(bool clear_settings) { 613 clear_settings_ = clear_settings; 614 } 615 bool is_ack() const { return is_ack_; } 616 void set_is_ack(bool is_ack) { 617 is_ack_ = is_ack; 618 } 619 620 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 621 622 private: 623 ValueMap values_; 624 bool clear_settings_; 625 bool is_ack_; 626 627 DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR); 628}; 629 630class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR { 631 public: 632 explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {} 633 SpdyPingId id() const { return id_; } 634 635 // ACK logic is valid only for SPDY versions 4 and above. 636 bool is_ack() const { return is_ack_; } 637 void set_is_ack(bool is_ack) { is_ack_ = is_ack; } 638 639 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 640 641 private: 642 SpdyPingId id_; 643 bool is_ack_; 644 645 DISALLOW_COPY_AND_ASSIGN(SpdyPingIR); 646}; 647 648class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR { 649 public: 650 SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status, 651 const base::StringPiece& description); 652 virtual ~SpdyGoAwayIR(); 653 SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; } 654 void set_last_good_stream_id(SpdyStreamId last_good_stream_id) { 655 DCHECK_LE(0u, last_good_stream_id); 656 DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask); 657 last_good_stream_id_ = last_good_stream_id; 658 } 659 SpdyGoAwayStatus status() const { return status_; } 660 void set_status(SpdyGoAwayStatus status) { 661 // TODO(hkhalil): Check valid ranges of status? 662 status_ = status; 663 } 664 665 const base::StringPiece& description() const; 666 667 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 668 669 private: 670 SpdyStreamId last_good_stream_id_; 671 SpdyGoAwayStatus status_; 672 const base::StringPiece description_; 673 674 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR); 675}; 676 677class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR { 678 public: 679 explicit SpdyHeadersIR(SpdyStreamId stream_id) 680 : SpdyFrameWithNameValueBlockIR(stream_id), 681 end_headers_(true), 682 has_priority_(false), 683 priority_(0) {} 684 685 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 686 687 bool end_headers() const { return end_headers_; } 688 void set_end_headers(bool end_headers) {end_headers_ = end_headers;} 689 bool has_priority() const { return has_priority_; } 690 void set_has_priority(bool has_priority) { has_priority_ = has_priority; } 691 uint32 priority() const { return priority_; } 692 void set_priority(SpdyPriority priority) { priority_ = priority; } 693 694 private: 695 bool end_headers_; 696 bool has_priority_; 697 // 31-bit priority. 698 uint32 priority_; 699 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR); 700}; 701 702class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR { 703 public: 704 SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta) 705 : SpdyFrameWithStreamIdIR(stream_id) { 706 set_delta(delta); 707 } 708 int32 delta() const { return delta_; } 709 void set_delta(int32 delta) { 710 DCHECK_LT(0, delta); 711 DCHECK_LE(delta, kSpdyMaximumWindowSize); 712 delta_ = delta; 713 } 714 715 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 716 717 private: 718 int32 delta_; 719 720 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR); 721}; 722 723class NET_EXPORT_PRIVATE SpdyBlockedIR 724 : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR) { 725 public: 726 explicit SpdyBlockedIR(SpdyStreamId stream_id) 727 : SpdyFrameWithStreamIdIR(stream_id) {} 728 729 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 730 731 private: 732 DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR); 733}; 734 735class NET_EXPORT_PRIVATE SpdyPushPromiseIR 736 : public SpdyFrameWithNameValueBlockIR { 737 public: 738 SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id) 739 : SpdyFrameWithNameValueBlockIR(stream_id), 740 promised_stream_id_(promised_stream_id), 741 end_push_promise_(true) {} 742 SpdyStreamId promised_stream_id() const { return promised_stream_id_; } 743 void set_promised_stream_id(SpdyStreamId id) { promised_stream_id_ = id; } 744 bool end_push_promise() const { return end_push_promise_; } 745 void set_end_push_promise(bool end_push_promise) { 746 end_push_promise_ = end_push_promise; 747 } 748 749 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 750 751 private: 752 SpdyStreamId promised_stream_id_; 753 bool end_push_promise_; 754 DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR); 755}; 756 757// TODO(jgraettinger): This representation needs review. SpdyContinuationIR 758// needs to frame a portion of a single, arbitrarily-broken encoded buffer. 759class NET_EXPORT_PRIVATE SpdyContinuationIR 760 : public SpdyFrameWithNameValueBlockIR { 761 public: 762 explicit SpdyContinuationIR(SpdyStreamId stream_id) 763 : SpdyFrameWithNameValueBlockIR(stream_id), 764 end_headers_(false) {} 765 766 virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE; 767 768 bool end_headers() const { return end_headers_; } 769 void set_end_headers(bool end_headers) {end_headers_ = end_headers;} 770 771 private: 772 bool end_headers_; 773 DISALLOW_COPY_AND_ASSIGN(SpdyContinuationIR); 774}; 775 776// ------------------------------------------------------------------------- 777// Wrapper classes for various SPDY frames. 778 779// All Spdy Frame types derive from this SpdyFrame class. 780class SpdyFrame { 781 public: 782 // Create a SpdyFrame using a pre-created buffer. 783 // If |owns_buffer| is true, this class takes ownership of the buffer 784 // and will delete it on cleanup. The buffer must have been created using 785 // new char[]. 786 // If |owns_buffer| is false, the caller retains ownership of the buffer and 787 // is responsible for making sure the buffer outlives this frame. In other 788 // words, this class does NOT create a copy of the buffer. 789 SpdyFrame(char* data, size_t size, bool owns_buffer) 790 : frame_(data), 791 size_(size), 792 owns_buffer_(owns_buffer) { 793 DCHECK(frame_); 794 } 795 796 ~SpdyFrame() { 797 if (owns_buffer_) { 798 delete [] frame_; 799 } 800 frame_ = NULL; 801 } 802 803 // Provides access to the frame bytes, which is a buffer containing 804 // the frame packed as expected for sending over the wire. 805 char* data() const { return frame_; } 806 807 // Returns the actual size of the underlying buffer. 808 size_t size() const { return size_; } 809 810 protected: 811 char* frame_; 812 813 private: 814 size_t size_; 815 bool owns_buffer_; 816 DISALLOW_COPY_AND_ASSIGN(SpdyFrame); 817}; 818 819// This interface is for classes that want to process SpdyFrameIRs without 820// having to know what type they are. An instance of this interface can be 821// passed to a SpdyFrameIR's Visit method, and the appropriate type-specific 822// method of this class will be called. 823class SpdyFrameVisitor { 824 public: 825 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) = 0; 826 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) = 0; 827 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0; 828 virtual void VisitSettings(const SpdySettingsIR& settings) = 0; 829 virtual void VisitPing(const SpdyPingIR& ping) = 0; 830 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0; 831 virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0; 832 virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0; 833 virtual void VisitBlocked(const SpdyBlockedIR& blocked) = 0; 834 virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0; 835 virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0; 836 virtual void VisitData(const SpdyDataIR& data) = 0; 837 838 protected: 839 SpdyFrameVisitor() {} 840 virtual ~SpdyFrameVisitor() {} 841 842 private: 843 DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor); 844}; 845 846} // namespace net 847 848#endif // NET_SPDY_SPDY_PROTOCOL_H_ 849