response_limit.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package imagedata
  2. import (
  3. "io"
  4. "net/http"
  5. )
  6. // hardLimitReadCloser is a wrapper around io.ReadCloser
  7. // that limits the number of bytes it can read from the upstream reader.
  8. type hardLimitReadCloser struct {
  9. r io.ReadCloser
  10. left int
  11. }
  12. func (lr *hardLimitReadCloser) Read(p []byte) (n int, err error) {
  13. if lr.left <= 0 {
  14. return 0, newFileSizeError()
  15. }
  16. if len(p) > lr.left {
  17. p = p[0:lr.left]
  18. }
  19. n, err = lr.r.Read(p)
  20. lr.left -= n
  21. return
  22. }
  23. func (lr *hardLimitReadCloser) Close() error {
  24. return lr.r.Close()
  25. }
  26. // limitResponseSize limits the size of the response body to MaxSrcFileSize (if set).
  27. // First, it tries to use Content-Length header to check the limit.
  28. // If Content-Length is not set, it limits the size of the response body by wrapping
  29. // body reader with hard limit reader.
  30. func limitResponseSize(r *http.Response, limit int) (*http.Response, error) {
  31. if limit == 0 {
  32. return r, nil
  33. }
  34. // If Content-Length was set, limit the size of the response body before reading it
  35. size := int(r.ContentLength)
  36. if size > limit {
  37. return nil, newFileSizeError()
  38. }
  39. // hard-limit the response body reader
  40. r.Body = &hardLimitReadCloser{r: r.Body, left: limit}
  41. return r, nil
  42. }