Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package spdy implements HTTP2.0 (SPDY/3) protocol which is described in | 5 // Package spdy implements the SPDY protocol (currently SPDY/3), described in |
bradfitz
2013/01/15 21:17:22
HTTP/2.0 would be the correct punctuation, but it'
Jxck
2013/01/20 16:52:31
Done.
| |
6 // http://tools.ietf.org/html/draft-ietf-httpbis-http2-00 | 6 // http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3. |
7 package spdy | 7 package spdy |
8 | 8 |
9 import ( | 9 import ( |
10 "bytes" | 10 "bytes" |
11 "compress/zlib" | 11 "compress/zlib" |
12 "io" | 12 "io" |
13 "net/http" | 13 "net/http" |
14 ) | 14 ) |
15 | 15 |
16 // Version is the protocol version number that this package implements. | 16 // Version is the protocol version number that this package implements. |
17 const Version = 3 | 17 const Version = 3 |
18 | 18 |
19 // ControlFrameType stores the type field in a control frame header. | 19 // ControlFrameType stores the type field in a control frame header. |
20 type ControlFrameType uint16 | 20 type ControlFrameType uint16 |
21 | 21 |
22 // Control frame type constants | 22 const ( |
23 const ( // Noop (0x0005) removed spdy/3 | |
mikio
2013/01/15 22:44:39
drop the comment
Jxck
2013/01/20 16:52:31
Done.
| |
24 TypeSynStream ControlFrameType = 0x0001 | 23 TypeSynStream ControlFrameType = 0x0001 |
25 TypeSynReply = 0x0002 | 24 TypeSynReply = 0x0002 |
26 TypeRstStream = 0x0003 | 25 TypeRstStream = 0x0003 |
27 TypeSettings = 0x0004 | 26 TypeSettings = 0x0004 |
28 TypePing = 0x0006 | 27 TypePing = 0x0006 |
29 TypeGoAway = 0x0007 | 28 TypeGoAway = 0x0007 |
30 TypeHeaders = 0x0008 | 29 TypeHeaders = 0x0008 |
31 TypeWindowUpdate = 0x0009 | 30 TypeWindowUpdate = 0x0009 |
32 ) | 31 ) |
33 | 32 |
34 // ControlFlags are the flags that can be set on a control frame. | 33 // ControlFlags are the flags that can be set on a control frame. |
35 type ControlFlags uint8 | 34 type ControlFlags uint8 |
36 | 35 |
37 const ( | 36 const ( |
38 » ControlFlagFin ControlFlags = 0x01 | 37 » ControlFlagFin ControlFlags = 0x01 |
38 » ControlFlagUnidirectional = 0x02 | |
39 » ControlFlagSettingsClearSettings = 0x01 | |
39 ) | 40 ) |
40 | 41 |
41 // DataFlags are the flags that can be set on a data frame. | 42 // DataFlags are the flags that can be set on a data frame. |
42 type DataFlags uint8 | 43 type DataFlags uint8 |
43 | 44 |
44 const ( | 45 const ( |
45 » DataFlagFin DataFlags = 0x01 | 46 » DataFlagFin DataFlags = 0x01 |
46 » DataFlagCompressed = 0x02 | 47 ) |
47 ) | 48 |
48 | 49 // MaxDataLength is the maximum number of bytes that can be stored in one frame. |
49 // MaxDataLength is the maximum number of bytes | |
50 // that can be stored in one frame. | |
mikio
2013/01/15 22:44:39
why folding?
Jxck
2013/01/20 16:52:31
Done.
| |
51 const MaxDataLength = 1<<24 - 1 | 50 const MaxDataLength = 1<<24 - 1 |
52 | 51 |
53 // Separator for multiple Header Values | 52 // headerValueSepator separates multiple header values. |
bradfitz
2013/01/15 21:17:22
Correct Go style is to use a complete sentence her
Jxck
2013/01/20 16:52:31
Done.
| |
54 const HeaderValueSeparator = "\x00" | 53 const headerValueSeparator = "\x00" |
55 | 54 |
56 // Frame is a single SPDY frame in its unpacked in-memory representation. | 55 // Frame is a single SPDY frame in its unpacked in-memory representation. Use |
57 // Use Framer to read and write it. | 56 // Framer to read and write it. |
58 type Frame interface { | 57 type Frame interface { |
59 write(f *Framer) error | 58 write(f *Framer) error |
60 } | 59 } |
61 | 60 |
62 // ControlFrameHeader contains all the fields in a control frame header, | 61 // ControlFrameHeader contains all the fields in a control frame header, |
63 // in its unpacked in-memory representation. | 62 // in its unpacked in-memory representation. |
64 // | |
65 // Control Frame Format | |
mikio
2013/01/15 22:44:39
i don't think the wire format in the package docs
Jxck
2013/01/20 16:52:31
Done.
| |
66 // +----------------------------------+ | |
67 // |1| Version(15bits) | Type(16bits) | | |
68 // +----------------------------------+ | |
69 // | flags (8) | Length (24 bits) | | |
70 // +----------------------------------+ | |
71 // | Data | | |
72 // +----------------------------------+ | |
73 type ControlFrameHeader struct { | 63 type ControlFrameHeader struct { |
74 // Note, high bit is the "Control" bit. | 64 // Note, high bit is the "Control" bit. |
75 » version uint16 | 65 » version uint16 // spdy version number |
76 frameType ControlFrameType | 66 frameType ControlFrameType |
77 Flags ControlFlags | 67 Flags ControlFlags |
78 » length uint32 | 68 » length uint32 // length of data field |
79 } | 69 } |
80 | 70 |
81 type controlFrame interface { | 71 type controlFrame interface { |
82 Frame | 72 Frame |
83 read(h ControlFrameHeader, f *Framer) error | 73 read(h ControlFrameHeader, f *Framer) error |
84 } | 74 } |
85 | 75 |
86 // SynStreamFrame is the unpacked, | 76 // StreamId represents a 31-bit value identifying the stream. |
87 // in-memory representation of a SYN_STREAM frame. | 77 type StreamId uint32 |
88 // | 78 |
89 // Control Frame: SYN_STREAM (18 + length) | 79 // SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM |
90 // +----------------------------------+ | 80 // frame. |
91 // |1| Version(15bits) | Type(16bits) | | |
92 // +----------------------------------+ | |
93 // | flags (8) | Length (24 bits) | flags = 0x01(FLAG_FIN), 0x02(FLAG_UNIDI RECTIONAL) | |
94 // +----------------------------------+ | |
95 // |X| Stream-ID(31bits) | <-+ | |
96 // +----------------------------------+ | | |
97 // |X|Associated-To-Stream-ID (31bits)| | 10byte | |
98 // +----------------------------------+ | | |
99 // |Pri(3)|unused(5)|SLOT(8bits)| | <-+ | |
100 // +----------------------------------+ | |
101 // | # of Name/Value pair(int 32) | <-+ | |
102 // +----------------------------------+ | compressed | |
103 // | Length of name (int 32) | | | |
104 // +----------------------------------+ | | |
105 // | Name (String) | | | |
106 // +----------------------------------+ | | |
107 // | Length of value (int 32) | | | |
108 // +----------------------------------+ | | |
109 // | Value (String) | | | |
110 // +----------------------------------+ | | |
111 // | (repeat) | <-+ | |
112 // +----------------------------------+ | |
113 type SynStreamFrame struct { | 81 type SynStreamFrame struct { |
114 CFHeader ControlFrameHeader | 82 CFHeader ControlFrameHeader |
115 » StreamId uint32 | 83 » StreamId StreamId |
116 » AssociatedToStreamId uint32 | 84 » AssociatedToStreamId StreamId // stream id for a stream which this strea m is associated to |
117 » // Note, only 3 highest bits currently used | 85 » Priority uint8 // priority of this frame (3-bit) |
118 » // Rest of Priority is unused. | 86 » Slot uint8 // index in the server's credential vector of the client certificate |
119 » Priority uint8 | 87 » Headers http.Header |
120 » Slot uint8 | 88 } |
89 | |
90 // SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame. | |
91 type SynReplyFrame struct { | |
92 » CFHeader ControlFrameHeader | |
93 » StreamId StreamId | |
121 Headers http.Header | 94 Headers http.Header |
122 } | 95 } |
123 | 96 |
124 // SynReplyFrame is the unpacked, | 97 // RstStreamStatus represents the status that led to a RST_STREAM. |
125 // in-memory representation of a SYN_REPLY frame. | 98 type RstStreamStatus uint32 |
126 // | 99 |
127 // Control Frame: SYN_REPLY (24 + length) | 100 const ( |
128 // +----------------------------------+ | 101 » ProtocolError RstStreamStatus = iota + 1 |
129 // |1| Version(15bits) | Type(16bits) | | 102 » InvalidStream |
130 // +----------------------------------+ | 103 » RefusedStream |
131 // | flags (8) | Length (24 bits) | flags = 0x01(FLAG_FIN) | 104 » UnsupportedVersion |
132 // +----------------------------------+ | 105 » Cancel |
133 // |X| Stream-ID(31bits) | | 106 » InternalError |
134 // +----------------------------------+ | 107 » FlowControlError |
135 // | # of Name/Value pair(int 32) | <-+ | 108 » StreamInUse |
136 // +----------------------------------+ | compressed | 109 » StreamAlreadyClosed |
137 // | Length of name (int 32) | | | 110 » InvalidCredentials |
138 // +----------------------------------+ | | 111 » FrameTooLarge |
139 // | Name (String) | | | 112 ) |
140 // +----------------------------------+ | | 113 |
141 // | Length of value (int 32) | | | 114 // RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM |
142 // +----------------------------------+ | | |
143 // | Value (String) | | | |
144 // +----------------------------------+ | | |
145 // | (repeat) | <-+ | |
146 // +----------------------------------+ | |
147 type SynReplyFrame struct { | |
148 » CFHeader ControlFrameHeader | |
149 » StreamId uint32 | |
150 » Headers http.Header | |
151 } | |
152 | |
153 // RSTStatusCode represents the status that led to a RST_STREAM | |
154 type RSTStatusCode uint32 | |
mikio
2013/01/15 22:44:39
perhaps RstStreamStatus might be better because
sp
Jxck
2013/01/20 16:52:31
Done.
| |
155 | |
156 const ( // 0 is invalid | |
mikio
2013/01/15 22:44:39
drop the comment
Jxck
2013/01/20 16:52:31
Done.
| |
157 » ProtocolError RSTStatusCode = 1 | |
mikio
2013/01/15 22:44:39
perhaps,
RstProtocolError RstStreamStatus = iota
mikio
2013/01/16 03:02:16
or
const (
ProtocolError RstStreamStatus
Jxck
2013/01/20 16:52:31
Done.
Jxck
2013/01/20 16:52:31
Done.
| |
158 » InvalidStream = 2 | |
159 » RefusedStream = 3 | |
160 » UnsupportedVersion = 4 | |
161 » Cancel = 5 | |
162 » InternalError = 6 | |
163 » FlowControlError = 7 | |
164 » STREAM_IN_USE = 8 | |
bradfitz
2013/01/15 21:17:22
Wrong case. See the lines above for Go style.
Jxck
2013/01/20 16:52:31
Done.
| |
165 » STREAM_ALREADY_CLOSED = 9 | |
166 » INVALID_CREDENTIALS = 10 | |
167 » FRAME_TOO_LARGE = 11 | |
168 ) | |
169 | |
170 // RstStreamFrame is the unpacked, | |
171 // in-memory representation of a RST_STREAM | |
172 // frame. | 115 // frame. |
173 // | |
174 // Control Frame: RST_STREAM (16 byte) | |
175 // +----------------------------------+ | |
176 // |1| Version(15bits) | Type(16bits) | | |
177 // +----------------------------------+ | |
178 // | flags (8) | Length (24 bits) | flags = 0, length = 8 | |
179 // +----------------------------------+ | |
180 // |X| Stream-ID(31bits) | | |
181 // +----------------------------------+ | |
182 // | Status code (32 bits) | | |
183 // +----------------------------------+ | |
184 type RstStreamFrame struct { | 116 type RstStreamFrame struct { |
185 CFHeader ControlFrameHeader | 117 CFHeader ControlFrameHeader |
186 » StreamId uint32 | 118 » StreamId StreamId |
187 » Status RSTStatusCode | 119 » Status RstStreamStatus |
188 } | 120 } |
189 | 121 |
190 // SettingsFlag represents a flag in a SETTINGS frame. | 122 // SettingsFlag represents a flag in a SETTINGS frame. |
191 type SettingsFlag uint8 | 123 type SettingsFlag uint8 |
192 | 124 |
193 const ( | 125 const ( |
194 FlagSettingsPersistValue SettingsFlag = 0x1 | 126 FlagSettingsPersistValue SettingsFlag = 0x1 |
195 FlagSettingsPersisted = 0x2 | 127 FlagSettingsPersisted = 0x2 |
196 ) | 128 ) |
197 | 129 |
198 // SettingsFlag represents the id of an id/value pair in a SETTINGS frame. | 130 // SettingsFlag represents the id of an id/value pair in a SETTINGS frame. |
199 type SettingsId uint32 | 131 type SettingsId uint32 |
200 | 132 |
201 const ( | 133 const ( |
202 » SettingsUploadBandwidth SettingsId = 1 | 134 » SettingsUploadBandwidth SettingsId = iota + 1 |
203 » SettingsDownloadBandwidth = 2 | 135 » SettingsDownloadBandwidth |
204 » SettingsRoundTripTime = 3 | 136 » SettingsRoundTripTime |
205 » SettingsMaxConcurrentStreams = 4 | 137 » SettingsMaxConcurrentStreams |
206 » SettingsCurrentCwnd = 5 | 138 » SettingsCurrentCwnd |
207 » SettingsDownloadRetransRate = 6 | 139 » SettingsDownloadRetransRate |
208 » SettingsInitialWindowSize = 7 | 140 » SettingsInitialWindowSize |
209 » SettingsClientCretificateVectorSize = 8 | 141 » SettingsClientCretificateVectorSize |
210 ) | 142 ) |
211 | 143 |
212 // SettingsFlagIdValue is the unpacked, | 144 // SettingsFlagIdValue is the unpacked, in-memory representation of the |
213 // in-memory representation of the combined | 145 // combined flag/id/value for a setting in a SETTINGS frame. |
214 // flag/id/value for a setting in a SETTINGS frame. | |
215 type SettingsFlagIdValue struct { | 146 type SettingsFlagIdValue struct { |
216 Flag SettingsFlag | 147 Flag SettingsFlag |
217 Id SettingsId | 148 Id SettingsId |
218 Value uint32 | 149 Value uint32 |
219 } | 150 } |
220 | 151 |
221 // SettingsFrame is the unpacked, | 152 // SettingsFrame is the unpacked, in-memory representation of a SPDY |
222 // in-memory representation of a SPDY SETTINGS frame. | 153 // SETTINGS frame. |
223 // | |
224 // Control Frame: SETTINGS (8 + length) | |
225 // +----------------------------------+ | |
226 // |1| Version(15bits) | Type(16bits) | | |
227 // +----------------------------------+ | |
228 // | flags (8) | Length (24 bits) | flags = 0x1(FLAG_SETTINGS_CLEAR_SETINGS ) | |
229 // +----------------------------------+ | |
230 // | ID.flags (8) | Unique ID (24) | | |
231 // +----------------------------------+ | |
232 // | Value (32) | | |
233 // +----------------------------------+ | |
234 type SettingsFrame struct { | 154 type SettingsFrame struct { |
235 CFHeader ControlFrameHeader | 155 CFHeader ControlFrameHeader |
236 FlagIdValues []SettingsFlagIdValue | 156 FlagIdValues []SettingsFlagIdValue |
237 } | 157 } |
238 | 158 |
239 // PingFrame is the unpacked, | 159 // PingFrame is the unpacked, in-memory representation of a PING frame. |
240 // in-memory representation of a PING frame. | |
241 // | |
242 // Control Frame: PING (12) | |
243 // +----------------------------------+ | |
244 // |1| Version(15bits) | Type(16bits) | | |
245 // +----------------------------------+ | |
246 // | flags (8) | Length (24 bits) | flags = 0, length = 4 | |
247 // +----------------------------------+ | |
248 // | Unique id (32 bits) | | |
249 // +----------------------------------+ | |
250 type PingFrame struct { | 160 type PingFrame struct { |
251 CFHeader ControlFrameHeader | 161 CFHeader ControlFrameHeader |
252 » Id uint32 | 162 » Id uint32 // unique id for this ping, from server is even, from cl ient is odd. |
253 } | 163 } |
254 | 164 |
255 // GoAwayFrame is the unpacked, | 165 // GoAwayStatus represents the status in a GoAwayFrame. |
256 // in-memory representation of a GOAWAY frame. | 166 type GoAwayStatus uint32 |
257 // | 167 |
258 // Control Frame: GOAWAY | 168 const ( |
259 // +----------------------------------+ | 169 » GoAwayOK GoAwayStatus = iota |
260 // |1| Version(15bits) | Type(16bits) | | 170 » GoAwayProtocolError |
261 // +----------------------------------+ | 171 » GoAwayInternalError |
262 // | flags (8) | Length (24 bits) | flags = 0, length = 8 | 172 ) |
263 // +----------------------------------+ | 173 |
264 // |X| Last-accepted-stream-id(31bits)| | 174 // GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame. |
265 // +----------------------------------+ | |
266 // | Status code | 0 = OK, 1 = PROTOCOL_ERROR, 11 = INTERN AL_ERROR | |
267 // +----------------------------------+ | |
268 type GoAwayFrame struct { | 175 type GoAwayFrame struct { |
269 CFHeader ControlFrameHeader | 176 CFHeader ControlFrameHeader |
270 » LastGoodStreamId uint32 | 177 » LastGoodStreamId StreamId // last stream id which was accepted by sender |
271 » StatusCode uint32 | 178 » Status GoAwayStatus |
mikio
2013/01/15 22:44:39
you can make new type GoAwayStatus or SessionStatu
Jxck
2013/01/20 16:52:31
Done.
| |
272 } | 179 } |
273 | 180 |
274 // HeadersFrame is the unpacked, | 181 // HeadersFrame is the unpacked, in-memory representation of a HEADERS frame. |
275 // in-memory representation of a HEADERS frame. | |
276 // | |
277 // Control Frame: HEADERS (12 + length) | |
278 // +----------------------------------+ | |
279 // |1| Version(15bits) | Type(16bits) | | |
280 // +----------------------------------+ | |
281 // | flags (8) | Length (24 bits) | flags = 0x01 (FLAG_FIN), Length >= 4 | |
282 // +----------------------------------+ | |
283 // |X| Stream-ID (31 bits) | | |
284 // +----------------------------------+ | |
285 // | # of Name/Value pair(int 32) | <-+ | |
286 // +----------------------------------+ | compressed | |
287 // | Length of name (int 32) | | | |
288 // +----------------------------------+ | | |
289 // | Name (String) | | | |
290 // +----------------------------------+ | | |
291 // | Length of value (int 32) | | | |
292 // +----------------------------------+ | | |
293 // | Value (String) | | | |
294 // +----------------------------------+ | | |
295 // | (repeat) | <-+ | |
296 // +----------------------------------+ | |
297 type HeadersFrame struct { | 182 type HeadersFrame struct { |
298 CFHeader ControlFrameHeader | 183 CFHeader ControlFrameHeader |
299 » StreamId uint32 | 184 » StreamId StreamId |
300 Headers http.Header | 185 Headers http.Header |
301 } | 186 } |
302 | 187 |
303 // WindowUpdateFrame is the unpacked, | 188 // WindowUpdateFrame is the unpacked, in-memory representation of a |
304 // in-memory representation of a WINDOW_UPDATE frame. | 189 // WINDOW_UPDATE frame. |
305 // | |
306 // Control Frame: WINDOW_UPDATE | |
307 // +----------------------------------+ | |
308 // |1| Version(15bits) | Type(16bits) | | |
309 // +----------------------------------+ | |
310 // | flags (8) | Length (24 bits) | flags = 0, lenght = 8 | |
311 // +----------------------------------+ | |
312 // |X| Stream-ID (31 bits) | | |
313 // +----------------------------------+ | |
314 // |X| Delta-Window-Size (31 bits) | | |
315 // +----------------------------------+ | |
316 type WindowUpdateFrame struct { | 190 type WindowUpdateFrame struct { |
317 CFHeader ControlFrameHeader | 191 CFHeader ControlFrameHeader |
318 » StreamId uint32 | 192 » StreamId StreamId |
319 » DeltaWindowSize uint32 | 193 » DeltaWindowSize uint32 // additional number of bytes to existing window size |
320 } | 194 } |
321 | 195 |
322 // TODO: Unused, so not implemented | 196 // TODO: Implement credential frame and related methods. |
323 // Control Frame: CREDENTIAL | 197 |
324 // +----------------------------------+ | 198 // DataFrame is the unpacked, in-memory representation of a DATA frame. |
325 // |1| Version(15bits) | Type(16bits) | | |
326 // +----------------------------------+ | |
327 // | flags (8) | Length (24 bits) | | |
328 // +----------------------------------+ | |
329 // | Slot (16 bits) | | | |
330 // +-----------------+ | | |
331 // | Proof Length (32 bits) | | |
332 // +----------------------------------+ | |
333 // | Proof | | |
334 // +----------------------------------+ <+ | |
335 // | Certificate Length (32 bits) | | | |
336 // +----------------------------------+ | Repeated until end of frame | |
337 // | Certificate | | | |
338 // +----------------------------------+ <+ | |
339 | |
340 // DataFrame is the unpacked, | |
341 // in-memory representation of a DATA frame. | |
342 // | |
343 // Data Frame Format | |
344 // +----------------------------------+ | |
345 // |0| Stream-ID (31bits) | | |
346 // +----------------------------------+ | |
347 // | flags (8) | Length (24 bits) | flags = 0x01(FLAG_FIN) or 0x02(FLAG_COM PRESS) | |
348 // +----------------------------------+ | |
349 // | Data | | |
350 // +----------------------------------+ | |
351 type DataFrame struct { | 199 type DataFrame struct { |
352 » // Note, high bit is the "Control" bit. | 200 » // Note, high bit is the "Control" bit. Should be 0 for data frames. |
353 » // Should be 0 for data frames. | 201 » StreamId StreamId |
354 » StreamId uint32 | |
355 Flags DataFlags | 202 Flags DataFlags |
356 » Data []byte | 203 » Data []byte // payload data of this frame |
357 } | 204 } |
358 | 205 |
359 // A SPDY specific error. | 206 // A SPDY specific error. |
360 type ErrorCode string | 207 type ErrorCode string |
361 | 208 |
362 const ( | 209 const ( |
363 UnlowercasedHeaderName ErrorCode = "header was not lowercased" | 210 UnlowercasedHeaderName ErrorCode = "header was not lowercased" |
364 » DuplicateHeaders ErrorCode = "multiple headers with same name" | 211 » DuplicateHeaders = "multiple headers with same name" |
365 » WrongCompressedPayloadSize ErrorCode = "compressed payload size was inco rrect" | 212 » WrongCompressedPayloadSize = "compressed payload size was inco rrect" |
366 » UnknownFrameType ErrorCode = "unknown frame type" | 213 » UnknownFrameType = "unknown frame type" |
367 » InvalidControlFrame ErrorCode = "invalid control frame" | 214 » InvalidControlFrame = "invalid control frame" |
368 » InvalidDataFrame ErrorCode = "invalid data frame" | 215 » InvalidDataFrame = "invalid data frame" |
369 » InvalidHeaderPresent ErrorCode = "frame contained invalid header" | 216 » InvalidHeaderPresent = "frame contained invalid header" |
370 » ZeroStreamId ErrorCode = "stream id zero is disallowed" | 217 » ZeroStreamId = "stream id zero is disallowed" |
371 ) | 218 ) |
372 | 219 |
373 // Error contains both the type of error and additional values. StreamId is 0 | 220 // Error contains both the type of error and additional values. StreamId is 0 |
374 // if Error is not associated with a stream. | 221 // if Error is not associated with a stream. |
375 type Error struct { | 222 type Error struct { |
376 Err ErrorCode | 223 Err ErrorCode |
377 » StreamId uint32 | 224 » StreamId StreamId |
378 } | 225 } |
379 | 226 |
380 func (e *Error) Error() string { | 227 func (e *Error) Error() string { |
381 return string(e.Err) | 228 return string(e.Err) |
382 } | 229 } |
383 | |
384 // TODO: need this ? | |
mikio
2013/01/15 22:44:39
do it or drop.
Jxck
2013/01/20 16:52:31
I'll think about this implementation later.
so rem
| |
385 // var mustReqHeaders = map[string]bool{ | |
386 // "method": true, | |
387 // "host": true, | |
388 // "path": true, | |
389 // "scheme": true, | |
390 // "version": true, | |
391 // } | |
392 | 230 |
393 var invalidReqHeaders = map[string]bool{ | 231 var invalidReqHeaders = map[string]bool{ |
394 "Connection": true, | 232 "Connection": true, |
395 "Host": true, | 233 "Host": true, |
396 "Keep-Alive": true, | 234 "Keep-Alive": true, |
397 "Proxy-Connection": true, | 235 "Proxy-Connection": true, |
398 "Transfer-Encoding": true, | 236 "Transfer-Encoding": true, |
399 } | 237 } |
400 | 238 |
401 var invalidRespHeaders = map[string]bool{ | 239 var invalidRespHeaders = map[string]bool{ |
402 "Connection": true, | 240 "Connection": true, |
403 "Keep-Alive": true, | 241 "Keep-Alive": true, |
404 "Proxy-Connection": true, | 242 "Proxy-Connection": true, |
405 "Transfer-Encoding": true, | 243 "Transfer-Encoding": true, |
406 } | 244 } |
407 | 245 |
408 // Framer handles serializing/deserializing SPDY frames, | 246 // Framer handles serializing/deserializing SPDY frames, including compressing/ |
409 // including compressing/decompressing payloads. | 247 // decompressing payloads. |
410 type Framer struct { | 248 type Framer struct { |
411 headerCompressionDisabled bool | 249 headerCompressionDisabled bool |
412 w io.Writer | 250 w io.Writer |
413 headerBuf *bytes.Buffer | 251 headerBuf *bytes.Buffer |
414 headerCompressor *zlib.Writer | 252 headerCompressor *zlib.Writer |
415 r io.Reader | 253 r io.Reader |
416 headerReader io.LimitedReader | 254 headerReader io.LimitedReader |
417 headerDecompressor io.ReadCloser | 255 headerDecompressor io.ReadCloser |
418 } | 256 } |
419 | 257 |
420 // NewFramer allocates a new Framer for a given SPDY connection, repesented by | 258 // NewFramer allocates a new Framer for a given SPDY connection, repesented by |
421 // a io.Writer and io.Reader. Note that Framer will read and write individual fi elds | 259 // a io.Writer and io.Reader. Note that Framer will read and write individual fi elds |
422 // from/to the Reader and Writer, so the caller should pass in an appropriately | 260 // from/to the Reader and Writer, so the caller should pass in an appropriately |
423 // buffered implementation to optimize performance. | 261 // buffered implementation to optimize performance. |
424 func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { | 262 func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { |
425 compressBuf := new(bytes.Buffer) | 263 compressBuf := new(bytes.Buffer) |
426 » compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompres sion, []byte(HeaderDictionary)) | 264 » compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompres sion, []byte(headerDictionary)) |
427 if err != nil { | 265 if err != nil { |
428 return nil, err | 266 return nil, err |
429 } | 267 } |
430 framer := &Framer{ | 268 framer := &Framer{ |
431 w: w, | 269 w: w, |
432 headerBuf: compressBuf, | 270 headerBuf: compressBuf, |
433 headerCompressor: compressor, | 271 headerCompressor: compressor, |
434 r: r, | 272 r: r, |
435 } | 273 } |
436 return framer, nil | 274 return framer, nil |
437 } | 275 } |
LEFT | RIGHT |