// Write is one method with which request data is sent. func (s *RequestStream) Write(inputData []byte) (int, error) { if s.closed() || s.state.ClosedHere() { return 0, errors.New("Error: Stream already closed.") } // Copy the data locally to avoid any pointer issues. data := make([]byte, len(inputData)) copy(data, inputData) // Send any new headers. s.writeHeader() // Chunk the response if necessary. written := 0 for len(data) > common.MAX_DATA_SIZE { dataFrame := new(frames.DATA) dataFrame.StreamID = s.streamID dataFrame.Data = data[:common.MAX_DATA_SIZE] s.output <- dataFrame written += common.MAX_DATA_SIZE } n := len(data) if n == 0 { return written, nil } dataFrame := new(frames.DATA) dataFrame.StreamID = s.streamID dataFrame.Data = data s.output <- dataFrame return written + n, nil }
func (p *PushStream) Finish() { p.writeHeader() end := new(frames.DATA) end.StreamID = p.streamID end.Data = []byte{} end.Flags = common.FLAG_FIN p.output <- end p.Close() }
// Write is used for sending data in the push. func (p *PushStream) Write(inputData []byte) (int, error) { if p.closed() || p.state.ClosedHere() { return 0, errors.New("Error: Stream already closed.") } state := p.origin.State() if p.origin == nil || state.ClosedHere() { return 0, errors.New("Error: Origin stream is closed.") } p.writeHeader() // Copy the data locally to avoid any pointer issues. data := make([]byte, len(inputData)) copy(data, inputData) // Chunk the response if necessary. written := 0 for len(data) > common.MAX_DATA_SIZE { dataFrame := new(frames.DATA) dataFrame.StreamID = p.streamID dataFrame.Data = data[:common.MAX_DATA_SIZE] p.output <- dataFrame written += common.MAX_DATA_SIZE } n := len(data) if n == 0 { return written, nil } dataFrame := new(frames.DATA) dataFrame.StreamID = p.streamID dataFrame.Data = data p.output <- dataFrame return written + n, nil }
// run is the main control path of // the stream. It is prepared, the // registered handler is called, // and then the stream is cleaned // up and closed. func (s *ResponseStream) Run() error { // Catch any panics. defer func() { if v := recover(); v != nil { if s != nil && s.state != nil && !s.state.Closed() { log.Printf("Encountered stream error: %v (%[1]T)\n", v) } } }() // Make sure Request is prepared. if s.requestBody == nil || s.request.Body == nil { s.requestBody = new(bytes.Buffer) s.request.Body = &common.ReadCloser{s.requestBody} } // Wait until the full request has been received. <-s.ready /*************** *** HANDLER *** ***************/ s.handler.ServeHTTP(s, s.request) // Close the stream with a SYN_REPLY if // none has been sent, or an empty DATA // frame, if a SYN_REPLY has been sent // already. // If the stream is already closed at // this end, then nothing happens. if !s.unidirectional { if s.state.OpenHere() && !s.wroteHeader { h := s.header if h == nil { h = make(http.Header) } h.Set("status", "200") h.Set("version", "HTTP/1.1") // Create the response SYN_REPLY. synReply := new(frames.SYN_REPLY) synReply.Flags = common.FLAG_FIN synReply.StreamID = s.streamID synReply.Header = h s.output <- synReply } else if s.state.OpenHere() { // Create the DATA. data := new(frames.DATA) data.StreamID = s.streamID data.Flags = common.FLAG_FIN data.Data = []byte{} s.output <- data } } // Clean up state. s.state.CloseHere() if s.state.Closed() { return s.Close() } return nil }