http.forms

index · http

Overview

Form body building and parsing utilities: URL encoding, HTML escaping, application/x-www-form-urlencoded and multipart/form-data handling. No networking dependencies.

Functions

NameSignature
url_escapeurl_escape(str) -> encoded
html_unescapehtml_unescape(str) -> decoded
html_escapehtml_escape(str) -> escaped
make_form_datamake_form_data(items) -> content_type, body
parse_argsparse_args(body) -> args
parse_form_dataparse_form_data(boundary, body) -> args

url_escape(str) -> encoded

URL-encode a string for safe use in query parameters

Encodes str using application/x-www-form-urlencoded rules:

html_unescape(str) -> decoded

Decode HTML entities back to their original characters

Handles three entity forms:

Codepoints above 255 are decoded to UTF-8 via std.utf.char.

One pass decodes each entity once: &amp;lt; gives &lt;, not <. Any other named entity is left as it is.

html_escape(str) -> escaped

Escape a string for safe embedding in HTML text or a quoted attribute

Replaces the five HTML specials: & with &amp;, < with &lt;, > with &gt;, " with &quot; and ' with &#39;.

One pass escapes each character once, so an entity in the input is escaped as text: &amp; gives &amp;amp;. It is not an HTML sanitizer.

make_form_data(items) -> content_type, body

Build a multipart/form-data body from a list of items

Each item in the list is a table with the following fields:

parse_args(body) -> args

Parse a URL-encoded form body into a key-value table

Parses an application/x-www-form-urlencoded body. + signs in values are restored to spaces before URL-decoding. Values come back raw: the caller escapes one at output, with html_escape for HTML. Returns an empty table for non-string or empty input. Key-value pairs missing the = separator are silently skipped.

parse_form_data(boundary, body) -> args

Parse a multipart/form-data body into a key-value table

Parses a multipart/form-data body using the given boundary string, as the request's Content-Type carries it, unquoted. The boundary is matched as plain text. Each part's headers are read by name, in any case and in any order, up to the first blank line.

A text field comes back as its bytes as sent: no decoding, no escaping. The caller escapes one at output. A part with a non-empty filename comes back as a table with filename, content, and content_type, the part's Content-Type as sent, or nil when the part has none. An empty filename, which a browser sends for an empty file input, makes a text field. A part with no name is skipped, and a later part replaces an earlier one of the same name.