simplify clanker slop

This commit is contained in:
Patricio Whittingslow
2026-07-26 22:08:57 -03:00
parent ebfd80c80c
commit 33ed289d30
2 changed files with 15 additions and 29 deletions
+14 -28
View File
@@ -480,9 +480,8 @@ type MultipartSink struct {
//
// A part header that does not fit buf is refused with [lneto.ErrShortBuffer],
// since reading more can never complete it, leaving the caller free to answer
// 413. backoff paces reads that return no data, as in [Handle]. The body is
// consumed, so call this before [Exchange.ReadBody].
func (exch *Exchange) ReadMultiparts(dst []MultipartSink, buf []byte, newSink func(hdr *httpraw.MultipartHeader) io.WriteCloser, backoff lneto.BackoffStrategy) (_ []MultipartSink, _ error) {
// 413. The body is consumed, so call this before [Exchange.ReadBody].
func (exch *Exchange) ReadMultiparts(dst []MultipartSink, buf []byte, newSink func(hdr *httpraw.MultipartHeader) io.WriteCloser) (_ []MultipartSink, _ error) {
mp, err := exch.RequestMultipart()
if err != nil {
return dst, err
@@ -510,10 +509,15 @@ func (exch *Exchange) ReadMultiparts(dst []MultipartSink, buf []byte, newSink fu
dst = dst[:len(dst)-1]
return dst, lneto.ErrShortBuffer // Header longer than buf.
}
buflen, err = exch.readBodyMore(buf, buflen, backoff)
if err != nil {
// A read that both delivers and fails, as the last of the body
// followed by a hangup does, may still hold what the parser is
// waiting for: take the data and let the error surface on the
// next read.
n, readErr := exch.ReadBody(buf[buflen:])
buflen += n
if n == 0 && readErr != nil {
dst = dst[:len(dst)-1]
return dst, err
return dst, readErr
}
}
part.Sink = newSink(&part.Header)
@@ -530,9 +534,10 @@ func (exch *Exchange) ReadMultiparts(dst []MultipartSink, buf []byte, newSink fu
if done {
break // Buffer now starts at the next part's delimiter.
}
buflen, err = exch.readBodyMore(buf, buflen, backoff)
if err != nil {
return dst, err
n, readErr := exch.ReadBody(buf[buflen:])
buflen += n
if n == 0 && readErr != nil {
return dst, readErr // Body ended mid part.
}
}
if part.Sink != nil {
@@ -543,25 +548,6 @@ func (exch *Exchange) ReadMultiparts(dst []MultipartSink, buf []byte, newSink fu
}
}
// readBodyMore reads more of the body in behind the buflen bytes already in buf,
// returning the new length once at least one byte arrived. A parser that stalled
// for want of data always makes progress or gets an error, never spins.
func (exch *Exchange) readBodyMore(buf []byte, buflen int, backoff lneto.BackoffStrategy) (int, error) {
for backoffs := uint(0); ; backoffs++ {
n, err := exch.ReadBody(buf[buflen:])
buflen += n
if n > 0 {
// Data first: a read that both delivered and failed, as the last
// of the body followed by a hangup does, may still hold the
// closing delimiter. The error surfaces on the next read.
return buflen, nil
} else if err != nil {
return buflen, err
}
backoff.Do(backoffs) // Nothing pending on the conn yet.
}
}
// RequestHeader returns the value of the first request header field matching
// key, or nil if absent. Key matching is case sensitive.
func (exch *Exchange) RequestHeader(key string) []byte {
+1 -1
View File
@@ -790,7 +790,7 @@ func serveMultipart(t *testing.T, request string, bufSize int, skip string, segm
}
return new(partBuffer)
}
parts, gotErr = exch.ReadMultiparts(parts, make([]byte, bufSize), newSink, nopBackoff)
parts, gotErr = exch.ReadMultiparts(parts, make([]byte, bufSize), newSink)
})
exch := newExchange(t, conn, 1024, false)
if err := Handle(exch, &sm, nopBackoff); err != nil {