OSDN Git Service

libgo: Update to weekly 2011-11-09.
[pf3gnuchains/gcc-fork.git] / libgo / go / exp / spdy / read.go
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 != nil {
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); err != 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(HeaderDictionary))
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.StreamId}
219                         }
220                 }
221         }
222         return nil
223 }
224
225 func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) error {
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.StreamId}
252                         }
253                 }
254         }
255         return nil
256 }
257
258 func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) error {
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.StreamId}
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 }