(sigil http request)
(sigil http request) - HTTP Request Types and Parsing
Provides the <http-request> record and functions for parsing HTTP/1.1 requests from sockets.
Exports
http-requestprocedureHTTP Request Record Uses define-struct for immutability and functional updates via inherit
http-request?procedureTest if a value is a http-request struct.
http-request-methodprocedureGet the method field of a http-request struct.
http-request-pathprocedureGet the path field of a http-request struct.
http-request-queryprocedureGet the query field of a http-request struct.
http-request-versionprocedureGet the version field of a http-request struct.
http-request-headersprocedureGet the headers field of a http-request struct.
http-request-bodyprocedureGet the body field of a http-request struct.
http-request-contextprocedureGet the context field of a http-request struct.
http-request-headerprocedureLook up a header value by name (case-insensitive).
Returns the header value as a string, or #f if not present.
(http-request-header req "Content-Type") ; => "text/html"
(http-request-header req "X-Custom") ; => #fhttp-request-uriprocedureGet the full URI (path + query string).
(http-request-uri req) ; => "/users?page=2"http-request-content-lengthprocedureGet Content-Length as an integer, or #f if not present.
http-request-content-typeprocedureGet Content-Type header value, or #f if not present.
http-request-context-refprocedureGet a value from the request context dict.
The key should be a keyword. Returns #f if not found and no default given.
(http-request-context-ref req user-id:) ; => 42
(http-request-context-ref req missing: "none") ; => "none"http-request-with-contextprocedureCreate a new request with an added context entry (functional update).
(http-request-with-context req user-id: 42)parse-methodprocedureParse HTTP method string to symbol
parse-request-lineprocedureParse an HTTP request line like "GET /path?query HTTP/1.1".
Returns a list (method path query version) or #f on error.
parse-headersprocedureParse headers from list of lines Returns dict with lowercase keyword keys
read-line-from-socketprocedureRead a line from socket (up to CRLF or LF) Returns line without line ending, or #f on error, or 'eof
read-http-requestprocedureRead an HTTP request from a socket.
Takes a socket, a line-reading function, and a byte-reading function. Returns an http-request record, or #f on error.
url-encode-valueprocedurePercent-encode a string for use in URL query values.
RFC 3986 unreserved characters (A-Z, a-z, 0-9, -, _, ., ~) are passed through unchanged. Spaces become +. All other characters are encoded as UTF-8 bytes with %XX sequences.
(url-encode-value "hello world") ; => "hello+world"
(url-encode-value "a&b=c") ; => "a%26b%3Dc"
(url-encode-value "café") ; => "caf%C3%A9"build-query-stringprocedureBuild a URL query string from an alist of key-value pairs.
Keys are strings, values are strings or #f. Pairs with #f values are omitted. Returns a string starting with ?, or an empty string if no pairs remain after filtering.
(build-query-string '(("q" . "hello world") ("page" . "1")))
; => "?q=hello+world&page=1"
(build-query-string '(("q" . "test") ("lang" . #f)))
; => "?q=test"
(build-query-string '())
; => ""build-repeated-paramsprocedureBuild repeated query parameters for APIs that accept multiple values for the same key (e.g., Twitch: id=1&id=2).
(build-repeated-params "id" '("123" "456"))
; => "id=123&id=456"ensure-listprocedureNormalize a value to a list. If the value is a string, wrap it in a single-element list; otherwise return it as-is.
(ensure-list "hello") ; => ("hello")
(ensure-list '("a" "b")) ; => ("a" "b")hex-char-valueprocedureDecode a single hex character to its numeric value
url-decodeprocedureDecode a URL-encoded (percent-encoded) string.
Handles %XX sequences and + for spaces.
(url-decode "hello%20world") ; => "hello world"
(url-decode "a+b") ; => "a b"parse-form-urlencodedprocedureParse URL-encoded form data (application/x-www-form-urlencoded).
Returns an alist with symbol keys.
(parse-form-urlencoded "name=Alice&age=30")
; => ((name . "Alice") (age . "30"))extract-multipart-boundaryprocedureExtract boundary from a Content-Type header.
Takes a Content-Type string like "multipart/form-data; boundary=----WebKitFormBoundary...". Returns the boundary string, or #f if not found.
parse-multipart-form-dataprocedureParse multipart/form-data body.
Takes the request body and boundary string. Returns alist with symbol keys, like parse-form-urlencoded. For file uploads, the value is a dict with filename:, content-type:, content:.
Example:
(let* ((boundary (extract-multipart-boundary (http-request-content-type req)))
(params (parse-multipart-form-data (http-request-body req) boundary)))
(assoc-ref 'name params))parse-form-dataprocedureParse form data from request, auto-detecting format.
Handles both application/x-www-form-urlencoded and multipart/form-data. Returns alist with symbol keys.
Example:
(let ((params (parse-form-data req)))
(assoc-ref 'username params))