package pipeline import ( "errors" "io" ) const cdnBodyLimit = 8 << 20 // ErrCDNBodyTooLarge reports a CDN response larger than the 8 MiB decoded-body limit. var ErrCDNBodyTooLarge = errors.New("pipeline: cdn response body exceeds 8 MiB") type limitedCDNBody struct { io.ReadCloser remaining int64 } func (b *limitedCDNBody) Read(p []byte) (int, error) { if len(p) == 0 { return 0, nil } if b.remaining == 0 { var one [1]byte n, err := b.ReadCloser.Read(one[:]) if n > 0 { return 0, ErrCDNBodyTooLarge } return 0, err } if int64(len(p)) > b.remaining { p = p[:int(b.remaining)] } n, err := b.ReadCloser.Read(p) b.remaining -= int64(n) return n, err } // ReadCDNBody reads a CDN response and rejects decoded bodies above 8 MiB. // The extra byte distinguishes an exact-limit response from a truncated one. func ReadCDNBody(body io.Reader) ([]byte, error) { data, err := io.ReadAll(io.LimitReader(body, cdnBodyLimit+1)) if err != nil { return nil, err } if len(data) > cdnBodyLimit { return nil, ErrCDNBodyTooLarge } return data, nil }