diff --git a/http/httphi/exchange.go b/http/httphi/exchange.go index 337023b..94caab8 100644 --- a/http/httphi/exchange.go +++ b/http/httphi/exchange.go @@ -506,6 +506,62 @@ func (exch *Exchange) RequestContentLength() (_ int64, present bool, _ error) { return exch.RequestHeaderRaw().ContentLength() } +func (exch *Exchange) RequestParseForm(dst *httpraw.Form, parseURL, prioritizeURL bool) (err error) { + dst.Reset(nil, 0) + if parseURL { + err = dst.ReadFromBytes(exch.RequestQuery()) + + } + if !parseURL { + cl, ok, err := exch.RequestContentLength() + if cl == 0 { + return nil + } + var rw ExchangeRW + exch.ReadWriter(&rw) + _, err = dst.ReadLimited(&rw, int(cl)) + + } + +} + +func (exch *Exchange) readQueryForm(dst *httpraw.Form) (n int, err error) { + query := exch.RequestQuery() + if len(query) == 0 { + return 0, nil + } else if dst.Len() > 0 { + err = dst.ReadFromBytes([]byte{'&'}) // Add separator. + if err != nil { + return 0, err + } + } + err = dst.ReadFromBytes(query) + if err != nil { + return 0, err + } + return len(query), nil +} + +func (exch *Exchange) readBodyForm(dst *httpraw.Form) (n int, err error) { + cl, _, err := exch.RequestContentLength() + if cl <= 0 { + return 0, nil + } + if dst.Len() > 0 { + err = dst.ReadFromBytes([]byte{'&'}) // Add separator. + if err != nil { + return 0, err + } + } + var rw ExchangeRW + exch.ReadWriter(&rw) + n, err = dst.ReadLimited(&rw, int(cl)) + if err != nil { + return n, err + } + return n, nil +} + // RequestParseForm reads the request body into buf and parses it as // "application/x-www-form-urlencoded" into dst. buf is the only storage used and // the only limit: a body longer than buf is refused with [lneto.ErrBufferFull] diff --git a/http/httpraw/form.go b/http/httpraw/form.go index 314b539..5082a2e 100644 --- a/http/httpraw/form.go +++ b/http/httpraw/form.go @@ -1,6 +1,9 @@ package httpraw -import "bytes" +import ( + "bytes" + "io" +) // Form holds "application/x-www-form-urlencoded" key-value pairs, the encoding // HTML forms use for POST bodies and query strings alike. Methods function @@ -23,6 +26,12 @@ func (f *Form) Reset(buf []byte, capKV int) { f.kv.Reset(buf, capKV) } +// ReadFromBytes appends buf to the underlying buffer, accumulating data to parse. Returns ErrBufferExhausted when buf does not fit and growth is disabled. +func (f *Form) ReadFromBytes(b []byte) error { return f.kv.ReadFromBytes(b) } + +// ReadLimited appends at most limit bytes read from r to the underlying buffer. A read returning data alongside io.EOF reports a nil error, later ones io.EOF. +func (f *Form) ReadLimited(r io.Reader, limit int) (int, error) { return f.kv.ReadLimited(r, limit) } + // ParseBytes copies the argument bytes to the Form's underlying buffer and parses them. func (f *Form) ParseBytes(b []byte) error { f.Reset(nil, 0)