Expand description
§form_net
Parses what a browser sends when a form is submitted:
application/x-www-form-urlencoded fields and multipart/form-data
uploads. It does no I/O: feed it bytes, get fields and parts.
Every budget (field count, name and value length, part count, part
header size, file count and size, total size) is checked before the bytes
it governs are buffered. Input that two parsers could read differently is
refused with a precise error, never repaired. No error, Debug, or
Display output ever contains a field value or a file name.
§Tier 1
// A urlencoded body
let form = form_net::parse_urlencoded(b"email=a%40b.example&remember=on")?;
assert_eq!(form.get("email"), Some("a@b.example"));
// A query string
let query = form_net::parse_query(b"?q=rust+forms&page=2")?;
assert_eq!(query.get("q"), Some("rust forms"));
// Building one
assert_eq!(form_net::serialize_urlencoded([("q", "rust forms")]), "q=rust+forms");
// A buffered multipart body
let body = b"--X\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\nHoliday\r\n--X--";
let mp = form_net::parse_multipart(b"multipart/form-data; boundary=X", body)?;
assert_eq!(mp.field("title"), Some("Holiday"));A typed form, from either encoding:
use form_net::FromForm;
form_net::form! {
pub struct Login {
pub email: String,
pub password: form_net::Secret,
pub remember: bool,
}
ignore = ["csrf_token"];
}
let body = b"email=a%40b.example&password=pw&remember=on&csrf_token=t";
let login = Login::from_body(b"application/x-www-form-urlencoded", body)?;
assert_eq!((login.email.as_str(), login.remember), ("a@b.example", true));An upload read from any std::io::Read, large files spilled to private
temporary files that are deleted on drop (feature fs):
let body = b"--X\r\nContent-Disposition: form-data; name=doc; filename=a.txt\r\n\r\nhello\r\n--X--";
let upload = form_net::read_multipart(b"multipart/form-data; boundary=X", &body[..])?;
assert_eq!(upload.file("doc").map(|f| f.len()), Some(5));§Tiers 2 and 3
Explicit Limits and Policy per route (parse_urlencoded_with,
parse_multipart_with); an Inspector that sees every part head, the
first bytes of every file, and every field before anything is stored;
a Sink that decides where file bytes go, driven by the Driver; the
allocation-free core (raw_pairs, decode_into, encode_into,
Boundary, MultipartParser), which builds without alloc.
§Features
| Feature | Default | Adds |
|---|---|---|
| (none) | the allocation-free core; no_std without alloc | |
alloc | owned results, the Tier 1 functions, form!, Driver, MemorySink | |
std | yes | MultipartReader, FormError::Io, FormError::Random; implies alloc |
random | the OS random source; implies std | |
fs | Store, StoredFile, Upload, UploadSession, read_multipart, FileName::sanitized; implies random |
The full contract is docs/API.md in the
repository. This release
(0.4) adds upload storage, inspection hooks, blocking readers, and typed
extraction to the 0.3 core; the multipart writer, the shared disk budget,
and sweep arrive in 0.5.
Macros§
Structs§
- Boundary
- A validated boundary with its delimiter (
CRLF "--" boundary, 5 to 74 bytes) and the failure table of the streaming matcher, built once. - Content
Type - A part’s declared
Content-Type, already checked. A hint: the client chose it. - Discard
Sink - A sink that discards file data and reports how many bytes it saw.
- Driver
alloc - The one streaming implementation of the hook order: parser, inspector, sink, the text buffer, the sniff window, and the empty-file delay.
- File
Data alloc - An owned file: its bytes, and the file name and content type the client
sent, when they are text. The output of
MemorySinkand a field type for typed extraction from buffered bodies. - File
Name - The client’s file name, with a view for each way a caller might want it.
- Form
alloc - The owned result of a urlencoded parse: every field, in input order, duplicates kept.
- Headers
- Every header line of a part, in order, as raw
(name, value)bytes with the value trimmed. - Limits
- Every budget form-net enforces.
- Location
- Where an error was found.
- Memory
Sink alloc - A sink that keeps each file in memory as a
FileData. - Multipart
alloc - The parts of a buffered multipart body, in body order.
- Multipart
Parser - The sans-IO
multipart/form-dataparser. - Multipart
Reader std - Reads a multipart body from a blocking reader, one part at a time.
- NoInspector
- An inspector that accepts everything; it compiles to nothing.
- Owned
Part Head alloc - An owned copy of a
PartHead. Its buffer is reused for the next head copied into it, so a driver that keeps one never allocates per part once the buffer has grown to the largest head. - Pairs
alloc - The iterator returned by
pairs. - Part
alloc - One part of a buffered multipart body. Its data borrows the body.
- Part
Head - The validated header block of one part, borrowed.
- Part
Reader std - One part of a
MultipartReader: read it like a file. - Part
Summary - What one part was.
- Policy
- The behaviours a route may choose. The defaults are the strict ones; every alternative is named after what it allows.
- RawPair
- One
name=valuesequence, undecoded. - RawPairs
- The iterator returned by
raw_pairs. - Refusal
- Why an inspector refused the input: the HTTP status it wants and a stable, machine-readable code for the reason.
- Secret
alloc - A text field that holds a secret (a password, a token).
- Serializer
alloc - Appends urlencoded pairs to an existing string, for example a URL that
already ends in
?. The first pair is not preceded by&; whatever the string held before is left untouched. - Step
- One step of the parser: how many input bytes it consumed, and what happened.
- Store
fs - Where uploads are kept.
Send + Sync; create one per process or per route and share it by reference. - Store
Sink fs - The
SinkaStorehands out for one request. - Store
Stats fs - A snapshot of what a store holds, read from atomic counters.
- Stored
File fs - One received file, in memory or in a temporary file.
- Stored
Reader fs - A reader over a
StoredFile;Read + Seekwith its own position. - Token
Field - The anti-forgery token field to capture from a multipart body.
- Upload
fs - The result of a completed multipart parse with storage: text fields, owned and wiped on drop, and files.
- Upload
Session fs - The push-style form for event-driven servers: hand each body chunk to
pushas reads complete, thenfinish.
Enums§
- Charset
- The
charseta part declared. - Empty
File Policy - A file input left empty (
filename=""and no data). - Encoding
Error - Bytes that do not decode.
- Event
- What the parser found.
- Extended
Filename Policy - What a
filename*parameter (RFC 8187) in a part means. Browsers never send it; RFC 7578 forbids senders from using it. - Extract
Error - Why typed extraction failed.
- File
Name Source - Where a file name came from.
- File
Value alloc - A file field’s value.
- Form
Error - Everything that can go wrong in form-net.
- Form
Kind - Which form encoding a request body uses.
- Header
Policy - Part headers other than
Content-Disposition,Content-Type, andContent-Transfer-Encoding. - Limit
- Which budget of
Limitswas exceeded. - Part
Kind - Whether a part is a text field or a file.
- Percent
Policy - What a
%not followed by two hex digits means in urlencoded input. - Policy
Refusal - Well-formed input that a
Policyrefuses. - Progress
alloc - What completed during a
Driver::push.Debugshows a field’s name and value length, never the value. - Spill
Mode fs - How spilled files are kept.
- Store
Error fs - What went wrong with storage.
- Syntax
Error - What part of the grammar the input broke.
- Token
Placement - Where the token field must be.
- Value
Error alloc - Why one field’s value did not convert.
form!turns it intoFormError::Extractwith the field’s name. - Verdict
- What an inspector says about what it saw.
Constants§
- MAX_
BOUNDARY_ LEN - The longest boundary RFC 2046 allows.
- MAX_
DELIMITER_ LEN - The longest delimiter: CRLF,
--, and a 70-byte boundary. - VERSION
- Crate version string, populated by Cargo at build time.
Traits§
- Form
Builder alloc - What
form!generates, and what a hand-writtenFromFormimplementation provides. Reports problems asFormError::Extract { reason, field }. - From
Field alloc - How one field type takes its values.
- From
Form alloc - A struct that can be read from a form. Implemented by
form!; every method is provided. - Inspector
- Takes part in a parse: called for every part head, the first bytes of every file, every data chunk, every complete text field, every part end, the end of the body, and once on any failure.
- Sink
- Where file parts go: one part at a time,
open, any number ofwrite, thencloseorabort.
Functions§
- decode_
into - Decodes one urlencoded component (a name or a value) into
out. - encode_
into - Encodes one component (a name or a value) without allocating: every
byte outside ASCII alphanumerics and
*-._is percent-encoded with uppercase hex, and space is written as+. Runs of bytes that need no escape are written with onewrite_str. - pairs
alloc - Iterates the fields of a urlencoded body lazily, with the default
limits. A name or value that needs no decoding is borrowed from the
input; others are decoded into a new
String(which belongs to the caller and is not wiped: useFormfor secret fields). After the first error the iterator returnsNone. - parse_
multipart alloc - Parses a buffered
multipart/form-databody with the default limits and policy. Part data borrows the body (zero copy); a name borrows too, except where an HTML escape had to be decoded. - parse_
multipart_ inspected alloc - As
parse_multipart_with, with an inspector called in the order theInspectordocumentation guarantees. For a buffered body the sniff window is a slice of the body, not a copy. A part the inspector skips is left out of the result. - parse_
multipart_ with alloc - As
parse_multipartwith explicit limits and policy.limits.validate()runs first. The token rule ofPolicy::token_fieldapplies; the captured token is the value of the text field with that name. - parse_
query alloc - As
parse_urlencoded, after stripping exactly one leading?if there is one. - parse_
urlencoded alloc - Parses a whole
application/x-www-form-urlencodedbody with the default limits and policy, and returns the fields, owned, in input order. - parse_
urlencoded_ inspected alloc - As
parse_urlencoded_with, callinginspector.field(name, value)for every pair in input order (decoded value bytes), theninspector.end(). On any error, including a refusal,inspector.failed(&error)is called once before the error is returned. AVerdict::Skipfromfielddrops that pair. Inspection never runs on a body form-net refuses. - parse_
urlencoded_ with alloc - As
parse_urlencodedwith explicit limits and policy.limits.validate()runs first. Of the policy, onlypercentapplies to urlencoded bodies. - raw_
pairs - Iterates the pairs of a urlencoded body without allocating or copying.
- read_
multipart fs - The blocking convenience: reads
bodyto the end in 64 KiB chunks with the default limits and policy, keeps files up to 64 KiB in memory, and spills larger ones to anonymous temporary files in a private directory that is created only when a file first spills and removed when the last file from it is dropped. There is no process-wide state. - serialize_
urlencoded alloc - Builds a urlencoded body or query from pairs, byte-identical to the
WHATWG serializer for UTF-8: names and values are encoded as
encode_intodoes, joined with=, and pairs are joined with&. Infallible: everystris valid input.