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.
15 func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) error {
16 return f.readSynStreamFrame(h, frame)
19 func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) error {
20 return f.readSynReplyFrame(h, frame)
23 func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) error {
25 if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
28 if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
34 func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error {
36 var numSettings uint32
37 if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {
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 {
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 {
54 func (frame *NoopFrame) read(h ControlFrameHeader, f *Framer) error {
59 func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) error {
61 if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {
67 func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) error {
69 if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil {
75 func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) error {
76 return f.readHeadersFrame(h, frame)
79 func newControlFrame(frameType ControlFrameType) (controlFrame, error) {
80 ctor, ok := cframeCtor[frameType]
82 return nil, &Error{Err: InvalidControlFrame}
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
99 func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) error {
100 if f.headerDecompressor != nil {
101 f.headerReader.N = payloadSize
104 f.headerReader = io.LimitedReader{R: f.r, N: payloadSize}
105 decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(HeaderDictionary))
109 f.headerDecompressor = decompressor
113 // ReadFrame reads SPDY encoded data and returns a decompressed Frame.
114 func (f *Framer) ReadFrame() (Frame, error) {
116 if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {
119 if (firstWord & 0x80000000) != 0 {
120 frameType := ControlFrameType(firstWord & 0xffff)
121 version := uint16(0x7fff & (firstWord >> 16))
122 return f.parseControlFrame(version, frameType)
124 return f.parseDataFrame(firstWord & 0x7fffffff)
127 func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, error) {
129 if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
132 flags := ControlFlags((length & 0xff000000) >> 24)
134 header := ControlFrameHeader{version, frameType, flags, length}
135 cframe, err := newControlFrame(frameType)
139 if err = cframe.read(header, f); err != nil {
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 {
151 h := make(http.Header, int(numHeaders))
152 for i := 0; i < int(numHeaders); i++ {
154 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
157 nameBytes := make([]byte, length)
158 if _, err := io.ReadFull(r, nameBytes); err != nil {
161 name := string(nameBytes)
162 if name != strings.ToLower(name) {
163 e = &Error{UnlowercasedHeaderName, streamId}
164 name = strings.ToLower(name)
167 e = &Error{DuplicateHeaders, streamId}
169 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
172 value := make([]byte, length)
173 if _, err := io.ReadFull(r, value); err != nil {
176 valueList := strings.Split(string(value), "\x00")
177 for _, v := range valueList {
187 func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) error {
190 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
193 if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil {
196 if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {
199 frame.Priority >>= 14
202 if !f.headerCompressionDisabled {
203 f.uncorkHeaderDecompressor(int64(h.length - 10))
204 reader = f.headerDecompressor
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}
214 // Remove this condition when we bump Version to 3.
216 for h := range frame.Headers {
217 if invalidReqHeaders[h] {
218 return &Error{InvalidHeaderPresent, frame.StreamId}
225 func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) error {
228 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
232 if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
236 if !f.headerCompressionDisabled {
237 f.uncorkHeaderDecompressor(int64(h.length - 6))
238 reader = f.headerDecompressor
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}
247 // Remove this condition when we bump Version to 3.
249 for h := range frame.Headers {
250 if invalidRespHeaders[h] {
251 return &Error{InvalidHeaderPresent, frame.StreamId}
258 func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) error {
261 if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
265 if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
269 if !f.headerCompressionDisabled {
270 f.uncorkHeaderDecompressor(int64(h.length - 6))
271 reader = f.headerDecompressor
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}
281 // Remove this condition when we bump Version to 3.
283 var invalidHeaders map[string]bool
284 if frame.StreamId%2 == 0 {
285 invalidHeaders = invalidReqHeaders
287 invalidHeaders = invalidRespHeaders
289 for h := range frame.Headers {
290 if invalidHeaders[h] {
291 return &Error{InvalidHeaderPresent, frame.StreamId}
298 func (f *Framer) parseDataFrame(streamId uint32) (*DataFrame, error) {
300 if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
304 frame.StreamId = streamId
305 frame.Flags = DataFlags(length >> 24)
307 frame.Data = make([]byte, length)
308 if _, err := io.ReadFull(f.r, frame.Data); err != nil {