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) write(f *Framer) os.Error {
16 return f.writeSynStreamFrame(frame)
19 func (frame *SynReplyFrame) write(f *Framer) os.Error {
20 return f.writeSynReplyFrame(frame)
23 func (frame *RstStreamFrame) write(f *Framer) (err os.Error) {
24 frame.CFHeader.version = Version
25 frame.CFHeader.frameType = TypeRstStream
26 frame.CFHeader.length = 8
28 // Serialize frame to Writer
29 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
32 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
35 if err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil {
41 func (frame *SettingsFrame) write(f *Framer) (err os.Error) {
42 frame.CFHeader.version = Version
43 frame.CFHeader.frameType = TypeSettings
44 frame.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4)
46 // Serialize frame to Writer
47 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
50 if err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil {
53 for _, flagIdValue := range frame.FlagIdValues {
54 flagId := (uint32(flagIdValue.Flag) << 24) | uint32(flagIdValue.Id)
55 if err = binary.Write(f.w, binary.BigEndian, flagId); err != nil {
58 if err = binary.Write(f.w, binary.BigEndian, flagIdValue.Value); err != nil {
65 func (frame *NoopFrame) write(f *Framer) os.Error {
66 frame.CFHeader.version = Version
67 frame.CFHeader.frameType = TypeNoop
69 // Serialize frame to Writer
70 return writeControlFrameHeader(f.w, frame.CFHeader)
73 func (frame *PingFrame) write(f *Framer) (err os.Error) {
74 frame.CFHeader.version = Version
75 frame.CFHeader.frameType = TypePing
76 frame.CFHeader.length = 4
78 // Serialize frame to Writer
79 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
82 if err = binary.Write(f.w, binary.BigEndian, frame.Id); err != nil {
88 func (frame *GoAwayFrame) write(f *Framer) (err os.Error) {
89 frame.CFHeader.version = Version
90 frame.CFHeader.frameType = TypeGoAway
91 frame.CFHeader.length = 4
93 // Serialize frame to Writer
94 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
97 if err = binary.Write(f.w, binary.BigEndian, frame.LastGoodStreamId); err != nil {
103 func (frame *HeadersFrame) write(f *Framer) os.Error {
104 return f.writeHeadersFrame(frame)
107 func (frame *DataFrame) write(f *Framer) os.Error {
108 return f.writeDataFrame(frame)
111 // WriteFrame writes a frame.
112 func (f *Framer) WriteFrame(frame Frame) os.Error {
113 return frame.write(f)
116 func writeControlFrameHeader(w io.Writer, h ControlFrameHeader) os.Error {
117 if err := binary.Write(w, binary.BigEndian, 0x8000|h.version); err != nil {
120 if err := binary.Write(w, binary.BigEndian, h.frameType); err != nil {
123 flagsAndLength := (uint32(h.Flags) << 24) | h.length
124 if err := binary.Write(w, binary.BigEndian, flagsAndLength); err != nil {
130 func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err os.Error) {
132 if err = binary.Write(w, binary.BigEndian, uint16(len(h))); err != nil {
136 for name, values := range h {
137 if err = binary.Write(w, binary.BigEndian, uint16(len(name))); err != nil {
141 name = strings.ToLower(name)
142 if _, err = io.WriteString(w, name); err != nil {
146 v := strings.Join(values, "\x00")
147 if err = binary.Write(w, binary.BigEndian, uint16(len(v))); err != nil {
151 if _, err = io.WriteString(w, v); err != nil {
159 func (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err os.Error) {
160 // Marshal the headers.
161 var writer io.Writer = f.headerBuf
162 if !f.headerCompressionDisabled {
163 writer = f.headerCompressor
165 if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
168 if !f.headerCompressionDisabled {
169 f.headerCompressor.Flush()
172 // Set ControlFrameHeader
173 frame.CFHeader.version = Version
174 frame.CFHeader.frameType = TypeSynStream
175 frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10)
177 // Serialize frame to Writer
178 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
181 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
184 if err = binary.Write(f.w, binary.BigEndian, frame.AssociatedToStreamId); err != nil {
187 if err = binary.Write(f.w, binary.BigEndian, frame.Priority<<14); err != nil {
190 if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
197 func (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err os.Error) {
198 // Marshal the headers.
199 var writer io.Writer = f.headerBuf
200 if !f.headerCompressionDisabled {
201 writer = f.headerCompressor
203 if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
206 if !f.headerCompressionDisabled {
207 f.headerCompressor.Flush()
210 // Set ControlFrameHeader
211 frame.CFHeader.version = Version
212 frame.CFHeader.frameType = TypeSynReply
213 frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 6)
215 // Serialize frame to Writer
216 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
219 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
222 if err = binary.Write(f.w, binary.BigEndian, uint16(0)); err != nil {
225 if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
232 func (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err os.Error) {
233 // Marshal the headers.
234 var writer io.Writer = f.headerBuf
235 if !f.headerCompressionDisabled {
236 writer = f.headerCompressor
238 if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
241 if !f.headerCompressionDisabled {
242 f.headerCompressor.Flush()
245 // Set ControlFrameHeader
246 frame.CFHeader.version = Version
247 frame.CFHeader.frameType = TypeHeaders
248 frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 6)
250 // Serialize frame to Writer
251 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
254 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
257 if err = binary.Write(f.w, binary.BigEndian, uint16(0)); err != nil {
260 if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
267 func (f *Framer) writeDataFrame(frame *DataFrame) (err os.Error) {
268 // Validate DataFrame
269 if frame.StreamId&0x80000000 != 0 || len(frame.Data) >= 0x0f000000 {
270 return &Error{InvalidDataFrame, frame.StreamId}
273 // Serialize frame to Writer
274 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
277 flagsAndLength := (uint32(frame.Flags) << 24) | uint32(len(frame.Data))
278 if err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil {
281 if _, err = f.w.Write(frame.Data); err != nil {