types.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package spdy implements SPDY protocol which is described in
  5. // draft-mbelshe-httpbis-spdy-00.
  6. //
  7. // http://tools.ietf.org/html/draft-mbelshe-httpbis-spdy-00
  8. package spdy
  9. import (
  10. "bytes"
  11. "compress/zlib"
  12. "io"
  13. "net/http"
  14. )
  15. // Data Frame Format
  16. // +----------------------------------+
  17. // |0| Stream-ID (31bits) |
  18. // +----------------------------------+
  19. // | flags (8) | Length (24 bits) |
  20. // +----------------------------------+
  21. // | Data |
  22. // +----------------------------------+
  23. //
  24. // Control Frame Format
  25. // +----------------------------------+
  26. // |1| Version(15bits) | Type(16bits) |
  27. // +----------------------------------+
  28. // | flags (8) | Length (24 bits) |
  29. // +----------------------------------+
  30. // | Data |
  31. // +----------------------------------+
  32. //
  33. // Control Frame: SYN_STREAM
  34. // +----------------------------------+
  35. // |1|000000000000001|0000000000000001|
  36. // +----------------------------------+
  37. // | flags (8) | Length (24 bits) | >= 12
  38. // +----------------------------------+
  39. // |X| Stream-ID(31bits) |
  40. // +----------------------------------+
  41. // |X|Associated-To-Stream-ID (31bits)|
  42. // +----------------------------------+
  43. // |Pri| unused | Length (16bits)|
  44. // +----------------------------------+
  45. //
  46. // Control Frame: SYN_REPLY
  47. // +----------------------------------+
  48. // |1|000000000000001|0000000000000010|
  49. // +----------------------------------+
  50. // | flags (8) | Length (24 bits) | >= 8
  51. // +----------------------------------+
  52. // |X| Stream-ID(31bits) |
  53. // +----------------------------------+
  54. // | unused (16 bits)| Length (16bits)|
  55. // +----------------------------------+
  56. //
  57. // Control Frame: RST_STREAM
  58. // +----------------------------------+
  59. // |1|000000000000001|0000000000000011|
  60. // +----------------------------------+
  61. // | flags (8) | Length (24 bits) | >= 4
  62. // +----------------------------------+
  63. // |X| Stream-ID(31bits) |
  64. // +----------------------------------+
  65. // | Status code (32 bits) |
  66. // +----------------------------------+
  67. //
  68. // Control Frame: SETTINGS
  69. // +----------------------------------+
  70. // |1|000000000000001|0000000000000100|
  71. // +----------------------------------+
  72. // | flags (8) | Length (24 bits) |
  73. // +----------------------------------+
  74. // | # of entries (32) |
  75. // +----------------------------------+
  76. //
  77. // Control Frame: NOOP
  78. // +----------------------------------+
  79. // |1|000000000000001|0000000000000101|
  80. // +----------------------------------+
  81. // | flags (8) | Length (24 bits) | = 0
  82. // +----------------------------------+
  83. //
  84. // Control Frame: PING
  85. // +----------------------------------+
  86. // |1|000000000000001|0000000000000110|
  87. // +----------------------------------+
  88. // | flags (8) | Length (24 bits) | = 4
  89. // +----------------------------------+
  90. // | Unique id (32 bits) |
  91. // +----------------------------------+
  92. //
  93. // Control Frame: GOAWAY
  94. // +----------------------------------+
  95. // |1|000000000000001|0000000000000111|
  96. // +----------------------------------+
  97. // | flags (8) | Length (24 bits) | = 4
  98. // +----------------------------------+
  99. // |X| Last-accepted-stream-id |
  100. // +----------------------------------+
  101. //
  102. // Control Frame: HEADERS
  103. // +----------------------------------+
  104. // |1|000000000000001|0000000000001000|
  105. // +----------------------------------+
  106. // | flags (8) | Length (24 bits) | >= 8
  107. // +----------------------------------+
  108. // |X| Stream-ID (31 bits) |
  109. // +----------------------------------+
  110. // | unused (16 bits)| Length (16bits)|
  111. // +----------------------------------+
  112. //
  113. // Control Frame: WINDOW_UPDATE
  114. // +----------------------------------+
  115. // |1|000000000000001|0000000000001001|
  116. // +----------------------------------+
  117. // | flags (8) | Length (24 bits) | = 8
  118. // +----------------------------------+
  119. // |X| Stream-ID (31 bits) |
  120. // +----------------------------------+
  121. // | Delta-Window-Size (32 bits) |
  122. // +----------------------------------+
  123. // Version is the protocol version number that this package implements.
  124. const Version = 2
  125. // ControlFrameType stores the type field in a control frame header.
  126. type ControlFrameType uint16
  127. // Control frame type constants
  128. const (
  129. TypeSynStream ControlFrameType = 0x0001
  130. TypeSynReply = 0x0002
  131. TypeRstStream = 0x0003
  132. TypeSettings = 0x0004
  133. TypeNoop = 0x0005
  134. TypePing = 0x0006
  135. TypeGoAway = 0x0007
  136. TypeHeaders = 0x0008
  137. TypeWindowUpdate = 0x0009
  138. )
  139. // ControlFlags are the flags that can be set on a control frame.
  140. type ControlFlags uint8
  141. const (
  142. ControlFlagFin ControlFlags = 0x01
  143. )
  144. // DataFlags are the flags that can be set on a data frame.
  145. type DataFlags uint8
  146. const (
  147. DataFlagFin DataFlags = 0x01
  148. DataFlagCompressed = 0x02
  149. )
  150. // MaxDataLength is the maximum number of bytes that can be stored in one frame.
  151. const MaxDataLength = 1<<24 - 1
  152. // Frame is a single SPDY frame in its unpacked in-memory representation. Use
  153. // Framer to read and write it.
  154. type Frame interface {
  155. write(f *Framer) error
  156. }
  157. // ControlFrameHeader contains all the fields in a control frame header,
  158. // in its unpacked in-memory representation.
  159. type ControlFrameHeader struct {
  160. // Note, high bit is the "Control" bit.
  161. version uint16
  162. frameType ControlFrameType
  163. Flags ControlFlags
  164. length uint32
  165. }
  166. type controlFrame interface {
  167. Frame
  168. read(h ControlFrameHeader, f *Framer) error
  169. }
  170. // SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM
  171. // frame.
  172. type SynStreamFrame struct {
  173. CFHeader ControlFrameHeader
  174. StreamId uint32
  175. AssociatedToStreamId uint32
  176. // Note, only 2 highest bits currently used
  177. // Rest of Priority is unused.
  178. Priority uint16
  179. Headers http.Header
  180. }
  181. // SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame.
  182. type SynReplyFrame struct {
  183. CFHeader ControlFrameHeader
  184. StreamId uint32
  185. Headers http.Header
  186. }
  187. // StatusCode represents the status that led to a RST_STREAM
  188. type StatusCode uint32
  189. const (
  190. ProtocolError StatusCode = 1
  191. InvalidStream = 2
  192. RefusedStream = 3
  193. UnsupportedVersion = 4
  194. Cancel = 5
  195. InternalError = 6
  196. FlowControlError = 7
  197. )
  198. // RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM
  199. // frame.
  200. type RstStreamFrame struct {
  201. CFHeader ControlFrameHeader
  202. StreamId uint32
  203. Status StatusCode
  204. }
  205. // SettingsFlag represents a flag in a SETTINGS frame.
  206. type SettingsFlag uint8
  207. const (
  208. FlagSettingsPersistValue SettingsFlag = 0x1
  209. FlagSettingsPersisted = 0x2
  210. )
  211. // SettingsFlag represents the id of an id/value pair in a SETTINGS frame.
  212. type SettingsId uint32
  213. const (
  214. SettingsUploadBandwidth SettingsId = 1
  215. SettingsDownloadBandwidth = 2
  216. SettingsRoundTripTime = 3
  217. SettingsMaxConcurrentStreams = 4
  218. SettingsCurrentCwnd = 5
  219. )
  220. // SettingsFlagIdValue is the unpacked, in-memory representation of the
  221. // combined flag/id/value for a setting in a SETTINGS frame.
  222. type SettingsFlagIdValue struct {
  223. Flag SettingsFlag
  224. Id SettingsId
  225. Value uint32
  226. }
  227. // SettingsFrame is the unpacked, in-memory representation of a SPDY
  228. // SETTINGS frame.
  229. type SettingsFrame struct {
  230. CFHeader ControlFrameHeader
  231. FlagIdValues []SettingsFlagIdValue
  232. }
  233. // NoopFrame is the unpacked, in-memory representation of a NOOP frame.
  234. type NoopFrame struct {
  235. CFHeader ControlFrameHeader
  236. }
  237. // PingFrame is the unpacked, in-memory representation of a PING frame.
  238. type PingFrame struct {
  239. CFHeader ControlFrameHeader
  240. Id uint32
  241. }
  242. // GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame.
  243. type GoAwayFrame struct {
  244. CFHeader ControlFrameHeader
  245. LastGoodStreamId uint32
  246. }
  247. // HeadersFrame is the unpacked, in-memory representation of a HEADERS frame.
  248. type HeadersFrame struct {
  249. CFHeader ControlFrameHeader
  250. StreamId uint32
  251. Headers http.Header
  252. }
  253. // DataFrame is the unpacked, in-memory representation of a DATA frame.
  254. type DataFrame struct {
  255. // Note, high bit is the "Control" bit. Should be 0 for data frames.
  256. StreamId uint32
  257. Flags DataFlags
  258. Data []byte
  259. }
  260. // HeaderDictionary is the dictionary sent to the zlib compressor/decompressor.
  261. // Even though the specification states there is no null byte at the end, Chrome sends it.
  262. const HeaderDictionary = "optionsgetheadpostputdeletetrace" +
  263. "acceptaccept-charsetaccept-encodingaccept-languageauthorizationexpectfromhost" +
  264. "if-modified-sinceif-matchif-none-matchif-rangeif-unmodifiedsince" +
  265. "max-forwardsproxy-authorizationrangerefererteuser-agent" +
  266. "100101200201202203204205206300301302303304305306307400401402403404405406407408409410411412413414415416417500501502503504505" +
  267. "accept-rangesageetaglocationproxy-authenticatepublicretry-after" +
  268. "servervarywarningwww-authenticateallowcontent-basecontent-encodingcache-control" +
  269. "connectiondatetrailertransfer-encodingupgradeviawarning" +
  270. "content-languagecontent-lengthcontent-locationcontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookie" +
  271. "MondayTuesdayWednesdayThursdayFridaySaturdaySunday" +
  272. "JanFebMarAprMayJunJulAugSepOctNovDec" +
  273. "chunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplication/xhtmltext/plainpublicmax-age" +
  274. "charset=iso-8859-1utf-8gzipdeflateHTTP/1.1statusversionurl\x00"
  275. // A SPDY specific error.
  276. type ErrorCode string
  277. const (
  278. UnlowercasedHeaderName ErrorCode = "header was not lowercased"
  279. DuplicateHeaders ErrorCode = "multiple headers with same name"
  280. WrongCompressedPayloadSize ErrorCode = "compressed payload size was incorrect"
  281. UnknownFrameType ErrorCode = "unknown frame type"
  282. InvalidControlFrame ErrorCode = "invalid control frame"
  283. InvalidDataFrame ErrorCode = "invalid data frame"
  284. InvalidHeaderPresent ErrorCode = "frame contained invalid header"
  285. ZeroStreamId ErrorCode = "stream id zero is disallowed"
  286. )
  287. // Error contains both the type of error and additional values. StreamId is 0
  288. // if Error is not associated with a stream.
  289. type Error struct {
  290. Err ErrorCode
  291. StreamId uint32
  292. }
  293. func (e *Error) Error() string {
  294. return string(e.Err)
  295. }
  296. var invalidReqHeaders = map[string]bool{
  297. "Connection": true,
  298. "Keep-Alive": true,
  299. "Proxy-Connection": true,
  300. "Transfer-Encoding": true,
  301. }
  302. var invalidRespHeaders = map[string]bool{
  303. "Connection": true,
  304. "Keep-Alive": true,
  305. "Transfer-Encoding": true,
  306. }
  307. // Framer handles serializing/deserializing SPDY frames, including compressing/
  308. // decompressing payloads.
  309. type Framer struct {
  310. headerCompressionDisabled bool
  311. w io.Writer
  312. headerBuf *bytes.Buffer
  313. headerCompressor *zlib.Writer
  314. r io.Reader
  315. headerReader io.LimitedReader
  316. headerDecompressor io.ReadCloser
  317. }
  318. // NewFramer allocates a new Framer for a given SPDY connection, repesented by
  319. // a io.Writer and io.Reader. Note that Framer will read and write individual fields
  320. // from/to the Reader and Writer, so the caller should pass in an appropriately
  321. // buffered implementation to optimize performance.
  322. func NewFramer(w io.Writer, r io.Reader) (*Framer, error) {
  323. compressBuf := new(bytes.Buffer)
  324. compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(HeaderDictionary))
  325. if err != nil {
  326. return nil, err
  327. }
  328. framer := &Framer{
  329. w: w,
  330. headerBuf: compressBuf,
  331. headerCompressor: compressor,
  332. r: r,
  333. }
  334. return framer, nil
  335. }