OLD | NEW |
(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 } |
OLD | NEW |