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