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.
14 func (frame *SynStreamFrame) write(f *Framer) error {
15 return f.writeSynStreamFrame(frame)
18 func (frame *SynReplyFrame) write(f *Framer) error {
19 return f.writeSynReplyFrame(frame)
22 func (frame *RstStreamFrame) write(f *Framer) (err error) {
23 frame.CFHeader.version = Version
24 frame.CFHeader.frameType = TypeRstStream
25 frame.CFHeader.length = 8
27 // Serialize frame to Writer
28 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
31 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
34 if err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil {
40 func (frame *SettingsFrame) write(f *Framer) (err error) {
41 frame.CFHeader.version = Version
42 frame.CFHeader.frameType = TypeSettings
43 frame.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4)
45 // Serialize frame to Writer
46 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
49 if err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil {
52 for _, flagIdValue := range frame.FlagIdValues {
53 flagId := (uint32(flagIdValue.Flag) << 24) | uint32(flagIdValue.Id)
54 if err = binary.Write(f.w, binary.BigEndian, flagId); err != nil {
57 if err = binary.Write(f.w, binary.BigEndian, flagIdValue.Value); err != nil {
64 func (frame *NoopFrame) write(f *Framer) error {
65 frame.CFHeader.version = Version
66 frame.CFHeader.frameType = TypeNoop
68 // Serialize frame to Writer
69 return writeControlFrameHeader(f.w, frame.CFHeader)
72 func (frame *PingFrame) write(f *Framer) (err error) {
73 frame.CFHeader.version = Version
74 frame.CFHeader.frameType = TypePing
75 frame.CFHeader.length = 4
77 // Serialize frame to Writer
78 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
81 if err = binary.Write(f.w, binary.BigEndian, frame.Id); err != nil {
87 func (frame *GoAwayFrame) write(f *Framer) (err error) {
88 frame.CFHeader.version = Version
89 frame.CFHeader.frameType = TypeGoAway
90 frame.CFHeader.length = 4
92 // Serialize frame to Writer
93 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
96 if err = binary.Write(f.w, binary.BigEndian, frame.LastGoodStreamId); err != nil {
102 func (frame *HeadersFrame) write(f *Framer) error {
103 return f.writeHeadersFrame(frame)
106 func (frame *DataFrame) write(f *Framer) error {
107 return f.writeDataFrame(frame)
110 // WriteFrame writes a frame.
111 func (f *Framer) WriteFrame(frame Frame) error {
112 return frame.write(f)
115 func writeControlFrameHeader(w io.Writer, h ControlFrameHeader) error {
116 if err := binary.Write(w, binary.BigEndian, 0x8000|h.version); err != nil {
119 if err := binary.Write(w, binary.BigEndian, h.frameType); err != nil {
122 flagsAndLength := (uint32(h.Flags) << 24) | h.length
123 if err := binary.Write(w, binary.BigEndian, flagsAndLength); err != nil {
129 func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) {
131 if err = binary.Write(w, binary.BigEndian, uint16(len(h))); err != nil {
135 for name, values := range h {
136 if err = binary.Write(w, binary.BigEndian, uint16(len(name))); err != nil {
140 name = strings.ToLower(name)
141 if _, err = io.WriteString(w, name); err != nil {
145 v := strings.Join(values, "\x00")
146 if err = binary.Write(w, binary.BigEndian, uint16(len(v))); err != nil {
150 if _, err = io.WriteString(w, v); err != nil {
158 func (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err error) {
159 // Marshal the headers.
160 var writer io.Writer = f.headerBuf
161 if !f.headerCompressionDisabled {
162 writer = f.headerCompressor
164 if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
167 if !f.headerCompressionDisabled {
168 f.headerCompressor.Flush()
171 // Set ControlFrameHeader
172 frame.CFHeader.version = Version
173 frame.CFHeader.frameType = TypeSynStream
174 frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10)
176 // Serialize frame to Writer
177 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
180 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
183 if err = binary.Write(f.w, binary.BigEndian, frame.AssociatedToStreamId); err != nil {
186 if err = binary.Write(f.w, binary.BigEndian, frame.Priority<<14); err != nil {
189 if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
196 func (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err error) {
197 // Marshal the headers.
198 var writer io.Writer = f.headerBuf
199 if !f.headerCompressionDisabled {
200 writer = f.headerCompressor
202 if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
205 if !f.headerCompressionDisabled {
206 f.headerCompressor.Flush()
209 // Set ControlFrameHeader
210 frame.CFHeader.version = Version
211 frame.CFHeader.frameType = TypeSynReply
212 frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 6)
214 // Serialize frame to Writer
215 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
218 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
221 if err = binary.Write(f.w, binary.BigEndian, uint16(0)); err != nil {
224 if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
231 func (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err error) {
232 // Marshal the headers.
233 var writer io.Writer = f.headerBuf
234 if !f.headerCompressionDisabled {
235 writer = f.headerCompressor
237 if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
240 if !f.headerCompressionDisabled {
241 f.headerCompressor.Flush()
244 // Set ControlFrameHeader
245 frame.CFHeader.version = Version
246 frame.CFHeader.frameType = TypeHeaders
247 frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 6)
249 // Serialize frame to Writer
250 if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
253 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
256 if err = binary.Write(f.w, binary.BigEndian, uint16(0)); err != nil {
259 if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
266 func (f *Framer) writeDataFrame(frame *DataFrame) (err error) {
267 // Validate DataFrame
268 if frame.StreamId&0x80000000 != 0 || len(frame.Data) >= 0x0f000000 {
269 return &Error{InvalidDataFrame, frame.StreamId}
272 // Serialize frame to Writer
273 if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
276 flagsAndLength := (uint32(frame.Flags) << 24) | uint32(len(frame.Data))
277 if err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil {
280 if _, err = f.w.Write(frame.Data); err != nil {