...
1
16
17
18
19
20
21
22
23 package spdy
24
25 import (
26 "bytes"
27 "compress/zlib"
28 "io"
29 "net/http"
30 )
31
32
33 const Version = 3
34
35
36 type ControlFrameType uint16
37
38 const (
39 TypeSynStream ControlFrameType = 0x0001
40 TypeSynReply ControlFrameType = 0x0002
41 TypeRstStream ControlFrameType = 0x0003
42 TypeSettings ControlFrameType = 0x0004
43 TypePing ControlFrameType = 0x0006
44 TypeGoAway ControlFrameType = 0x0007
45 TypeHeaders ControlFrameType = 0x0008
46 TypeWindowUpdate ControlFrameType = 0x0009
47 )
48
49
50 type ControlFlags uint8
51
52 const (
53 ControlFlagFin ControlFlags = 0x01
54 ControlFlagUnidirectional ControlFlags = 0x02
55 ControlFlagSettingsClearSettings ControlFlags = 0x01
56 )
57
58
59 type DataFlags uint8
60
61 const (
62 DataFlagFin DataFlags = 0x01
63 )
64
65
66 const MaxDataLength = 1<<24 - 1
67
68
69 const headerValueSeparator = "\x00"
70
71
72
73 type Frame interface {
74 write(f *Framer) error
75 }
76
77
78
79 type ControlFrameHeader struct {
80
81 version uint16
82 frameType ControlFrameType
83 Flags ControlFlags
84 length uint32
85 }
86
87 type controlFrame interface {
88 Frame
89 read(h ControlFrameHeader, f *Framer) error
90 }
91
92
93 type StreamId uint32
94
95
96
97 type SynStreamFrame struct {
98 CFHeader ControlFrameHeader
99 StreamId StreamId
100 AssociatedToStreamId StreamId
101 Priority uint8
102 Slot uint8
103 Headers http.Header
104 }
105
106
107 type SynReplyFrame struct {
108 CFHeader ControlFrameHeader
109 StreamId StreamId
110 Headers http.Header
111 }
112
113
114 type RstStreamStatus uint32
115
116 const (
117 ProtocolError RstStreamStatus = iota + 1
118 InvalidStream
119 RefusedStream
120 UnsupportedVersion
121 Cancel
122 InternalError
123 FlowControlError
124 StreamInUse
125 StreamAlreadyClosed
126 InvalidCredentials
127 FrameTooLarge
128 )
129
130
131
132 type RstStreamFrame struct {
133 CFHeader ControlFrameHeader
134 StreamId StreamId
135 Status RstStreamStatus
136 }
137
138
139 type SettingsFlag uint8
140
141 const (
142 FlagSettingsPersistValue SettingsFlag = 0x1
143 FlagSettingsPersisted SettingsFlag = 0x2
144 )
145
146
147 type SettingsId uint32
148
149 const (
150 SettingsUploadBandwidth SettingsId = iota + 1
151 SettingsDownloadBandwidth
152 SettingsRoundTripTime
153 SettingsMaxConcurrentStreams
154 SettingsCurrentCwnd
155 SettingsDownloadRetransRate
156 SettingsInitialWindowSize
157 SettingsClientCretificateVectorSize
158 )
159
160
161
162 type SettingsFlagIdValue struct {
163 Flag SettingsFlag
164 Id SettingsId
165 Value uint32
166 }
167
168
169
170 type SettingsFrame struct {
171 CFHeader ControlFrameHeader
172 FlagIdValues []SettingsFlagIdValue
173 }
174
175
176 type PingFrame struct {
177 CFHeader ControlFrameHeader
178 Id uint32
179 }
180
181
182 type GoAwayStatus uint32
183
184 const (
185 GoAwayOK GoAwayStatus = iota
186 GoAwayProtocolError
187 GoAwayInternalError
188 )
189
190
191 type GoAwayFrame struct {
192 CFHeader ControlFrameHeader
193 LastGoodStreamId StreamId
194 Status GoAwayStatus
195 }
196
197
198 type HeadersFrame struct {
199 CFHeader ControlFrameHeader
200 StreamId StreamId
201 Headers http.Header
202 }
203
204
205
206 type WindowUpdateFrame struct {
207 CFHeader ControlFrameHeader
208 StreamId StreamId
209 DeltaWindowSize uint32
210 }
211
212
213
214
215 type DataFrame struct {
216
217 StreamId StreamId
218 Flags DataFlags
219 Data []byte
220 }
221
222
223 type ErrorCode string
224
225 const (
226 UnlowercasedHeaderName ErrorCode = "header was not lowercased"
227 DuplicateHeaders ErrorCode = "multiple headers with same name"
228 WrongCompressedPayloadSize ErrorCode = "compressed payload size was incorrect"
229 UnknownFrameType ErrorCode = "unknown frame type"
230 InvalidControlFrame ErrorCode = "invalid control frame"
231 InvalidDataFrame ErrorCode = "invalid data frame"
232 InvalidHeaderPresent ErrorCode = "frame contained invalid header"
233 ZeroStreamId ErrorCode = "stream id zero is disallowed"
234 )
235
236
237
238 type Error struct {
239 Err ErrorCode
240 StreamId StreamId
241 }
242
243 func (e *Error) Error() string {
244 return string(e.Err)
245 }
246
247 var invalidReqHeaders = map[string]bool{
248 "Connection": true,
249 "Host": true,
250 "Keep-Alive": true,
251 "Proxy-Connection": true,
252 "Transfer-Encoding": true,
253 }
254
255 var invalidRespHeaders = map[string]bool{
256 "Connection": true,
257 "Keep-Alive": true,
258 "Proxy-Connection": true,
259 "Transfer-Encoding": true,
260 }
261
262
263
264 type Framer struct {
265 headerCompressionDisabled bool
266 w io.Writer
267 headerBuf *bytes.Buffer
268 headerCompressor *zlib.Writer
269 r io.Reader
270 headerReader io.LimitedReader
271 headerDecompressor io.ReadCloser
272 }
273
274
275
276
277
278 func NewFramer(w io.Writer, r io.Reader) (*Framer, error) {
279 compressBuf := new(bytes.Buffer)
280 compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))
281 if err != nil {
282 return nil, err
283 }
284 framer := &Framer{
285 w: w,
286 headerBuf: compressBuf,
287 headerCompressor: compressor,
288 r: r,
289 }
290 return framer, nil
291 }
292
View as plain text