I think there are still a little problem:
if maxBytesReader initialized with n<0, it will have a problem
I think that this will never trigger
see https://github.com/golang/go/blob/master/src/net/http/request.go#L740
func (l *maxBytesReader) Read(p []byte) (n int, err error) { toRead := l.n if l.n == 0 { if l.sawEOF { return l.tooLarge() // -------> I think that this will never trigger } // The underlying io.Reader may not return (0, io.EOF) // at EOF if the requested size is 0, so read 1 byte // instead. The io.Reader docs are a bit ambiguous // about the return value of Read when 0 bytes are // requested, and {bytes,strings}.Reader gets it wrong // too (it returns (0, nil) even at EOF). toRead = 1 } if int64(len(p)) > toRead { p = p[:toRead] } n, err = l.r.Read(p) if err == io.EOF { l.sawEOF = true } if l.n == 0 { // If we had zero bytes to read remaining (but hadn't seen EOF) // and we get a byte here, that means we went over our limit. if n > 0 { return l.tooLarge() } return 0, err } l.n -= int64(n) if l.n < 0 { l.n = 0 } return }
Here is my code:
type maxBytesReader struct { w ResponseWriter r io.ReadCloser // underlying reader n int64 // max bytes remaining stopped bool } func (l *maxBytesReader) tooLarge() (n int, err error) { if !l.stopped { l.stopped = true if res, ok := l.w.(*response); ok { res.requestTooLarge() } } return 0, errors.New("http: request body too large") } func (l *maxBytesReader) Read(p []byte) (n int, err error) { if l.n < 0 { return l.tooLarge() // Reached if and only if maxBytesReader initialized with n<0 } toRead := l.n if l.n == 0 { // The underlying io.Reader may not return (0, io.EOF) // at EOF if the requested size is 0, so read 1 byte // instead. The io.Reader docs are a bit ambiguous // about the return value of Read when 0 bytes are // requested, and {bytes,strings}.Reader gets it wrong // too (it returns (0, nil) even at EOF). toRead = 1 } if int64(len(p)) > toRead { p = p[:toRead] } n, err = l.r.Read(p) if l.n == 0 { // If we had zero bytes to read remaining (but hadn't seen EOF) // and we get a byte here, that means we went over our limit. if n > 0 { return l.tooLarge() } return 0, err // Usually 0, io.EOF } l.n -= int64(n) return }
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.