timeout_response.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package server
  2. import (
  3. "net/http"
  4. "time"
  5. )
  6. // timeoutResponse manages response writer with timeout. It has
  7. // timeout on all write methods.
  8. type timeoutResponse struct {
  9. http.ResponseWriter
  10. controller *http.ResponseController
  11. timeout time.Duration
  12. }
  13. // newTimeoutResponse creates a new timeoutResponse
  14. func newTimeoutResponse(rw http.ResponseWriter, timeout time.Duration) http.ResponseWriter {
  15. return &timeoutResponse{
  16. ResponseWriter: rw,
  17. controller: http.NewResponseController(rw),
  18. timeout: timeout,
  19. }
  20. }
  21. // Write implements http.ResponseWriter.Write
  22. func (rw *timeoutResponse) Write(b []byte) (int, error) {
  23. var (
  24. n int
  25. err error
  26. )
  27. rw.withWriteDeadline(func() {
  28. n, err = rw.ResponseWriter.Write(b)
  29. })
  30. return n, err
  31. }
  32. // Header returns current HTTP headers
  33. func (rw *timeoutResponse) Header() http.Header {
  34. return rw.ResponseWriter.Header()
  35. }
  36. // withWriteDeadline executes a Write* function with a deadline
  37. func (rw *timeoutResponse) withWriteDeadline(f func()) {
  38. deadline := time.Now().Add(rw.timeout)
  39. // Set write deadline
  40. rw.controller.SetWriteDeadline(deadline)
  41. // Reset write deadline after method has finished
  42. defer rw.controller.SetWriteDeadline(time.Time{})
  43. f()
  44. }