diagram out interesting approach to form parsing for clanker

This commit is contained in:
Patricio Whittingslow
2026-07-30 00:17:16 -03:00
parent be56c82b2c
commit 1985688076
2 changed files with 66 additions and 1 deletions
+56
View File
@@ -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]
+10 -1
View File
@@ -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)