Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(177)

Side by Side Diff: spdy/read.go

Issue 5574065: code review 5574065: go.net: initial code (Closed)
Patch Set: diff -r b50a7fb49394 https://code.google.com/p/go.net Created 13 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « dict/dict.go ('k') | spdy/spdy_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
5 package spdy
6
7 import (
8 "compress/zlib"
9 "encoding/binary"
10 "io"
11 "net/http"
12 "strings"
13 )
14
15 func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) error {
16 return f.readSynStreamFrame(h, frame)
17 }
18
19 func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) error {
20 return f.readSynReplyFrame(h, frame)
21 }
22
23 func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) error {
24 frame.CFHeader = h
25 if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != ni l {
26 return err
27 }
28 if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
29 return err
30 }
31 return nil
32 }
33
34 func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error {
35 frame.CFHeader = h
36 var numSettings uint32
37 if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {
38 return err
39 }
40 frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings)
41 for i := uint32(0); i < numSettings; i++ {
42 if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues [i].Id); err != nil {
43 return err
44 }
45 frame.FlagIdValues[i].Flag = SettingsFlag((frame.FlagIdValues[i] .Id & 0xff000000) >> 24)
46 frame.FlagIdValues[i].Id &= 0xffffff
47 if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues [i].Value); err != nil {
48 return err
49 }
50 }
51 return nil
52 }
53
54 func (frame *NoopFrame) read(h ControlFrameHeader, f *Framer) error {
55 frame.CFHeader = h
56 return nil
57 }
58
59 func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) error {
60 frame.CFHeader = h
61 if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {
62 return err
63 }
64 return nil
65 }
66
67 func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) error {
68 frame.CFHeader = h
69 if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); e rr != nil {
70 return err
71 }
72 return nil
73 }
74
75 func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) error {
76 return f.readHeadersFrame(h, frame)
77 }
78
79 func newControlFrame(frameType ControlFrameType) (controlFrame, error) {
80 ctor, ok := cframeCtor[frameType]
81 if !ok {
82 return nil, &Error{Err: InvalidControlFrame}
83 }
84 return ctor(), nil
85 }
86
87 var cframeCtor = map[ControlFrameType]func() controlFrame{
88 TypeSynStream: func() controlFrame { return new(SynStreamFrame) },
89 TypeSynReply: func() controlFrame { return new(SynReplyFrame) },
90 TypeRstStream: func() controlFrame { return new(RstStreamFrame) },
91 TypeSettings: func() controlFrame { return new(SettingsFrame) },
92 TypeNoop: func() controlFrame { return new(NoopFrame) },
93 TypePing: func() controlFrame { return new(PingFrame) },
94 TypeGoAway: func() controlFrame { return new(GoAwayFrame) },
95 TypeHeaders: func() controlFrame { return new(HeadersFrame) },
96 // TODO(willchan): Add TypeWindowUpdate
97 }
98
99 func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) error {
100 if f.headerDecompressor != nil {
101 f.headerReader.N = payloadSize
102 return nil
103 }
104 f.headerReader = io.LimitedReader{R: f.r, N: payloadSize}
105 decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(HeaderDi ctionary))
106 if err != nil {
107 return err
108 }
109 f.headerDecompressor = decompressor
110 return nil
111 }
112
113 // ReadFrame reads SPDY encoded data and returns a decompressed Frame.
114 func (f *Framer) ReadFrame() (Frame, error) {
115 var firstWord uint32
116 if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {
117 return nil, err
118 }
119 if (firstWord & 0x80000000) != 0 {
120 frameType := ControlFrameType(firstWord & 0xffff)
121 version := uint16(0x7fff & (firstWord >> 16))
122 return f.parseControlFrame(version, frameType)
123 }
124 return f.parseDataFrame(firstWord & 0x7fffffff)
125 }
126
127 func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) ( Frame, error) {
128 var length uint32
129 if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
130 return nil, err
131 }
132 flags := ControlFlags((length & 0xff000000) >> 24)
133 length &= 0xffffff
134 header := ControlFrameHeader{version, frameType, flags, length}
135 cframe, err := newControlFrame(frameType)
136 if err != nil {
137 return nil, err
138 }
139 if err = cframe.read(header, f); err != nil {
140 return nil, err
141 }
142 return cframe, nil
143 }
144
145 func parseHeaderValueBlock(r io.Reader, streamId uint32) (http.Header, error) {
146 var numHeaders uint16
147 if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil {
148 return nil, err
149 }
150 var e error
151 h := make(http.Header, int(numHeaders))
152 for i := 0; i < int(numHeaders); i++ {
153 var length uint16
154 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
155 return nil, err
156 }
157 nameBytes := make([]byte, length)
158 if _, err := io.ReadFull(r, nameBytes); err != nil {
159 return nil, err
160 }
161 name := string(nameBytes)
162 if name != strings.ToLower(name) {
163 e = &Error{UnlowercasedHeaderName, streamId}
164 name = strings.ToLower(name)
165 }
166 if h[name] != nil {
167 e = &Error{DuplicateHeaders, streamId}
168 }
169 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
170 return nil, err
171 }
172 value := make([]byte, length)
173 if _, err := io.ReadFull(r, value); err != nil {
174 return nil, err
175 }
176 valueList := strings.Split(string(value), "\x00")
177 for _, v := range valueList {
178 h.Add(name, v)
179 }
180 }
181 if e != nil {
182 return h, e
183 }
184 return h, nil
185 }
186
187 func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) error {
188 frame.CFHeader = h
189 var err error
190 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
191 return err
192 }
193 if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId) ; err != nil {
194 return err
195 }
196 if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {
197 return err
198 }
199 frame.Priority >>= 14
200
201 reader := f.r
202 if !f.headerCompressionDisabled {
203 f.uncorkHeaderDecompressor(int64(h.length - 10))
204 reader = f.headerDecompressor
205 }
206
207 frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
208 if !f.headerCompressionDisabled && ((err == io.EOF && f.headerReader.N = = 0) || f.headerReader.N != 0) {
209 err = &Error{WrongCompressedPayloadSize, 0}
210 }
211 if err != nil {
212 return err
213 }
214 // Remove this condition when we bump Version to 3.
215 if Version >= 3 {
216 for h := range frame.Headers {
217 if invalidReqHeaders[h] {
218 return &Error{InvalidHeaderPresent, frame.Stream Id}
219 }
220 }
221 }
222 return nil
223 }
224
225 func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) e rror {
226 frame.CFHeader = h
227 var err error
228 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
229 return err
230 }
231 var unused uint16
232 if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
233 return err
234 }
235 reader := f.r
236 if !f.headerCompressionDisabled {
237 f.uncorkHeaderDecompressor(int64(h.length - 6))
238 reader = f.headerDecompressor
239 }
240 frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
241 if !f.headerCompressionDisabled && ((err == io.EOF && f.headerReader.N = = 0) || f.headerReader.N != 0) {
242 err = &Error{WrongCompressedPayloadSize, 0}
243 }
244 if err != nil {
245 return err
246 }
247 // Remove this condition when we bump Version to 3.
248 if Version >= 3 {
249 for h := range frame.Headers {
250 if invalidRespHeaders[h] {
251 return &Error{InvalidHeaderPresent, frame.Stream Id}
252 }
253 }
254 }
255 return nil
256 }
257
258 func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) err or {
259 frame.CFHeader = h
260 var err error
261 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
262 return err
263 }
264 var unused uint16
265 if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
266 return err
267 }
268 reader := f.r
269 if !f.headerCompressionDisabled {
270 f.uncorkHeaderDecompressor(int64(h.length - 6))
271 reader = f.headerDecompressor
272 }
273 frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
274 if !f.headerCompressionDisabled && ((err == io.EOF && f.headerReader.N = = 0) || f.headerReader.N != 0) {
275 err = &Error{WrongCompressedPayloadSize, 0}
276 }
277 if err != nil {
278 return err
279 }
280
281 // Remove this condition when we bump Version to 3.
282 if Version >= 3 {
283 var invalidHeaders map[string]bool
284 if frame.StreamId%2 == 0 {
285 invalidHeaders = invalidReqHeaders
286 } else {
287 invalidHeaders = invalidRespHeaders
288 }
289 for h := range frame.Headers {
290 if invalidHeaders[h] {
291 return &Error{InvalidHeaderPresent, frame.Stream Id}
292 }
293 }
294 }
295 return nil
296 }
297
298 func (f *Framer) parseDataFrame(streamId uint32) (*DataFrame, error) {
299 var length uint32
300 if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
301 return nil, err
302 }
303 var frame DataFrame
304 frame.StreamId = streamId
305 frame.Flags = DataFlags(length >> 24)
306 length &= 0xffffff
307 frame.Data = make([]byte, length)
308 if _, err := io.ReadFull(f.r, frame.Data); err != nil {
309 return nil, err
310 }
311 return &frame, nil
312 }
OLDNEW
« no previous file with comments | « dict/dict.go ('k') | spdy/spdy_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b