types.go 12 KB

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