OSDN Git Service

Add sparc fmaf test.
[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         "http"
11         "io"
12         "os"
13         "strings"
14 )
15
16 func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) os.Error {
17         return f.readSynStreamFrame(h, frame)
18 }
19
20 func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) os.Error {
21         return f.readSynReplyFrame(h, frame)
22 }
23
24 func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) os.Error {
25         frame.CFHeader = h
26         if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
27                 return err
28         }
29         if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
30                 return err
31         }
32         return nil
33 }
34
35 func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) os.Error {
36         frame.CFHeader = h
37         var numSettings uint32
38         if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {
39                 return err
40         }
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 {
44                         return err
45                 }
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 {
49                         return err
50                 }
51         }
52         return nil
53 }
54
55 func (frame *NoopFrame) read(h ControlFrameHeader, f *Framer) os.Error {
56         frame.CFHeader = h
57         return nil
58 }
59
60 func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) os.Error {
61         frame.CFHeader = h
62         if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {
63                 return err
64         }
65         return nil
66 }
67
68 func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) os.Error {
69         frame.CFHeader = h
70         if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil {
71                 return err
72         }
73         return nil
74 }
75
76 func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) os.Error {
77         return f.readHeadersFrame(h, frame)
78 }
79
80 func newControlFrame(frameType ControlFrameType) (controlFrame, os.Error) {
81         ctor, ok := cframeCtor[frameType]
82         if !ok {
83                 return nil, &Error{Err: InvalidControlFrame}
84         }
85         return ctor(), nil
86 }
87
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
98 }
99
100 func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) os.Error {
101         if f.headerDecompressor != nil {
102                 f.headerReader.N = payloadSize
103                 return nil
104         }
105         f.headerReader = io.LimitedReader{R: f.r, N: payloadSize}
106         decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(HeaderDictionary))
107         if err != nil {
108                 return err
109         }
110         f.headerDecompressor = decompressor
111         return nil
112 }
113
114 // ReadFrame reads SPDY encoded data and returns a decompressed Frame.
115 func (f *Framer) ReadFrame() (Frame, os.Error) {
116         var firstWord uint32
117         if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {
118                 return nil, err
119         }
120         if (firstWord & 0x80000000) != 0 {
121                 frameType := ControlFrameType(firstWord & 0xffff)
122                 version := uint16(0x7fff & (firstWord >> 16))
123                 return f.parseControlFrame(version, frameType)
124         }
125         return f.parseDataFrame(firstWord & 0x7fffffff)
126 }
127
128 func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, os.Error) {
129         var length uint32
130         if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
131                 return nil, err
132         }
133         flags := ControlFlags((length & 0xff000000) >> 24)
134         length &= 0xffffff
135         header := ControlFrameHeader{version, frameType, flags, length}
136         cframe, err := newControlFrame(frameType)
137         if err != nil {
138                 return nil, err
139         }
140         if err = cframe.read(header, f); err != nil {
141                 return nil, err
142         }
143         return cframe, nil
144 }
145
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 {
149                 return nil, err
150         }
151         var e os.Error
152         h := make(http.Header, int(numHeaders))
153         for i := 0; i < int(numHeaders); i++ {
154                 var length uint16
155                 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
156                         return nil, err
157                 }
158                 nameBytes := make([]byte, length)
159                 if _, err := io.ReadFull(r, nameBytes); err != nil {
160                         return nil, err
161                 }
162                 name := string(nameBytes)
163                 if name != strings.ToLower(name) {
164                         e = &Error{UnlowercasedHeaderName, streamId}
165                         name = strings.ToLower(name)
166                 }
167                 if h[name] != nil {
168                         e = &Error{DuplicateHeaders, streamId}
169                 }
170                 if err := binary.Read(r, binary.BigEndian, &length); err != nil {
171                         return nil, err
172                 }
173                 value := make([]byte, length)
174                 if _, err := io.ReadFull(r, value); err != nil {
175                         return nil, err
176                 }
177                 valueList := strings.Split(string(value), "\x00")
178                 for _, v := range valueList {
179                         h.Add(name, v)
180                 }
181         }
182         if e != nil {
183                 return h, e
184         }
185         return h, nil
186 }
187
188 func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) os.Error {
189         frame.CFHeader = h
190         var err os.Error
191         if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
192                 return err
193         }
194         if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil {
195                 return err
196         }
197         if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {
198                 return err
199         }
200         frame.Priority >>= 14
201
202         reader := f.r
203         if !f.headerCompressionDisabled {
204                 f.uncorkHeaderDecompressor(int64(h.length - 10))
205                 reader = f.headerDecompressor
206         }
207
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}
211         }
212         if err != nil {
213                 return err
214         }
215         // Remove this condition when we bump Version to 3.
216         if Version >= 3 {
217                 for h := range frame.Headers {
218                         if invalidReqHeaders[h] {
219                                 return &Error{InvalidHeaderPresent, frame.StreamId}
220                         }
221                 }
222         }
223         return nil
224 }
225
226 func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) os.Error {
227         frame.CFHeader = h
228         var err os.Error
229         if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
230                 return err
231         }
232         var unused uint16
233         if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
234                 return err
235         }
236         reader := f.r
237         if !f.headerCompressionDisabled {
238                 f.uncorkHeaderDecompressor(int64(h.length - 6))
239                 reader = f.headerDecompressor
240         }
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}
244         }
245         if err != nil {
246                 return err
247         }
248         // Remove this condition when we bump Version to 3.
249         if Version >= 3 {
250                 for h := range frame.Headers {
251                         if invalidRespHeaders[h] {
252                                 return &Error{InvalidHeaderPresent, frame.StreamId}
253                         }
254                 }
255         }
256         return nil
257 }
258
259 func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) os.Error {
260         frame.CFHeader = h
261         var err os.Error
262         if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
263                 return err
264         }
265         var unused uint16
266         if err = binary.Read(f.r, binary.BigEndian, &unused); err != nil {
267                 return err
268         }
269         reader := f.r
270         if !f.headerCompressionDisabled {
271                 f.uncorkHeaderDecompressor(int64(h.length - 6))
272                 reader = f.headerDecompressor
273         }
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}
277         }
278         if err != nil {
279                 return err
280         }
281
282         // Remove this condition when we bump Version to 3.
283         if Version >= 3 {
284                 var invalidHeaders map[string]bool
285                 if frame.StreamId%2 == 0 {
286                         invalidHeaders = invalidReqHeaders
287                 } else {
288                         invalidHeaders = invalidRespHeaders
289                 }
290                 for h := range frame.Headers {
291                         if invalidHeaders[h] {
292                                 return &Error{InvalidHeaderPresent, frame.StreamId}
293                         }
294                 }
295         }
296         return nil
297 }
298
299 func (f *Framer) parseDataFrame(streamId uint32) (*DataFrame, os.Error) {
300         var length uint32
301         if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
302                 return nil, err
303         }
304         var frame DataFrame
305         frame.StreamId = streamId
306         frame.Flags = DataFlags(length >> 24)
307         length &= 0xffffff
308         frame.Data = make([]byte, length)
309         if _, err := io.ReadFull(f.r, frame.Data); err != nil {
310                 return nil, err
311         }
312         return &frame, nil
313 }