ghttp_response_writer.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. //
  7. package ghttp
  8. import (
  9. "bufio"
  10. "bytes"
  11. "net"
  12. "net/http"
  13. )
  14. // ResponseWriter is the custom writer for http response.
  15. type ResponseWriter struct {
  16. Status int // HTTP status.
  17. writer http.ResponseWriter // The underlying ResponseWriter.
  18. buffer *bytes.Buffer // The output buffer.
  19. hijacked bool // Mark this request is hijacked or not.
  20. wroteHeader bool // Is header wrote or not, avoiding error: superfluous/multiple response.WriteHeader call.
  21. }
  22. // RawWriter returns the underlying ResponseWriter.
  23. func (w *ResponseWriter) RawWriter() http.ResponseWriter {
  24. return w.writer
  25. }
  26. // Header implements the interface function of http.ResponseWriter.Header.
  27. func (w *ResponseWriter) Header() http.Header {
  28. return w.writer.Header()
  29. }
  30. // Write implements the interface function of http.ResponseWriter.Write.
  31. func (w *ResponseWriter) Write(data []byte) (int, error) {
  32. w.buffer.Write(data)
  33. return len(data), nil
  34. }
  35. // WriteHeader implements the interface of http.ResponseWriter.WriteHeader.
  36. func (w *ResponseWriter) WriteHeader(status int) {
  37. w.Status = status
  38. }
  39. // Hijack implements the interface function of http.Hijacker.Hijack.
  40. func (w *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  41. w.hijacked = true
  42. return w.writer.(http.Hijacker).Hijack()
  43. }
  44. // OutputBuffer outputs the buffer to client and clears the buffer.
  45. func (w *ResponseWriter) Flush() {
  46. if w.hijacked {
  47. return
  48. }
  49. if w.Status != 0 && !w.wroteHeader {
  50. w.wroteHeader = true
  51. w.writer.WriteHeader(w.Status)
  52. }
  53. // Default status text output.
  54. if w.Status != http.StatusOK && w.buffer.Len() == 0 {
  55. w.buffer.WriteString(http.StatusText(w.Status))
  56. }
  57. if w.buffer.Len() > 0 {
  58. w.writer.Write(w.buffer.Bytes())
  59. w.buffer.Reset()
  60. }
  61. }