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.
16 func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) os.Error {
17 return f.readSynStreamFrame(h, frame)
20 func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) os.Error {
21 return f.readSynReplyFrame(h, frame)
24 func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) os.Error {
26 if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
29 if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
35 func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) os.Error {
37 var numSettings uint32
38 if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {
41 frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings)
42 for i := uint32(0); i < numSettings; i++ {
43 if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil {
46 frame.FlagIdValues[i].Flag = SettingsFlag((frame.FlagIdValues[i].Id & 0xff000000) >> 24)
47 frame.FlagIdValues[i].Id &= 0xffffff
48 if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Value); err != nil {
55 func (frame *NoopFrame) read(h ControlFrameHeader, f *Framer) os.Error {
60 func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) os.Error {
62 if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {
68 func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) os.Error {
70 if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil {
76 func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) os.Error {
77 return f.readHeadersFrame(h, frame)
80 func newControlFrame(frameType ControlFrameType) (controlFrame, os.Error) {
81 ctor, ok := cframeCtor[frameType]
83 return nil, &Error{Err: InvalidControlFrame}
88 var cframeCtor = map[ControlFrameType]func() controlFrame{
89 TypeSynStream: func() controlFrame { return new(SynStreamFrame) },
90 TypeSynReply: func() controlFrame { return new(SynReplyFrame) },
91 TypeRstStream: func() controlFrame { return new(RstStreamFrame) },
92 TypeSettings: func() controlFrame { return new(SettingsFrame) },
93 TypeNoop: func() controlFrame { return new(NoopFrame) },
94 TypePing: func() controlFrame { return new(PingFrame) },
95 TypeGoAway: func() controlFrame { return new(GoAwayFrame) },
96 TypeHeaders: func() controlFrame { return new(HeadersFrame) },
97 // TODO(willchan): Add TypeWindowUpdate
100 func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) os.Error {
101 if f.headerDecompressor != nil {
102 f.headerReader.N = payloadSize
105 f.headerReader = io.LimitedReader{R: f.r, N: payloadSize}
106 decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(HeaderDictionary))
110 f.headerDecompressor = decompressor
114 // ReadFrame reads SPDY encoded data and returns a decompressed Frame.
115 func (f *Framer) ReadFrame() (Frame, os.Error) {
117 if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {
120 if (firstWord & 0x80000000) != 0 {
121 frameType := ControlFrameType(firstWord & 0xffff)
122 version := uint16(0x7fff & (firstWord >> 16))
123 return f.parseControlFrame(version, frameType)
125 return f.parseDataFrame(firstWord & 0x7fffffff)
128 func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, os.Error) {
130 if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
133 flags := ControlFlags((length & 0xff000000) >> 24)
135 header := ControlFrameHeader{version, frameType, flags, length}
136 cframe, err := newControlFrame(frameType)
140 if err = cframe.read(header, f); err != nil {
146 func parseHeaderValueBlock(r io.Reader, streamId uint32) (http.Header, os.Error) {
147 var numHeaders uint16
148 if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil {
152 h := make(http.Header, int(numHeaders))
153 for i := 0; i < int(numHeaders); i++ {
155 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
158 nameBytes := make([]byte, length)
159 if _, err := io.ReadFull(r, nameBytes); err != nil {
162 name := string(nameBytes)
163 if name != strings.ToLower(name) {
164 e = &Error{UnlowercasedHeaderName, streamId}
165 name = strings.ToLower(name)
168 e = &Error{DuplicateHeaders, streamId}
170 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
173 value := make([]byte, length)
174 if _, err := io.ReadFull(r, value); err != nil {
177 valueList := strings.Split(string(value), "\x00")
178 for _, v := range valueList {
188 func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) os.Error {
191 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
194 if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil {
197 if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {
200 frame.Priority >>= 14
203 if !f.headerCompressionDisabled {
204 f.uncorkHeaderDecompressor(int64(h.length - 10))
205 reader = f.headerDecompressor
208 frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
209 if !f.headerCompressionDisabled && ((err == os.EOF && f.headerReader.N == 0) || f.headerReader.N != 0) {
210 err = &Error{WrongCompressedPayloadSize, 0}
215 // Remove this condition when we bump Version to 3.
217 for h := range frame.Headers {
218 if invalidReqHeaders[h] {
219 return &Error{InvalidHeaderPresent, frame.StreamId}
226 func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) os.Error {
229 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
233 if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
237 if !f.headerCompressionDisabled {
238 f.uncorkHeaderDecompressor(int64(h.length - 6))
239 reader = f.headerDecompressor
241 frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
242 if !f.headerCompressionDisabled && ((err == os.EOF && f.headerReader.N == 0) || f.headerReader.N != 0) {
243 err = &Error{WrongCompressedPayloadSize, 0}
248 // Remove this condition when we bump Version to 3.
250 for h := range frame.Headers {
251 if invalidRespHeaders[h] {
252 return &Error{InvalidHeaderPresent, frame.StreamId}
259 func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) os.Error {
262 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
266 if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
270 if !f.headerCompressionDisabled {
271 f.uncorkHeaderDecompressor(int64(h.length - 6))
272 reader = f.headerDecompressor
274 frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
275 if !f.headerCompressionDisabled && ((err == os.EOF && f.headerReader.N == 0) || f.headerReader.N != 0) {
276 err = &Error{WrongCompressedPayloadSize, 0}
282 // Remove this condition when we bump Version to 3.
284 var invalidHeaders map[string]bool
285 if frame.StreamId%2 == 0 {
286 invalidHeaders = invalidReqHeaders
288 invalidHeaders = invalidRespHeaders
290 for h := range frame.Headers {
291 if invalidHeaders[h] {
292 return &Error{InvalidHeaderPresent, frame.StreamId}
299 func (f *Framer) parseDataFrame(streamId uint32) (*DataFrame, os.Error) {
301 if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
305 frame.StreamId = streamId
306 frame.Flags = DataFlags(length >> 24)
308 frame.Data = make([]byte, length)
309 if _, err := io.ReadFull(f.r, frame.Data); err != nil {