From bcaa35dd2cdc9005f5917185a9a47551db0bd076 Mon Sep 17 00:00:00 2001 From: Automatic website updater <> Date: Tue, 14 Apr 2026 10:09:06 +0100 Subject: [PATCH] Automatic website update --- index.html | 1660 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1654 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 4c8e568..093193f 100644 --- a/index.html +++ b/index.html @@ -45,7 +45,7 @@ ul.no-bullet {list-style: none}
-Safsaf +
@@ -89,6 +89,64 @@ server. +
  • 2.2 (safsaf handler-wrappers cors) +
  • +
  • 2.3 (safsaf handler-wrappers csrf) +
  • +
  • 2.4 (safsaf handler-wrappers exceptions) +
  • +
  • 2.5 (safsaf handler-wrappers logging) +
  • +
  • 2.6 (safsaf handler-wrappers max-body-size) +
  • +
  • 2.7 (safsaf handler-wrappers security-headers) +
  • +
  • 2.8 (safsaf handler-wrappers sessions) +
  • +
  • 2.9 (safsaf handler-wrappers trailing-slash) +
  • +
  • 2.10 (safsaf params) +
  • +
  • 2.11 (safsaf response-helpers) +
  • +
  • 2.12 (safsaf router) +
  • +
  • 2.13 (safsaf templating) +
  • +
  • 2.14 (safsaf utils) +
  • Appendix A Version History
  • Appendix B Copying Information
  • @@ -600,12 +658,25 @@ Next: , P

    -Up: API   [Contents][Index]

    +Next: , Up: API   [Contents][Index]

    2.1 (safsaf)

    @@ -621,7 +692,7 @@ Up: API   [ -
    Procedure: default-method-not-allowed-handler a b
    +
    Procedure: default-method-not-allowed-handler request allowed-methods

    Return a 405 Method Not Allowed response with an Allow header listing ALLOWED-METHODS.

    @@ -631,7 +702,7 @@ ALLOWED-METHODS.
    -
    Procedure: run-safsaf _ KEY: #:host #:port #:method-not-allowed? #:method-not-allowed-handler #:connection-buffer-size
    +
    Procedure: run-safsaf routes KEY: #:host #:port #:method-not-allowed? #:method-not-allowed-handler #:connection-buffer-size

    Start a Safsaf web server.

    ROUTES is a list of routes and route-groups (as returned by component @@ -660,6 +731,1380 @@ returns immediately — the caller manages the lifecycle. +


    +
    + +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.2 (safsaf handler-wrappers cors)

    + + + + + + +
    +

    2.2.1 Procedures

    + + +
    +
    Procedure: cors-handler-wrapper handler KEY: #:origins #:methods #:headers #:max-age #:allow-credentials? #:expose-headers
    +

    Handler wrapper that adds CORS (Cross-Origin Resource Sharing) headers +to responses. +

    +

    Browsers enforce the Same-Origin Policy: scripts on one origin (scheme + +host + port) cannot read responses from a different origin. CORS +relaxes this by letting the server declare which origins, methods, and +headers are permitted. +

    +

    For “simple” requests the browser sends the request and checks the +response headers. For non-simple requests (e.g. PUT/DELETE, custom +headers, or JSON Content-Type) the browser sends a preflight OPTIONS +request first. This wrapper handles both cases. +

    +

    ORIGINS is a list of allowed origin strings, or ’("*") for any. METHODS +is a list of allowed method symbols. HEADERS is a list of allowed +request header name strings. MAX-AGE is the preflight cache duration in +seconds. ALLOW-CREDENTIALS? controls whether credentials (cookies, +auth) are allowed cross-origin. Note: cannot be #t when origins is +’("*"). EXPOSE-HEADERS is a list of response header name strings the +browser may read from JavaScript. +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.3 (safsaf handler-wrappers csrf)

    + + + + + + +
    +

    2.3.1 Parameters

    + + +
    +
    Parameter: current-csrf-token
    +

    Default value: +

    +
    #f
    +
    +
    + + + + + +
    +
    +

    2.3.2 Procedures

    + + +
    +
    Procedure: csrf-handler-wrapper handler KEY: #:cookie-name
    +

    CSRF token handler wrapper. +

    +

    Ensures a CSRF token cookie is present on every response (generates one +if the request has none). The token is bound to current-csrf-token so +handlers and templates can read it via (current-csrf-token). +

    +

    Token validation is NOT done here — it belongs in the form processing +layer. Use parse-form-params from (safsaf params), which automatically +checks the submitted token against the cookie token. +

    +
    + + + + +
    +
    Procedure: csrf-token-field
    +

    Return an SXML hidden input element for the CSRF token. Use in forms: +(csrf-token-field)(input (@ (type "hidden") +...)). +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.4 (safsaf handler-wrappers exceptions)

    + + + + + + +
    +

    2.4.1 Procedures

    + + +
    +
    Procedure: default-render-error render-html render-json
    +

    Return a render-error procedure that content-negotiates between +RENDER-HTML and RENDER-JSON based on the request’s Accept header. +

    +
    + + + + +
    +
    Procedure: default-render-html request code message backtrace-string dev?
    +

    Default HTML error renderer. In dev mode, shows a rich backtrace page. +In production, returns a minimal HTML page. +

    +
    + + + + +
    +
    Procedure: default-render-json _request code message backtrace-string dev?
    +

    Default JSON error renderer. In dev mode, includes the backtrace. In +production, returns only the error message. +

    +
    + + + + +
    +
    Procedure: exceptions-handler-wrapper handler KEY: #:dev? #:logger #:render-html #:render-json #:render-error
    +

    Handler wrapper that catches exceptions from HANDLER and returns an +error response. +

    +

    The response format is content-negotiated from the request’s Accept +header, choosing between HTML and JSON. +

    +

    When LOGGER is provided, exceptions are logged through it. Otherwise, +the backtrace is written to the current error port. In dev mode (DEV? +is #t), the response includes the backtrace and exception details. In +production mode, a generic error is returned. +

    +

    Rendering can be customised at three levels: +

    +

    #:render-error — full override. A procedure (request code message +backtrace-string dev?) -> (values response body) that bypasses content +negotiation entirely. +

    +

    #:render-html — custom HTML rendering. A procedure with the same +signature, called when content negotiation selects HTML. +

    +

    #:render-json — custom JSON rendering. A procedure with the same +signature, called when content negotiation selects JSON. +

    +

    The default RENDER-ERROR content-negotiates between RENDER-HTML and +RENDER-JSON. Providing #:render-html or #:render-json replaces just +that format; providing #:render-error replaces the entire rendering. +

    +
    + + + + +
    +
    Procedure: make-exceptions-handler-wrapper KEY: #:dev? #:logger #:render-html #:render-json #:render-error
    +

    Return a handler wrapper that catches exceptions and returns an error +response. See exceptions-handler-wrapper for details. +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.5 (safsaf handler-wrappers logging)

    + + + + + + +
    +

    2.5.1 Procedures

    + + +
    +
    Procedure: logging-handler-wrapper handler KEY: #:logger #:level
    +

    Handler wrapper that logs each request and response. +

    +

    Logs at LEVEL (default ’INFO) with method, path, status code, and +duration in milliseconds. If LOGGER is given, logs to that logger; +otherwise uses the default logger set via set-default-logger!. +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.6 (safsaf handler-wrappers max-body-size)

    + + + + + + +
    +

    2.6.1 Procedures

    + + +
    +
    Procedure: make-max-body-size-handler-wrapper max-bytes KEY: #:handler-413
    +

    Return a handler wrapper that rejects requests whose Content-Length +exceeds MAX-BYTES with a 413 Payload Too Large response. +

    +

    HANDLER-413 is a handler (request body-port) -> (values response body) +called when the limit is exceeded; the default returns plain text. +

    +

    Note: this checks the Content-Length header only. Chunked transfers +without Content-Length are not limited by this wrapper. +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.7 (safsaf handler-wrappers security-headers)

    + + + + + + +
    +

    2.7.1 Procedures

    + + +
    +
    Procedure: security-headers-handler-wrapper handler KEY: #:content-type-options #:frame-options #:strict-transport-security #:referrer-policy #:cross-origin-opener-policy #:permissions-policy #:content-security-policy #:content-security-policy-report-only
    +

    Handler wrapper that adds security headers to every response. +

    +

    All headers are optional and configurable. Pass #f to disable a header. +Defaults: X-Content-Type-Options: nosniff X-Frame-Options: DENY +Referrer-Policy: strict-origin-when-cross-origin +

    +

    Not set by default (enable explicitly): Strict-Transport-Security (e.g. +"max-age=63072000; includeSubDomains") Cross-Origin-Opener-Policy (e.g. +"same-origin") Permissions-Policy (e.g. "camera=(), microphone=()") +Content-Security-Policy (e.g. "default-src ’self’; script-src ’self’") +Content-Security-Policy-Report-Only — same syntax, for testing policies +without enforcing them +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.8 (safsaf handler-wrappers sessions)

    + + + + + + +
    +

    2.8.1 Parameters

    + + +
    +
    Parameter: current-session
    +

    Default value: +

    +
    #f
    +
    +
    + + + + + +
    +
    +

    2.8.2 Procedures

    + + +
    +
    Procedure: make-session-config secret-key KEY: #:cookie-name #:expire-delta #:algorithm
    +

    Create a session manager for use with session-handler-wrapper. +

    +

    SECRET-KEY is the HMAC signing key (a string). EXPIRE-DELTA is (days +hours minutes), default 30 days. ALGORITHM is the HMAC algorithm, +default sha512. +

    +
    + + + + +
    +
    Procedure: make-session-handler-wrapper session-manager
    +

    Return a handler wrapper that binds session data from SESSION-MANAGER. +See session-handler-wrapper for details. +

    +
    + + + + +
    +
    Procedure: session-delete session-manager
    +

    Return a Set-Cookie header that expires the session cookie. Include in +a response headers list: (redirect-response "/" #:headers (list +(session-delete manager))) +

    +
    + + + + +
    +
    Procedure: session-handler-wrapper handler session-manager
    +

    Session handler wrapper using signed cookies via (webutils sessions). +

    +

    Reads the session cookie from the request, verifies the HMAC signature, +and binds current-session for the duration of the handler. If no valid +session cookie is present, current-session is #f. +

    +

    Handlers read session data via: (current-session) → session data or #f +

    +

    To set or delete the session, handlers include the appropriate header in +their response using session-set and session-delete: +

    +

    (redirect-response "/" #:headers (list (session-set manager data))) +(redirect-response "/" #:headers (list (session-delete manager))) +

    +
    + + + + +
    +
    Procedure: session-set session-manager data
    +

    Return a Set-Cookie header that stores signed DATA in the session +cookie. DATA can be any Scheme value that can be written and read back. +Include in a response headers list: (redirect-response "/" #:headers +(list (session-set manager ’((user-id . 42))))) +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.9 (safsaf handler-wrappers trailing-slash)

    + + + + + + +
    +

    2.9.1 Procedures

    + + +
    +
    Procedure: make-trailing-slash-handler-wrapper KEY: #:mode #:code
    +

    Return a handler wrapper that normalizes trailing slashes. +

    +

    MODE is either ’strip (default) or ’append: ’strip — redirect /foo/ to +/foo ’append — redirect /foo to /foo/ +

    +

    The root path / is always left alone. +

    +

    CODE is the HTTP status code for the redirect (default 301). +

    +

    Use with wrap-routes: (wrap-routes routes +(make-trailing-slash-handler-wrapper #:mode ’append)) +

    +
    + + + + +
    +
    Procedure: trailing-slash-handler-wrapper handler KEY: #:mode #:code
    +

    Handler wrapper that normalizes trailing slashes in request paths. +

    +

    MODE is either ’strip (default) or ’append: ’strip — redirect /foo/ to +/foo ’append — redirect /foo to /foo/ +

    +

    The root path / is always left alone. +

    +

    CODE is the HTTP status code for the redirect (default 301). +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.10 (safsaf params)

    + + + + + + +
    +

    2.10.1 Macros

    + + +
    +
    Macro: invalid-param-message x
    +

    Undocumented macro. +

    +
    + + + + +
    +
    Macro: invalid-param-value x
    +

    Undocumented macro. +

    +
    + + + + +
    +
    Macro: invalid-param? x
    +

    Undocumented macro. +

    +
    + + + + +
    +
    Macro: make-invalid-param x
    +

    Undocumented macro. +

    +
    + + + + + +
    +
    +

    2.10.2 Procedures

    + + +
    +
    Procedure: any-invalid-params? parsed-params
    +

    Return #t if any values in PARSED-PARAMS are invalid. +

    +
    + + + + +
    +
    Procedure: as-checkbox s
    +

    Undocumented procedure. +

    +
    + + + + +
    +
    Procedure: as-integer s
    +

    Undocumented procedure. +

    +
    + + + + +
    +
    Procedure: as-matching regex KEY: #:message
    +

    Return a processor that accepts values matching REGEX. +

    +
    + + + + +
    +
    Procedure: as-number s
    +

    Undocumented procedure. +

    +
    + + + + +
    +
    Procedure: as-one-of choices KEY: #:message
    +

    Return a processor that accepts only values in CHOICES (a list of +strings). +

    +
    + + + + +
    +
    Procedure: as-predicate pred KEY: #:message
    +

    Return a processor that accepts values for which PRED returns true. +

    +
    + + + + +
    +
    Procedure: as-string x
    +

    Undocumented procedure. +

    +
    + + + + +
    +
    Procedure: field-errors parsed-params name
    +

    Return a list of error message strings for NAME, or ’(). Convenient for +rendering form fields with per-field errors. +

    +
    + + + + +
    +
    Procedure: guard-against-mutually-exclusive-params parsed-params groups
    +

    Check PARSED-PARAMS for mutually exclusive parameter groups. GROUPS is +a list of lists of symbols, e.g. ’((limit_results all_results)). If +parameters from the same group co-occur, the later ones are replaced +with <invalid-param> records. +

    +
    + + + + +
    +
    Procedure: invalid-param-ref parsed-params name
    +

    Return the <invalid-param> record for NAME, or #f if valid or absent. +

    +
    + + + + +
    +
    Procedure: params->query-string parsed-params
    +

    Serialize PARSED-PARAMS back to a URI query string. Skips invalid +params. Handles multi-value (list) entries. Useful for building +pagination links that preserve current filters. +

    +
    + + + + +
    +
    Procedure: parse-form-params param-specs raw-params KEY: #:csrf-field
    +

    Like parse-params but prepends a CSRF token check. Uses +current-csrf-token from (safsaf handler-wrappers csrf). +

    +
    + + + + +
    +
    Procedure: parse-params param-specs raw-params
    +

    Parse and transform parameters from RAW-PARAMS according to PARAM-SPECS. +

    +

    RAW-PARAMS is an alist of (string . string) pairs, as returned by +parse-query-string or parse-form-body. +

    +

    PARAM-SPECS is a list of specifications. Each spec is a list whose +first element is the parameter name (a symbol), second is a processor +procedure (string -> value | <invalid-param>), and the rest are keyword +options: +

    +

    (name processor) ; optional (name processor #:required) ; must be +present (name processor #:default value) ; fallback (name processor +#:multi-value) ; collect all occurrences (name processor #:multi-value +#:default value) ; multi-value with fallback (name processor +#:no-default-when (fields) #:default value) ; conditional default +

    +

    Returns an alist of (symbol . value) pairs. Values that fail +validation appear as <invalid-param> records inline. Missing optional +params without defaults are omitted. +

    +
    + + + + + +
    +
    +

    2.10.3 Record Types

    + + +
    +
    Record type: <invalid-param>
    +

    This record type has the following fields: +

    +
      +
    • value
    • message
    + +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.11 (safsaf response-helpers)

    + + + + + + +
    +

    2.11.1 Procedures

    + + +
    +
    Procedure: bad-request-response OPT: body KEY: #:headers
    +

    Return a 400 Bad Request response. +

    +
    + + + + +
    +
    Procedure: build-response/inherit response KEY: #:headers
    +

    Build a new response based on RESPONSE, preserving its version, status +code, and reason phrase. HEADERS defaults to the existing headers; +override it to modify them. +

    +

    Use this in handler wrappers that need to adjust headers on an inner +handler’s response without losing any response fields. +

    +
    + + + + +
    +
    Procedure: delete-cookie-header name
    +

    Return a Set-Cookie header pair that expires cookie NAME. Wraps +(webutils cookie) delete-cookie. +

    +
    + + + + +
    +
    Procedure: forbidden-response OPT: body KEY: #:headers
    +

    Return a 403 Forbidden response. +

    +
    + + + + +
    +
    Procedure: html-response shtml KEY: #:code #:headers #:charset
    +

    Return an HTML response by streaming SHTML to the client. SHTML is an +SXML/SHTML tree as accepted by write-shtml-as-html. CHARSET defaults to +"utf-8". +

    +
    + + + + +
    +
    Procedure: internal-server-error-response OPT: body KEY: #:headers
    +

    Return a 500 Internal Server Error response. +

    +
    + + + + +
    +
    Procedure: json-response str KEY: #:code #:headers
    +

    Return a JSON response. STR is the JSON string to send. +

    +
    + + + + +
    +
    Procedure: list->streaming-json-array proc lst port KEY: #:unicode
    +

    Write LST as a JSON array to PORT, applying PROC to each element to +produce a JSON-serializable value. Each element is written individually +via scm->json so the entire array need not be held in memory. +

    +
    + + + + +
    +
    Procedure: make-static-handler root-dir KEY: #:cache-control
    +

    Return a handler that serves static files from ROOT-DIR. +

    +

    The handler expects route params to contain a wildcard capture (the file +path segments). Use with a wildcard route: +

    +

    (route ’GET ’(. path) (make-static-handler "/path/to/public")) +

    +

    Supports If-Modified-Since for 304 responses. CACHE-CONTROL, if given, +is a Cache-Control value in Guile’s header format — an alist, e.g. +’((max-age . 3600)) or ’((no-cache)). +

    +

    Works with /gnu/store paths: files with a very low mtime (as produced by +the store’s timestamp normalization) use the process start time as +Last-Modified instead, so that conditional requests behave sensibly. +

    +
    + + + + +
    +
    Procedure: negotiate-content-type request OPT: supported KEY: #:extensions
    +

    Return the most appropriate MIME type symbol for REQUEST from SUPPORTED. +

    +

    Checks the URL path extension first (.json, .html, .txt) — if present +and the implied type is in SUPPORTED, it wins. Otherwise, walks the +Accept header and returns the first type that appears in SUPPORTED. +Falls back to the first element of SUPPORTED if nothing matches. +

    +

    EXTENSIONS is an alist mapping file extension strings to MIME type +symbols, used for path-based negotiation. Defaults to +%negotiation-extensions. +

    +
    + + + + +
    +
    Procedure: not-found-response OPT: body KEY: #:headers
    +

    Return a 404 Not Found response. +

    +
    + + + + +
    +
    Procedure: payload-too-large-response OPT: body KEY: #:headers
    +

    Return a 413 Payload Too Large response. +

    +
    + + + + +
    +
    Procedure: redirect-response path KEY: #:code #:headers
    +

    Return a redirect response to PATH (a string). +

    +
    + + + + +
    +
    Procedure: scm-alist->streaming-json alist port KEY: #:unicode
    +

    Write ALIST as a JSON object to PORT, streaming each value as it is +produced. If a value in the alist is a procedure, it is called with +PORT so it can write its own JSON representation directly. Otherwise +the value is serialized via scm->json. +

    +
    + + + + +
    +
    Procedure: set-cookie-header name value KEY: #:path #:domain #:max-age #:secure #:http-only #:expires
    +

    Return a Set-Cookie header pair suitable for inclusion in a response +headers alist. Wraps (webutils cookie) set-cookie. +

    +

    Example: (values (build-response #:headers (list (set-cookie-header +"session" token #:path "/" #:http-only #t #:secure #t))) "ok") +

    +
    + + + + +
    +
    Procedure: streaming-json-response thunk KEY: #:code #:headers
    +

    Return a JSON response whose body is written incrementally by THUNK. +THUNK is a procedure of one argument (the output port). Use +scm-alist->streaming-json and list->streaming-json-array inside THUNK to +write JSON without materializing the entire response in memory. +

    +
    + + + + +
    +
    Procedure: text-response str KEY: #:code #:headers
    +

    Return a plain text response. STR is the text string to send. +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.12 (safsaf router)

    + + + + + + +
    +

    2.12.1 Macros

    + + +
    +
    Macro: compiled-route-handler x
    +

    Undocumented macro. +

    +
    + + + + +
    +
    Macro: route-group-children x
    +

    Return the list of child routes and groups of ROUTE-GROUP. +

    +
    + + + + +
    +
    Macro: route-group-name x
    +

    Return the name of ROUTE-GROUP, or #f if unnamed. +

    +
    + + + + +
    +
    Macro: route-group-prefix x
    +

    Return the prefix pattern of ROUTE-GROUP. +

    +
    + + + + +
    +
    Macro: route-group? x
    +

    Return #t if OBJ is a <route-group>. +

    +
    + + + + +
    +
    Macro: route-handler x
    +

    Return the handler procedure of ROUTE. +

    +
    + + + + +
    +
    Macro: route-method x
    +

    Return the HTTP method of ROUTE. +

    +
    + + + + +
    +
    Macro: route-name x
    +

    Return the name of ROUTE, or #f if unnamed. +

    +
    + + + + +
    +
    Macro: route-pattern x
    +

    Return the URL pattern of ROUTE. +

    +
    + + + + +
    +
    Macro: route? x
    +

    Return #t if OBJ is a <route>. +

    +
    + + + + + +
    +
    +

    2.12.2 Parameters

    + + +
    +
    Parameter: current-reverse-routes
    +

    Default value: +

    +
    #f
    +
    +
    + + + + +
    +
    Parameter: current-route-params
    +

    Default value: +

    +
    ()
    +
    +
    + + + + + +
    +
    +

    2.12.3 Procedures

    + + +
    +
    Procedure: compile-routes routes
    +

    Compile a route tree (route, route-group, or list) into two values: 1. +An ordered list of <compiled-route> records ready for matching. 2. A +<reverse-routes> record for use with path-for. +

    +

    The last route must be a catch-all (’* pattern with a rest parameter) so +that every request is handled. +

    +
    + + + + +
    +
    Procedure: find-allowed-methods compiled-routes path-segments
    +

    Scan COMPILED-ROUTES for routes whose path matches PATH-SEGMENTS, +collecting their HTTP methods. The last route (the catch-all) is +excluded. Returns a deduplicated list of method symbols, or ’() if no +route’s path matches. +

    +
    + + + + +
    +
    Procedure: make-route-group prefix KEY: #:name
    +

    Create an empty route group with PREFIX. Children can be added later +with route-group-add-children!. +

    +
    + + + + +
    +
    Procedure: match-route compiled-routes method path-segments
    +

    Find the first matching route for METHOD and PATH-SEGMENTS. Returns +(values handler bindings) on match, or (values #f #f) on no match. +

    +
    + + + + +
    +
    Procedure: path-for group name OPT: params KEY: #:query #:fragment #:relative?
    +

    Generate a URL path for a named route within GROUP. +

    +

    GROUP is a route-group value. NAME is either a symbol naming a route +within GROUP, or a list of symbols for nested lookup where the last +element is the route name and preceding elements are child group names. +

    +

    (path-for routes ’users) (path-for routes ’user ’((id . "42"))) +(path-for routes ’(api items) ’((id . "7"))) +

    +

    PARAMS is an alist mapping capture symbols to string values, or to a +list of strings for rest parameters. +

    +

    Optional keyword arguments: #:query — alist of query parameters ((key . +value) ...) #:fragment — fragment string (without the leading #) +#:relative? — if #t, omit the leading / +

    +
    + + + + +
    +
    Procedure: route method pattern handler KEY: #:name
    +

    Create a route. METHOD is a symbol, list of symbols, or ’* for any. +PATTERN is a list of segments: strings (literal), symbols (capture), +two-element lists (predicate capture: (proc name)), with optional dotted +tail (wildcard capture). HANDLER is a procedure (request body-port) -> +(values response body). NAME is an optional symbol used for reverse +routing with path-for. +

    +
    + + + + +
    +
    Procedure: route-group prefix KEY: #:name . children
    +

    Create a route group. PREFIX is a pattern list (same syntax as route +patterns). CHILDREN is an ordered list of routes and route-groups. NAME +is an optional symbol for nested path-for lookups. +

    +
    + + + + +
    +
    Procedure: route-group-add-children! group new-children
    +

    Append NEW-CHILDREN to GROUP’s child list. +

    +
    + + + + +
    +
    Procedure: wrap-routes routes . wrappers
    +

    Apply WRAPPERS to every handler in ROUTES, which may be a route, +route-group, or list of either. Returns a new structure with wrapped +handlers. When multiple wrappers are given, the first wrapper in the +list wraps outermost (runs first on the request, last on the response). +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Next: , Previous: , Up: API   [Contents][Index]

    +
    +

    2.13 (safsaf templating)

    + + + + + + +
    +

    2.13.1 Procedures

    + + +
    +
    Procedure: streaming-html-response shtml KEY: #:code #:headers #:charset
    +

    Return an HTML response that streams SHTML to the client. +

    +

    SHTML is an SHTML tree that may contain procedures. Each procedure is +called as (proc port) during output and should write HTML to the +port. Static parts are rendered via htmlprag. +

    +
    +
      (streaming-response
    +   `(*TOP*
    +     (*DECL* DOCTYPE html)
    +     (html (head (title "My Page"))
    +           (body (h1 "Hello")
    +                 ,(lambda (port)
    +                    (write-shtml-as-html '(p "dynamic") port))))))
    +
    + +
    + + + + +
    +
    Procedure: write-shtml-as-html/streaming shtml port
    +

    Write SHTML to PORT, like write-shtml-as-html from htmlprag, but +any procedure encountered in the tree is called as (proc port) +and may write directly to PORT. +

    +

    This allows mixing static SHTML with dynamic streaming sections: +

    +
    +
      (write-shtml-as-html/streaming
    +   `(html (body (h1 "Title")
    +                ,(lambda (port) (display "dynamic" port))
    +                (footer "bye")))
    +   port)
    +
    + +

    Static parts are rendered via htmlprag’s shtml->html, then +interleaved with procedure calls at output time. +

    +
    + + + + + + +
    +
    +
    +
    +
    +

    +Previous: , Up: API   [Contents][Index]

    +
    +

    2.14 (safsaf utils)

    + + + + + + +
    +

    2.14.1 Procedures

    + + +
    +
    Procedure: multipart-text-fields parts
    +

    Extract text fields from multipart PARTS as an alist of (name . value). +File upload parts (those with a filename parameter) are excluded. +

    +
    + + + + +
    +
    Procedure: parse-form-body request body-port
    +

    Read and parse a URL-encoded form body from REQUEST. Returns an alist +of string key-value pairs. +

    +
    + + + + +
    +
    Procedure: parse-multipart-body request body-port
    +

    Read and parse a multipart/form-data body from REQUEST. Returns a list +of <part> records from (webutils multipart). Use parts-ref, +parts-ref-string, part-body, etc. to access parts. +

    +
    + + + + +
    +
    Procedure: parse-query-string request
    +

    Parse the query string from REQUEST. Returns an alist of string +key-value pairs, or ’() if no query string. +

    +
    + + + + +
    +
    Procedure: request-cookie-ref request name OPT: default
    +

    Return the value of cookie NAME from REQUEST, or DEFAULT if not found. +

    +
    + + + + +
    +
    Procedure: request-cookies request
    +

    Return the cookies from REQUEST as an alist of (name . value) pairs. +Returns ’() if no Cookie header is present. Importing (webutils cookie) +registers the Cookie header parser with (web http). +

    +
    + + + + + +
    @@ -727,6 +2172,17 @@ Next: , P

    Data Type Index

    +
    Jump to:   < +
    + + + + + + +
    Index Entry  Section

    <
    <invalid-param>: safsaf_params

    +
    Jump to:   < +

    @@ -738,25 +2194,201 @@ Next: , Pre

    Procedure Index

    -
    Jump to:   D +
    Jump to:   A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +J +   +L +   +M +   +N +   +P   R   +S +   +T +   +W +  
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Index Entry  Section

    A
    any-invalid-params?: safsaf_params
    as-checkbox: safsaf_params
    as-integer: safsaf_params
    as-matching: safsaf_params
    as-number: safsaf_params
    as-one-of: safsaf_params
    as-predicate: safsaf_params
    as-string: safsaf_params

    B
    bad-request-response: safsaf_response-helpers
    build-response/inherit: safsaf_response-helpers

    C
    compile-routes: safsaf_router
    compiled-route-handler: safsaf_router
    cors-handler-wrapper: safsaf_handler-wrappers_cors
    csrf-handler-wrapper: safsaf_handler-wrappers_csrf
    csrf-token-field: safsaf_handler-wrappers_csrf

    D
    default-method-not-allowed-handler: safsaf
    default-render-error: safsaf_handler-wrappers_exceptions
    default-render-html: safsaf_handler-wrappers_exceptions
    default-render-json: safsaf_handler-wrappers_exceptions
    delete-cookie-header: safsaf_response-helpers

    E
    exceptions-handler-wrapper: safsaf_handler-wrappers_exceptions

    F
    field-errors: safsaf_params
    find-allowed-methods: safsaf_router
    forbidden-response: safsaf_response-helpers

    G
    guard-against-mutually-exclusive-params: safsaf_params

    H
    html-response: safsaf_response-helpers

    I
    internal-server-error-response: safsaf_response-helpers
    invalid-param-message: safsaf_params
    invalid-param-ref: safsaf_params
    invalid-param-value: safsaf_params
    invalid-param?: safsaf_params

    J
    json-response: safsaf_response-helpers

    L
    list->streaming-json-array: safsaf_response-helpers
    logging-handler-wrapper: safsaf_handler-wrappers_logging

    M
    make-exceptions-handler-wrapper: safsaf_handler-wrappers_exceptions
    make-invalid-param: safsaf_params
    make-max-body-size-handler-wrapper: safsaf_handler-wrappers_max-body-size
    make-route-group: safsaf_router
    make-session-config: safsaf_handler-wrappers_sessions
    make-session-handler-wrapper: safsaf_handler-wrappers_sessions
    make-static-handler: safsaf_response-helpers
    make-trailing-slash-handler-wrapper: safsaf_handler-wrappers_trailing-slash
    match-route: safsaf_router
    multipart-text-fields: safsaf_utils

    N
    negotiate-content-type: safsaf_response-helpers
    not-found-response: safsaf_response-helpers

    P
    params->query-string: safsaf_params
    parse-form-body: safsaf_utils
    parse-form-params: safsaf_params
    parse-multipart-body: safsaf_utils
    parse-params: safsaf_params
    parse-query-string: safsaf_utils
    path-for: safsaf_router
    payload-too-large-response: safsaf_response-helpers

    R
    redirect-response: safsaf_response-helpers
    request-cookie-ref: safsaf_utils
    request-cookies: safsaf_utils
    route: safsaf_router
    route-group: safsaf_router
    route-group-add-children!: safsaf_router
    route-group-children: safsaf_router
    route-group-name: safsaf_router
    route-group-prefix: safsaf_router
    route-group?: safsaf_router
    route-handler: safsaf_router
    route-method: safsaf_router
    route-name: safsaf_router
    route-pattern: safsaf_router
    route?: safsaf_router
    run-safsaf: safsaf

    S
    scm-alist->streaming-json: safsaf_response-helpers
    security-headers-handler-wrapper: safsaf_handler-wrappers_security-headers
    session-delete: safsaf_handler-wrappers_sessions
    session-handler-wrapper: safsaf_handler-wrappers_sessions
    session-set: safsaf_handler-wrappers_sessions
    set-cookie-header: safsaf_response-helpers
    streaming-html-response: safsaf_templating
    streaming-json-response: safsaf_response-helpers

    T
    text-response: safsaf_response-helpers
    trailing-slash-handler-wrapper: safsaf_handler-wrappers_trailing-slash

    W
    wrap-routes: safsaf_router
    write-shtml-as-html/streaming: safsaf_templating

    -
    Jump to:   D +
    Jump to:   A +   +B +   +C +   +D +   +E +   +F +   +G +   +H +   +I +   +J +   +L +   +M +   +N +   +P   R   +S +   +T +   +W +  
    @@ -769,6 +2401,22 @@ Previous:

    Variable Index

    +
    Jump to:   C +   +
    + + + + + + + + + +
    Index Entry  Section

    C
    current-csrf-token: safsaf_handler-wrappers_csrf
    current-reverse-routes: safsaf_router
    current-route-params: safsaf_router
    current-session: safsaf_handler-wrappers_sessions

    +
    Jump to:   C +   +