withcoderesponsewriter.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package response
  2. import (
  3. "bufio"
  4. "errors"
  5. "net"
  6. "net/http"
  7. )
  8. // A WithCodeResponseWriter is a helper to delay sealing a http.ResponseWriter on writing code.
  9. type WithCodeResponseWriter struct {
  10. Writer http.ResponseWriter
  11. Code int
  12. }
  13. // NewWithCodeResponseWriter returns a WithCodeResponseWriter.
  14. // If writer is already a WithCodeResponseWriter, it returns writer directly.
  15. func NewWithCodeResponseWriter(writer http.ResponseWriter) *WithCodeResponseWriter {
  16. switch w := writer.(type) {
  17. case *WithCodeResponseWriter:
  18. return w
  19. default:
  20. return &WithCodeResponseWriter{
  21. Writer: writer,
  22. Code: http.StatusOK,
  23. }
  24. }
  25. }
  26. // Flush flushes the response writer.
  27. func (w *WithCodeResponseWriter) Flush() {
  28. if flusher, ok := w.Writer.(http.Flusher); ok {
  29. flusher.Flush()
  30. }
  31. }
  32. // Header returns the http header.
  33. func (w *WithCodeResponseWriter) Header() http.Header {
  34. return w.Writer.Header()
  35. }
  36. // Hijack implements the http.Hijacker interface.
  37. // This expands the Response to fulfill http.Hijacker if the underlying http.ResponseWriter supports it.
  38. func (w *WithCodeResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  39. if hijacked, ok := w.Writer.(http.Hijacker); ok {
  40. return hijacked.Hijack()
  41. }
  42. return nil, nil, errors.New("server doesn't support hijacking")
  43. }
  44. // Write writes bytes into w.
  45. func (w *WithCodeResponseWriter) Write(bytes []byte) (int, error) {
  46. return w.Writer.Write(bytes)
  47. }
  48. // WriteHeader writes code into w, and not sealing the writer.
  49. func (w *WithCodeResponseWriter) WriteHeader(code int) {
  50. w.Writer.WriteHeader(code)
  51. w.Code = code
  52. }