This guide tackles the issue of buffering in Go's HTTP response handling, where responses are typically buffered and sent in blocks to the client after the request is processed. For streaming scenarios, this may not be desirable.
The provided code snippet illustrates the problem, where two lines of data are supposed to be streamed but are instead sent simultaneously due to buffering.
One approach to address this is to flush the response buffer explicitly. Go's ResponseWriter provides a Flush method, but its availability is dependent on the specific implementation.
For an example, the following modified code incorporates flushing:
func handle(res http.ResponseWriter, req *http.Request) { fmt.Fprintf(res, "sending first line of data") if f, ok := res.(http.Flusher); ok { f.Flush() } sleep(10) //not real code fmt.Fprintf(res, "sending second line of data") }
In certain scenarios, such as streaming the output of an external command, direct flushing may not be sufficient. Go's pipe mechanism allows for direct streaming between the command's output and the response writer.
Here's a sample implementation:
pipeReader, pipeWriter := io.Pipe() cmd.Stdout = pipeWriter cmd.Stderr = pipeWriter go writeCmdOutput(res, pipeReader) err := cmd.Run() pipeWriter.Close() func writeCmdOutput(res http.ResponseWriter, pipeReader *io.PipeReader) { buffer := make([]byte, BUF_LEN) for { n, err := pipeReader.Read(buffer) if err != nil { pipeReader.Close() break } data := buffer[0:n] res.Write(data) if f, ok := res.(http.Flusher); ok { f.Flush() } //reset buffer for i := 0; i < n; i++ { buffer[i] = 0 } } }
For more flexibility, it's possible to use the TCP Hijacker, which grants direct control over the TCP connection. However, this approach requires a deeper understanding of network programming and is less recommended for general use cases.
Note that buffering may still occur in network components or within the client application, so it's crucial to evaluate your specific use case to determine the need for explicit flushing or alternative solutions.
The above is the detailed content of How Can I Stream HTTP Responses in Golang and Avoid Default Buffering?. For more information, please follow other related articles on the PHP Chinese website!