Home | History | Annotate | Download | only in spdy
      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 
     27 namespace 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. Do not rely on
     32 // the mapping from enum value SPDYn to the integer n.
     33 enum SpdyMajorVersion {
     34   SPDY2 = 2,
     35   SPDY_MIN_VERSION = SPDY2,
     36   SPDY3 = 3,
     37   SPDY4 = 4,
     38   SPDY5 = 5,
     39   SPDY_MAX_VERSION = SPDY5
     40 };
     41 
     42 // A SPDY stream id is a 31 bit entity.
     43 typedef uint32 SpdyStreamId;
     44 
     45 // Specifies the stream ID used to denote the current session (for
     46 // flow control).
     47 const SpdyStreamId kSessionFlowControlStreamId = 0;
     48 
     49 // Initial window size for a Spdy stream in bytes.
     50 const int32 kSpdyStreamInitialWindowSize = 64 * 1024;  // 64 KBytes
     51 
     52 // Initial window size for a Spdy session in bytes.
     53 const int32 kSpdySessionInitialWindowSize = 64 * 1024;  // 64 KBytes
     54 
     55 // Maximum window size for a Spdy stream or session.
     56 const int32 kSpdyMaximumWindowSize = 0x7FFFFFFF;  // Max signed 32bit int
     57 
     58 // SPDY 2 dictionary.
     59 // This is just a hacked dictionary to use for shrinking HTTP-like headers.
     60 const char kV2Dictionary[] =
     61   "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
     62   "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
     63   "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
     64   "-agent10010120020120220320420520630030130230330430530630740040140240340440"
     65   "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
     66   "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
     67   "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
     68   "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
     69   "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
     70   "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
     71   "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
     72   "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
     73   ".1statusversionurl";
     74 const int kV2DictionarySize = arraysize(kV2Dictionary);
     75 
     76 // SPDY 3 dictionary.
     77 const char kV3Dictionary[] = {
     78   0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69,  // ....opti
     79   0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68,  // ons....h
     80   0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70,  // ead....p
     81   0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70,  // ost....p
     82   0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65,  // ut....de
     83   0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05,  // lete....
     84   0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00,  // trace...
     85   0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00,  // .accept.
     86   0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70,  // ...accep
     87   0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,  // t-charse
     88   0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63,  // t....acc
     89   0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,  // ept-enco
     90   0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f,  // ding....
     91   0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c,  // accept-l
     92   0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00,  // anguage.
     93   0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70,  // ...accep
     94   0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73,  // t-ranges
     95   0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00,  // ....age.
     96   0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77,  // ...allow
     97   0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68,  // ....auth
     98   0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,  // orizatio
     99   0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63,  // n....cac
    100   0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72,  // he-contr
    101   0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f,  // ol....co
    102   0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,  // nnection
    103   0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
    104   0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65,  // ent-base
    105   0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
    106   0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,  // ent-enco
    107   0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10,  // ding....
    108   0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,  // content-
    109   0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,  // language
    110   0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74,  // ....cont
    111   0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67,  // ent-leng
    112   0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f,  // th....co
    113   0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f,  // ntent-lo
    114   0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,  // cation..
    115   0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,  // ..conten
    116   0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00,  // t-md5...
    117   0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,  // .content
    118   0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00,  // -range..
    119   0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,  // ..conten
    120   0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00,  // t-type..
    121   0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00,  // ..date..
    122   0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00,  // ..etag..
    123   0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,  // ..expect
    124   0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69,  // ....expi
    125   0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66,  // res....f
    126   0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68,  // rom....h
    127   0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69,  // ost....i
    128   0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00,  // f-match.
    129   0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f,  // ...if-mo
    130   0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73,  // dified-s
    131   0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d,  // ince....
    132   0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d,  // if-none-
    133   0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00,  // match...
    134   0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67,  // .if-rang
    135   0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d,  // e....if-
    136   0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,  // unmodifi
    137   0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65,  // ed-since
    138   0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74,  // ....last
    139   0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,  // -modifie
    140   0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63,  // d....loc
    141   0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,  // ation...
    142   0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72,  // .max-for
    143   0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00,  // wards...
    144   0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00,  // .pragma.
    145   0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79,  // ...proxy
    146   0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,  // -authent
    147   0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,  // icate...
    148   0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61,  // .proxy-a
    149   0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,  // uthoriza
    150   0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05,  // tion....
    151   0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00,  // range...
    152   0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72,  // .referer
    153   0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72,  // ....retr
    154   0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00,  // y-after.
    155   0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,  // ...serve
    156   0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00,  // r....te.
    157   0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c,  // ...trail
    158   0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72,  // er....tr
    159   0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65,  // ansfer-e
    160   0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00,  // ncoding.
    161   0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61,  // ...upgra
    162   0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73,  // de....us
    163   0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,  // er-agent
    164   0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79,  // ....vary
    165   0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00,  // ....via.
    166   0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69,  // ...warni
    167   0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77,  // ng....ww
    168   0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,  // w-authen
    169   0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00,  // ticate..
    170   0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,  // ..method
    171   0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00,  // ....get.
    172   0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,  // ...statu
    173   0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30,  // s....200
    174   0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76,  // .OK....v
    175   0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00,  // ersion..
    176   0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31,  // ..HTTP.1
    177   0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72,  // .1....ur
    178   0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62,  // l....pub
    179   0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73,  // lic....s
    180   0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69,  // et-cooki
    181   0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65,  // e....kee
    182   0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00,  // p-alive.
    183   0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69,  // ...origi
    184   0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32,  // n1001012
    185   0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35,  // 01202205
    186   0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30,  // 20630030
    187   0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33,  // 23033043
    188   0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37,  // 05306307
    189   0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30,  // 40240540
    190   0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34,  // 64074084
    191   0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31,  // 09410411
    192   0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31,  // 41241341
    193   0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34,  // 44154164
    194   0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34,  // 17502504
    195   0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e,  // 505203.N
    196   0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f,  // on-Autho
    197   0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65,  // ritative
    198   0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,  // .Informa
    199   0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20,  // tion204.
    200   0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65,  // No.Conte
    201   0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f,  // nt301.Mo
    202   0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d,  // ved.Perm
    203   0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34,  // anently4
    204   0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52,  // 00.Bad.R
    205   0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30,  // equest40
    206   0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68,  // 1.Unauth
    207   0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30,  // orized40
    208   0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64,  // 3.Forbid
    209   0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e,  // den404.N
    210   0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64,  // ot.Found
    211   0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65,  // 500.Inte
    212   0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,  // rnal.Ser
    213   0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f,  // ver.Erro
    214   0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74,  // r501.Not
    215   0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65,  // .Impleme
    216   0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20,  // nted503.
    217   0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20,  // Service.
    218   0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,  // Unavaila
    219   0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46,  // bleJan.F
    220   0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41,  // eb.Mar.A
    221   0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a,  // pr.May.J
    222   0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41,  // un.Jul.A
    223   0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20,  // ug.Sept.
    224   0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20,  // Oct.Nov.
    225   0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30,  // Dec.00.0
    226   0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e,  // 0.00.Mon
    227   0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57,  // ..Tue..W
    228   0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c,  // ed..Thu.
    229   0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61,  // .Fri..Sa
    230   0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20,  // t..Sun..
    231   0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b,  // GMTchunk
    232   0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f,  // ed.text.
    233   0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61,  // html.ima
    234   0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69,  // ge.png.i
    235   0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67,  // mage.jpg
    236   0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67,  // .image.g
    237   0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,  // if.appli
    238   0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,  // cation.x
    239   0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,  // ml.appli
    240   0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,  // cation.x
    241   0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c,  // html.xml
    242   0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c,  // .text.pl
    243   0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74,  // ain.text
    244   0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72,  // .javascr
    245   0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c,  // ipt.publ
    246   0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,  // icprivat
    247   0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65,  // emax-age
    248   0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65,  // .gzip.de
    249   0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64,  // flate.sd
    250   0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,  // chcharse
    251   0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63,  // t.utf-8c
    252   0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69,  // harset.i
    253   0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d,  // so-8859-
    254   0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a,  // 1.utf-..
    255   0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e         // .enq.0.
    256 };
    257 const int kV3DictionarySize = arraysize(kV3Dictionary);
    258 
    259 // The HTTP/2 connection header prefix, which must be the first bytes
    260 // sent by the client upon starting an HTTP/2 connection, and which
    261 // must be followed by a SETTINGS frame.
    262 //
    263 // Equivalent to the string "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
    264 // (without the null terminator).
    265 const char kHttp2ConnectionHeaderPrefix[] = {
    266   0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54,  // PRI * HT
    267   0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a,  // TP/2.0..
    268   0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a   // ..SM....
    269 };
    270 const int kHttp2ConnectionHeaderPrefixSize =
    271     arraysize(kHttp2ConnectionHeaderPrefix);
    272 
    273 // Types of SPDY frames.
    274 enum SpdyFrameType {
    275   DATA = 0,
    276   SYN_STREAM = 1,
    277   FIRST_CONTROL_TYPE = SYN_STREAM,
    278   SYN_REPLY,
    279   RST_STREAM,
    280   SETTINGS,
    281   NOOP,  // Because it is valid in SPDY/2, kept for identifiability/enum order.
    282   PING,
    283   GOAWAY,
    284   HEADERS,
    285   WINDOW_UPDATE,
    286   CREDENTIAL,  // No longer valid.  Kept for identifiability/enum order.
    287   BLOCKED,
    288   PUSH_PROMISE,
    289   CONTINUATION,
    290   ALTSVC,
    291   PRIORITY,
    292   LAST_CONTROL_TYPE = PRIORITY
    293 };
    294 
    295 // Flags on data packets.
    296 enum SpdyDataFlags {
    297   DATA_FLAG_NONE = 0x00,
    298   DATA_FLAG_FIN = 0x01,
    299   DATA_FLAG_END_SEGMENT = 0x02,
    300   DATA_FLAG_PAD_LOW = 0x08,
    301   DATA_FLAG_PAD_HIGH = 0x10,
    302   DATA_FLAG_COMPRESSED = 0x20,
    303 };
    304 
    305 // Flags on control packets
    306 enum SpdyControlFlags {
    307   CONTROL_FLAG_NONE = 0x00,
    308   CONTROL_FLAG_FIN = 0x01,
    309   CONTROL_FLAG_UNIDIRECTIONAL = 0x02,
    310 };
    311 
    312 enum SpdyPingFlags {
    313   PING_FLAG_ACK = 0x01,
    314 };
    315 
    316 // Used by HEADERS, PUSH_PROMISE, and CONTINUATION.
    317 enum SpdyHeadersFlags {
    318   HEADERS_FLAG_END_SEGMENT = 0x02,
    319   HEADERS_FLAG_END_HEADERS = 0x04,
    320   HEADERS_FLAG_PAD_LOW = 0x08,
    321   HEADERS_FLAG_PAD_HIGH = 0x10,
    322   HEADERS_FLAG_PRIORITY = 0x20,
    323 };
    324 
    325 enum SpdyPushPromiseFlags {
    326   PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x04,
    327 };
    328 
    329 // Flags on the SETTINGS control frame.
    330 enum SpdySettingsControlFlags {
    331   SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x01,
    332 };
    333 
    334 enum Http2SettingsControlFlags {
    335   SETTINGS_FLAG_ACK = 0x01,
    336 };
    337 
    338 // Flags for settings within a SETTINGS frame.
    339 enum SpdySettingsFlags {
    340   SETTINGS_FLAG_NONE = 0x00,
    341   SETTINGS_FLAG_PLEASE_PERSIST = 0x01,
    342   SETTINGS_FLAG_PERSISTED = 0x02,
    343 };
    344 
    345 // List of known settings. Avoid changing these enum values, as persisted
    346 // settings are keyed on them, and they are also exposed in net-internals.
    347 enum SpdySettingsIds {
    348   SETTINGS_UPLOAD_BANDWIDTH = 0x1,
    349   SETTINGS_DOWNLOAD_BANDWIDTH = 0x2,
    350   // Network round trip time in milliseconds.
    351   SETTINGS_ROUND_TRIP_TIME = 0x3,
    352   // The maximum number of simultaneous live streams in each direction.
    353   SETTINGS_MAX_CONCURRENT_STREAMS = 0x4,
    354   // TCP congestion window in packets.
    355   SETTINGS_CURRENT_CWND = 0x5,
    356   // Downstream byte retransmission rate in percentage.
    357   SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6,
    358   // Initial window size in bytes
    359   SETTINGS_INITIAL_WINDOW_SIZE = 0x7,
    360   // HPACK header table maximum size.
    361   SETTINGS_HEADER_TABLE_SIZE = 0x8,
    362   // Whether or not server push (PUSH_PROMISE) is enabled.
    363   SETTINGS_ENABLE_PUSH = 0x9,
    364   // Whether or not to enable GZip compression of DATA frames.
    365   SETTINGS_COMPRESS_DATA = 0xa,
    366 };
    367 
    368 // Status codes for RST_STREAM frames.
    369 enum SpdyRstStreamStatus {
    370   RST_STREAM_INVALID = 0,
    371   RST_STREAM_PROTOCOL_ERROR = 1,
    372   RST_STREAM_INVALID_STREAM = 2,
    373   RST_STREAM_STREAM_CLOSED = 2,  // Equivalent to INVALID_STREAM
    374   RST_STREAM_REFUSED_STREAM = 3,
    375   RST_STREAM_UNSUPPORTED_VERSION = 4,
    376   RST_STREAM_CANCEL = 5,
    377   RST_STREAM_INTERNAL_ERROR = 6,
    378   RST_STREAM_FLOW_CONTROL_ERROR = 7,
    379   RST_STREAM_STREAM_IN_USE = 8,
    380   RST_STREAM_STREAM_ALREADY_CLOSED = 9,
    381   RST_STREAM_INVALID_CREDENTIALS = 10,
    382   // FRAME_TOO_LARGE (defined by SPDY versions 3.1 and below), and
    383   // FRAME_SIZE_ERROR (defined by HTTP/2) are mapped to the same internal
    384   // reset status.
    385   RST_STREAM_FRAME_TOO_LARGE = 11,
    386   RST_STREAM_FRAME_SIZE_ERROR = 11,
    387   RST_STREAM_SETTINGS_TIMEOUT = 12,
    388   RST_STREAM_CONNECT_ERROR = 13,
    389   RST_STREAM_ENHANCE_YOUR_CALM = 14,
    390   RST_STREAM_NUM_STATUS_CODES = 15
    391 };
    392 
    393 // Status codes for GOAWAY frames.
    394 enum SpdyGoAwayStatus {
    395   GOAWAY_OK = 0,
    396   GOAWAY_NO_ERROR = GOAWAY_OK,
    397   GOAWAY_PROTOCOL_ERROR = 1,
    398   GOAWAY_INTERNAL_ERROR = 2,
    399   GOAWAY_FLOW_CONTROL_ERROR = 3,
    400   GOAWAY_SETTINGS_TIMEOUT = 4,
    401   GOAWAY_STREAM_CLOSED = 5,
    402   GOAWAY_FRAME_SIZE_ERROR = 6,
    403   GOAWAY_REFUSED_STREAM = 7,
    404   GOAWAY_CANCEL = 8,
    405   GOAWAY_COMPRESSION_ERROR = 9,
    406   GOAWAY_CONNECT_ERROR = 10,
    407   GOAWAY_ENHANCE_YOUR_CALM = 11,
    408   GOAWAY_INADEQUATE_SECURITY = 12
    409 };
    410 
    411 // A SPDY priority is a number between 0 and 7 (inclusive).
    412 // SPDY priority range is version-dependent. For SPDY 2 and below, priority is a
    413 // number between 0 and 3.
    414 typedef uint8 SpdyPriority;
    415 
    416 typedef std::map<std::string, std::string> SpdyNameValueBlock;
    417 
    418 typedef uint64 SpdyPingId;
    419 
    420 typedef std::string SpdyProtocolId;
    421 
    422 // TODO(hkhalil): Add direct testing for this? It won't increase coverage any,
    423 // but is good to do anyway.
    424 class NET_EXPORT_PRIVATE SpdyConstants {
    425  public:
    426   // Returns true if a given on-the-wire enumeration of a frame type is valid
    427   // for a given protocol version, false otherwise.
    428   static bool IsValidFrameType(SpdyMajorVersion version, int frame_type_field);
    429 
    430   // Parses a frame type from an on-the-wire enumeration of a given protocol
    431   // version.
    432   // Behavior is undefined for invalid frame type fields; consumers should first
    433   // use IsValidFrameType() to verify validity of frame type fields.
    434   static SpdyFrameType ParseFrameType(SpdyMajorVersion version,
    435                                       int frame_type_field);
    436 
    437   // Serializes a given frame type to the on-the-wire enumeration value for the
    438   // given protocol version.
    439   // Returns -1 on failure (I.E. Invalid frame type for the given version).
    440   static int SerializeFrameType(SpdyMajorVersion version,
    441                                 SpdyFrameType frame_type);
    442 
    443   // Returns true if a given on-the-wire enumeration of a setting id is valid
    444   // for a given protocol version, false otherwise.
    445   static bool IsValidSettingId(SpdyMajorVersion version, int setting_id_field);
    446 
    447   // Parses a setting id from an on-the-wire enumeration of a given protocol
    448   // version.
    449   // Behavior is undefined for invalid setting id fields; consumers should first
    450   // use IsValidSettingId() to verify validity of setting id fields.
    451   static SpdySettingsIds ParseSettingId(SpdyMajorVersion version,
    452                                         int setting_id_field);
    453 
    454   // Serializes a given setting id to the on-the-wire enumeration value for the
    455   // given protocol version.
    456   // Returns -1 on failure (I.E. Invalid setting id for the given version).
    457   static int SerializeSettingId(SpdyMajorVersion version, SpdySettingsIds id);
    458 
    459   // Returns true if a given on-the-wire enumeration of a RST_STREAM status code
    460   // is valid for a given protocol version, false otherwise.
    461   static bool IsValidRstStreamStatus(SpdyMajorVersion version,
    462                                      int rst_stream_status_field);
    463 
    464   // Parses a RST_STREAM status code from an on-the-wire enumeration of a given
    465   // protocol version.
    466   // Behavior is undefined for invalid RST_STREAM status code fields; consumers
    467   // should first use IsValidRstStreamStatus() to verify validity of RST_STREAM
    468   // status code fields..
    469   static SpdyRstStreamStatus ParseRstStreamStatus(SpdyMajorVersion version,
    470                                                   int rst_stream_status_field);
    471 
    472   // Serializes a given RST_STREAM status code to the on-the-wire enumeration
    473   // value for the given protocol version.
    474   // Returns -1 on failure (I.E. Invalid RST_STREAM status code for the given
    475   // version).
    476   static int SerializeRstStreamStatus(SpdyMajorVersion version,
    477                                       SpdyRstStreamStatus rst_stream_status);
    478 
    479   // Returns true if a given on-the-wire enumeration of a GOAWAY status code is
    480   // valid for the given protocol version, false otherwise.
    481   static bool IsValidGoAwayStatus(SpdyMajorVersion version,
    482                                   int goaway_status_field);
    483 
    484   // Parses a GOAWAY status from an on-the-wire enumeration of a given protocol
    485   // version.
    486   // Behavior is undefined for invalid GOAWAY status fields; consumers should
    487   // first use IsValidGoAwayStatus() to verify validity of GOAWAY status fields.
    488   static SpdyGoAwayStatus ParseGoAwayStatus(SpdyMajorVersion version,
    489                                             int goaway_status_field);
    490 
    491   // Serializes a given GOAWAY status to the on-the-wire enumeration value for
    492   // the given protocol version.
    493   // Returns -1 on failure (I.E. Invalid GOAWAY status for the given version).
    494   static int SerializeGoAwayStatus(SpdyMajorVersion version,
    495                                    SpdyGoAwayStatus status);
    496 
    497   // Size, in bytes, of the data frame header. Future versions of SPDY
    498   // will likely vary this, so we allow for the flexibility of a function call
    499   // for this value as opposed to a constant.
    500   static size_t GetDataFrameMinimumSize();
    501 
    502   // Size, in bytes, of the control frame header.
    503   static size_t GetControlFrameHeaderSize(SpdyMajorVersion version);
    504 
    505   static size_t GetPrefixLength(SpdyFrameType type, SpdyMajorVersion version);
    506 
    507   static size_t GetFrameMaximumSize(SpdyMajorVersion version);
    508 
    509   // Returns the size of a header block size field. Valid only for SPDY
    510   // versions <= 3.
    511   static size_t GetSizeOfSizeField(SpdyMajorVersion version);
    512 
    513   static SpdyMajorVersion ParseMajorVersion(int version_number);
    514 
    515   static int SerializeMajorVersion(SpdyMajorVersion version);
    516 
    517   static std::string GetVersionString(SpdyMajorVersion version);
    518 };
    519 
    520 class SpdyFrame;
    521 typedef SpdyFrame SpdySerializedFrame;
    522 
    523 class SpdyFrameVisitor;
    524 
    525 // Intermediate representation for SPDY frames.
    526 // TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
    527 // gone.
    528 class NET_EXPORT_PRIVATE SpdyFrameIR {
    529  public:
    530   virtual ~SpdyFrameIR() {}
    531 
    532   virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
    533 
    534  protected:
    535   SpdyFrameIR() {}
    536 
    537  private:
    538   DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR);
    539 };
    540 
    541 // Abstract class intended to be inherited by IRs that have a stream associated
    542 // to them.
    543 class NET_EXPORT_PRIVATE SpdyFrameWithStreamIdIR : public SpdyFrameIR {
    544  public:
    545   virtual ~SpdyFrameWithStreamIdIR() {}
    546   SpdyStreamId stream_id() const { return stream_id_; }
    547   void set_stream_id(SpdyStreamId stream_id) {
    548     DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
    549     stream_id_ = stream_id;
    550   }
    551 
    552  protected:
    553   explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) {
    554     set_stream_id(stream_id);
    555   }
    556 
    557  private:
    558   SpdyStreamId stream_id_;
    559 
    560   DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR);
    561 };
    562 
    563 // Abstract class intended to be inherited by IRs that have the option of a FIN
    564 // flag. Implies SpdyFrameWithStreamIdIR.
    565 class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR {
    566  public:
    567   virtual ~SpdyFrameWithFinIR() {}
    568   bool fin() const { return fin_; }
    569   void set_fin(bool fin) { fin_ = fin; }
    570 
    571  protected:
    572   explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
    573       : SpdyFrameWithStreamIdIR(stream_id),
    574         fin_(false) {}
    575 
    576  private:
    577   bool fin_;
    578 
    579   DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR);
    580 };
    581 
    582 // Abstract class intended to be inherited by IRs that contain a name-value
    583 // block. Implies SpdyFrameWithFinIR.
    584 class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR
    585     : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
    586  public:
    587   const SpdyNameValueBlock& name_value_block() const {
    588     return name_value_block_;
    589   }
    590   void set_name_value_block(const SpdyNameValueBlock& name_value_block) {
    591     // Deep copy.
    592     name_value_block_ = name_value_block;
    593   }
    594   void SetHeader(const base::StringPiece& name,
    595                  const base::StringPiece& value) {
    596     name_value_block_[name.as_string()] = value.as_string();
    597   }
    598   SpdyNameValueBlock* mutable_name_value_block() {
    599     return &name_value_block_;
    600   }
    601 
    602  protected:
    603   explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id);
    604   virtual ~SpdyFrameWithNameValueBlockIR();
    605 
    606  private:
    607   SpdyNameValueBlock name_value_block_;
    608 
    609   DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR);
    610 };
    611 
    612 class NET_EXPORT_PRIVATE SpdyDataIR
    613     : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
    614  public:
    615   // Performs deep copy on data.
    616   SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data);
    617 
    618   // Use in conjunction with SetDataShallow() for shallow-copy on data.
    619   explicit SpdyDataIR(SpdyStreamId stream_id);
    620 
    621   virtual ~SpdyDataIR();
    622 
    623   base::StringPiece data() const { return data_; }
    624 
    625   bool pad_low() const { return pad_low_; }
    626 
    627   bool pad_high() const { return pad_high_; }
    628 
    629   int padding_payload_len() const { return padding_payload_len_; }
    630 
    631   void set_padding_len(int padding_len) {
    632     // The padding_len should be in (0, 65535 + 2].
    633     // Note that SpdyFramer::GetDataFrameMaximumPayload() enforces the overall
    634     // payload size later so we actually can't pad more than 16375 bytes.
    635     DCHECK_GT(padding_len, 0);
    636     DCHECK_LT(padding_len, 65537);
    637 
    638     if (padding_len <= 256) {
    639       pad_low_ = true;
    640       --padding_len;
    641     } else {
    642       pad_low_ = pad_high_ = true;
    643       padding_len -= 2;
    644     }
    645     padding_payload_len_ = padding_len;
    646   }
    647 
    648   // Deep-copy of data (keep private copy).
    649   void SetDataDeep(const base::StringPiece& data) {
    650     data_store_.reset(new std::string(data.data(), data.length()));
    651     data_ = *(data_store_.get());
    652   }
    653 
    654   // Shallow-copy of data (do not keep private copy).
    655   void SetDataShallow(const base::StringPiece& data) {
    656     data_store_.reset();
    657     data_ = data;
    658   }
    659 
    660   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    661 
    662  private:
    663   // Used to store data that this SpdyDataIR should own.
    664   scoped_ptr<std::string> data_store_;
    665   base::StringPiece data_;
    666 
    667   bool pad_low_;
    668   bool pad_high_;
    669   // padding_payload_len_ = desired padding length - len(padding length field).
    670   int padding_payload_len_;
    671 
    672   DISALLOW_COPY_AND_ASSIGN(SpdyDataIR);
    673 };
    674 
    675 class NET_EXPORT_PRIVATE SpdySynStreamIR
    676     : public SpdyFrameWithNameValueBlockIR {
    677  public:
    678   explicit SpdySynStreamIR(SpdyStreamId stream_id)
    679       : SpdyFrameWithNameValueBlockIR(stream_id),
    680         associated_to_stream_id_(0),
    681         priority_(0),
    682         unidirectional_(false) {}
    683   SpdyStreamId associated_to_stream_id() const {
    684     return associated_to_stream_id_;
    685   }
    686   void set_associated_to_stream_id(SpdyStreamId stream_id) {
    687     associated_to_stream_id_ = stream_id;
    688   }
    689   SpdyPriority priority() const { return priority_; }
    690   void set_priority(SpdyPriority priority) { priority_ = priority; }
    691   bool unidirectional() const { return unidirectional_; }
    692   void set_unidirectional(bool unidirectional) {
    693     unidirectional_ = unidirectional;
    694   }
    695 
    696   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    697 
    698  private:
    699   SpdyStreamId associated_to_stream_id_;
    700   SpdyPriority priority_;
    701   bool unidirectional_;
    702 
    703   DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR);
    704 };
    705 
    706 class NET_EXPORT_PRIVATE SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR {
    707  public:
    708   explicit SpdySynReplyIR(SpdyStreamId stream_id)
    709       : SpdyFrameWithNameValueBlockIR(stream_id) {}
    710 
    711   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    712 
    713  private:
    714   DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR);
    715 };
    716 
    717 class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
    718  public:
    719   SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status,
    720                   base::StringPiece description);
    721 
    722   virtual ~SpdyRstStreamIR();
    723 
    724   SpdyRstStreamStatus status() const {
    725     return status_;
    726   }
    727   void set_status(SpdyRstStreamStatus status) {
    728     status_ = status;
    729   }
    730 
    731   base::StringPiece description() const { return description_; }
    732 
    733   void set_description(base::StringPiece description) {
    734     description_ = description;
    735   }
    736 
    737   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    738 
    739  private:
    740   SpdyRstStreamStatus status_;
    741   base::StringPiece description_;
    742 
    743   DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
    744 };
    745 
    746 class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
    747  public:
    748   // Associates flags with a value.
    749   struct Value {
    750     Value() : persist_value(false),
    751               persisted(false),
    752               value(0) {}
    753     bool persist_value;
    754     bool persisted;
    755     int32 value;
    756   };
    757   typedef std::map<SpdySettingsIds, Value> ValueMap;
    758 
    759   SpdySettingsIR();
    760 
    761   virtual ~SpdySettingsIR();
    762 
    763   // Overwrites as appropriate.
    764   const ValueMap& values() const { return values_; }
    765   void AddSetting(SpdySettingsIds id,
    766                   bool persist_value,
    767                   bool persisted,
    768                   int32 value) {
    769     values_[id].persist_value = persist_value;
    770     values_[id].persisted = persisted;
    771     values_[id].value = value;
    772   }
    773 
    774   bool clear_settings() const { return clear_settings_; }
    775   void set_clear_settings(bool clear_settings) {
    776     clear_settings_ = clear_settings;
    777   }
    778   bool is_ack() const { return is_ack_; }
    779   void set_is_ack(bool is_ack) {
    780     is_ack_ = is_ack;
    781   }
    782 
    783   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    784 
    785  private:
    786   ValueMap values_;
    787   bool clear_settings_;
    788   bool is_ack_;
    789 
    790   DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR);
    791 };
    792 
    793 class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
    794  public:
    795   explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
    796   SpdyPingId id() const { return id_; }
    797 
    798   // ACK logic is valid only for SPDY versions 4 and above.
    799   bool is_ack() const { return is_ack_; }
    800   void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
    801 
    802   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    803 
    804  private:
    805   SpdyPingId id_;
    806   bool is_ack_;
    807 
    808   DISALLOW_COPY_AND_ASSIGN(SpdyPingIR);
    809 };
    810 
    811 class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
    812  public:
    813   SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status,
    814                const base::StringPiece& description);
    815   virtual ~SpdyGoAwayIR();
    816   SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
    817   void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
    818     DCHECK_LE(0u, last_good_stream_id);
    819     DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
    820     last_good_stream_id_ = last_good_stream_id;
    821   }
    822   SpdyGoAwayStatus status() const { return status_; }
    823   void set_status(SpdyGoAwayStatus status) {
    824     // TODO(hkhalil): Check valid ranges of status?
    825     status_ = status;
    826   }
    827 
    828   const base::StringPiece& description() const;
    829 
    830   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    831 
    832  private:
    833   SpdyStreamId last_good_stream_id_;
    834   SpdyGoAwayStatus status_;
    835   const base::StringPiece description_;
    836 
    837   DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR);
    838 };
    839 
    840 class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR {
    841  public:
    842   explicit SpdyHeadersIR(SpdyStreamId stream_id)
    843     : SpdyFrameWithNameValueBlockIR(stream_id),
    844       has_priority_(false),
    845       priority_(0) {}
    846 
    847   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    848 
    849   bool has_priority() const { return has_priority_; }
    850   void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
    851   uint32 priority() const { return priority_; }
    852   void set_priority(SpdyPriority priority) { priority_ = priority; }
    853 
    854  private:
    855   bool has_priority_;
    856   // 31-bit priority.
    857   uint32 priority_;
    858   DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
    859 };
    860 
    861 class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
    862  public:
    863   SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta)
    864       : SpdyFrameWithStreamIdIR(stream_id) {
    865     set_delta(delta);
    866   }
    867   int32 delta() const { return delta_; }
    868   void set_delta(int32 delta) {
    869     DCHECK_LT(0, delta);
    870     DCHECK_LE(delta, kSpdyMaximumWindowSize);
    871     delta_ = delta;
    872   }
    873 
    874   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    875 
    876  private:
    877   int32 delta_;
    878 
    879   DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR);
    880 };
    881 
    882 class NET_EXPORT_PRIVATE SpdyBlockedIR
    883     : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR) {
    884  public:
    885   explicit SpdyBlockedIR(SpdyStreamId stream_id)
    886       : SpdyFrameWithStreamIdIR(stream_id) {}
    887 
    888   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    889 
    890  private:
    891   DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR);
    892 };
    893 
    894 class NET_EXPORT_PRIVATE SpdyPushPromiseIR
    895     : public SpdyFrameWithNameValueBlockIR {
    896  public:
    897   SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
    898       : SpdyFrameWithNameValueBlockIR(stream_id),
    899         promised_stream_id_(promised_stream_id) {}
    900   SpdyStreamId promised_stream_id() const { return promised_stream_id_; }
    901   void set_promised_stream_id(SpdyStreamId id) { promised_stream_id_ = id; }
    902 
    903   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    904 
    905  private:
    906   SpdyStreamId promised_stream_id_;
    907   DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR);
    908 };
    909 
    910 // TODO(jgraettinger): This representation needs review. SpdyContinuationIR
    911 // needs to frame a portion of a single, arbitrarily-broken encoded buffer.
    912 class NET_EXPORT_PRIVATE SpdyContinuationIR
    913     : public SpdyFrameWithNameValueBlockIR {
    914  public:
    915   explicit SpdyContinuationIR(SpdyStreamId stream_id)
    916       : SpdyFrameWithNameValueBlockIR(stream_id),
    917         end_headers_(false) {}
    918 
    919   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    920 
    921   bool end_headers() const { return end_headers_; }
    922   void set_end_headers(bool end_headers) {end_headers_ = end_headers;}
    923 
    924  private:
    925   bool end_headers_;
    926   DISALLOW_COPY_AND_ASSIGN(SpdyContinuationIR);
    927 };
    928 
    929 class NET_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameWithStreamIdIR {
    930  public:
    931   explicit SpdyAltSvcIR(SpdyStreamId stream_id);
    932 
    933   uint32 max_age() const { return max_age_; }
    934   uint16 port() const { return port_; }
    935   SpdyProtocolId protocol_id() const {
    936     return protocol_id_;
    937   }
    938   std::string host() const { return host_; }
    939   std::string origin() const { return origin_; }
    940 
    941   void set_max_age(uint32 max_age) { max_age_ = max_age; }
    942   void set_port(uint16 port) { port_ = port; }
    943   void set_protocol_id(SpdyProtocolId protocol_id) {
    944     protocol_id_ = protocol_id;
    945   }
    946   void set_host(std::string host) {
    947     host_ = host;
    948   }
    949   void set_origin(std::string origin) {
    950     origin_ = origin;
    951   }
    952 
    953   virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
    954 
    955  private:
    956   uint32 max_age_;
    957   uint16 port_;
    958   SpdyProtocolId protocol_id_;
    959   std::string host_;
    960   std::string origin_;
    961   DISALLOW_COPY_AND_ASSIGN(SpdyAltSvcIR);
    962 };
    963 
    964 // -------------------------------------------------------------------------
    965 // Wrapper classes for various SPDY frames.
    966 
    967 // All Spdy Frame types derive from this SpdyFrame class.
    968 class SpdyFrame {
    969  public:
    970   // Create a SpdyFrame using a pre-created buffer.
    971   // If |owns_buffer| is true, this class takes ownership of the buffer
    972   // and will delete it on cleanup.  The buffer must have been created using
    973   // new char[].
    974   // If |owns_buffer| is false, the caller retains ownership of the buffer and
    975   // is responsible for making sure the buffer outlives this frame.  In other
    976   // words, this class does NOT create a copy of the buffer.
    977   SpdyFrame(char* data, size_t size, bool owns_buffer)
    978       : frame_(data),
    979         size_(size),
    980         owns_buffer_(owns_buffer) {
    981     DCHECK(frame_);
    982   }
    983 
    984   ~SpdyFrame() {
    985     if (owns_buffer_) {
    986       delete [] frame_;
    987     }
    988     frame_ = NULL;
    989   }
    990 
    991   // Provides access to the frame bytes, which is a buffer containing
    992   // the frame packed as expected for sending over the wire.
    993   char* data() const { return frame_; }
    994 
    995   // Returns the actual size of the underlying buffer.
    996   size_t size() const { return size_; }
    997 
    998  protected:
    999   char* frame_;
   1000 
   1001  private:
   1002   size_t size_;
   1003   bool owns_buffer_;
   1004   DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
   1005 };
   1006 
   1007 // This interface is for classes that want to process SpdyFrameIRs without
   1008 // having to know what type they are.  An instance of this interface can be
   1009 // passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
   1010 // method of this class will be called.
   1011 class SpdyFrameVisitor {
   1012  public:
   1013   virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) = 0;
   1014   virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) = 0;
   1015   virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
   1016   virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
   1017   virtual void VisitPing(const SpdyPingIR& ping) = 0;
   1018   virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
   1019   virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
   1020   virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
   1021   virtual void VisitBlocked(const SpdyBlockedIR& blocked) = 0;
   1022   virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0;
   1023   virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0;
   1024   virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) = 0;
   1025   virtual void VisitData(const SpdyDataIR& data) = 0;
   1026 
   1027  protected:
   1028   SpdyFrameVisitor() {}
   1029   virtual ~SpdyFrameVisitor() {}
   1030 
   1031  private:
   1032   DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor);
   1033 };
   1034 
   1035 }  // namespace net
   1036 
   1037 #endif  // NET_SPDY_SPDY_PROTOCOL_H_
   1038