No description
  • Scheme 75%
  • Shell 17.4%
  • Rust 4.5%
  • Makefile 3%
  • Common Lisp 0.1%
Find a file
2026-07-30 15:46:43 -06:00
.builds ci: set umask 022 in package/verify tasks too (jerbuild creates group-writable cache dirs during pkg operations) 2026-07-22 13:10:56 -06:00
.jerboa Resolve security audit findings 2026-07-11 17:22:32 -06:00
docs Resolve security audit findings 2026-07-11 17:22:32 -06:00
fuzz Security hardening and release readiness 2026-06-23 10:50:01 -06:00
lib/jerboa-https/sandbox build: remove tracked generated .sls files and ignore them 2026-07-24 11:43:54 -06:00
scripts Resolve security audit findings 2026-07-11 17:22:32 -06:00
src perf: httpd writer-flush writes live sub-range without copying 2026-07-22 16:00:13 -06:00
support Resolve security audit findings 2026-07-11 17:22:32 -06:00
tests test: httpd multi-flush partial-buffer sub-range write coverage 2026-07-22 16:36:14 -06:00
wasm Security hardening and release readiness 2026-06-23 10:50:01 -06:00
.gitignore build: remove tracked generated .sls files and ignore them 2026-07-24 11:43:54 -06:00
AGENTS.md docs: remove jerboa-emacs restriction 2026-07-30 15:46:43 -06:00
chez-https.md Resolve security audit findings 2026-07-11 17:22:32 -06:00
dependencies.lock perf: httpd writer-flush writes live sub-range without copying 2026-07-22 16:00:13 -06:00
jpkg.sexp Add jpkg packaging 2026-07-21 15:09:24 -06:00
LICENSE Switch to MIT license 2026-07-21 13:42:17 -06:00
Makefile security: pin WASM HTTP parser module SHA-256 (fail closed) 2026-07-22 15:35:28 -06:00
README.md Resolve security audit findings 2026-07-11 17:22:32 -06:00
SECURITY.md Resolve security audit findings 2026-07-11 17:22:32 -06:00

chez-https

Native HTTP/1.1 client over TLS for Chez Scheme. No subprocesses. No curl. Pure in-process HTTPS.

Dependencies

  • jerboa-ssl — TLS transport layer, locked by commit and tree in dependencies.lock
  • Chez Scheme 10.x
  • OpenSSL (libssl, libcrypto)

Installation

# From this checkout, fetch the reviewed dependency revision.
support/locked-dependency.sh fetch dependencies.lock jerboa-ssl ~/mine/jerboa-ssl
make

CI uses the same lock verifier. Updating jerboa-ssl requires a reviewed commit and tree-hash change in dependencies.lock; default branches are never consumed by the build.

Usage

(import (chez-https))

;; Simple GET
(let ([req (http-get "https://example.com/")])
  (display (request-status req))    ;; 200
  (display (request-text req))      ;; HTML body as string
  (request-close req))

;; With headers and query parameters (S3-compatible format)
(let ([headers (list (list "Authorization" ':: "AWS4-HMAC-SHA256 ...")
                     '::
                     (list "Host" ':: "bucket.s3.amazonaws.com")
                     (list "x-amz-date" ':: "20260306T120000Z"))]
      [params  (list (list "list-type" ':: "2")
                     (list "prefix" ':: "AWSLogs/"))])
  (let ([req (http-get url 'headers: headers 'params: params)])
    (display (request-status req))
    (request-close req)))

;; PUT with body
(let ([req (http-put url
             'headers: headers
             'params: #f
             'data: (string->utf8 "request body"))])
  (display (request-status req))
  (request-close req))

API

HTTP Methods

(http-get    url ['headers: hdrs] ['params: params])
(http-post   url ['headers: hdrs] ['params: params] ['data: body])
(http-put    url ['headers: hdrs] ['params: params] ['data: body])
(http-delete url ['headers: hdrs] ['params: params])
(http-head   url ['headers: hdrs] ['params: params])

Response Accessors

Function Returns Description
(request-status req) integer HTTP status code (200, 404, etc.)
(request-text req) string Response body as UTF-8 string
(request-content req) bytevector Response body as raw bytes
(request-headers req) alist Response headers (lowercase keys)
(request-header req name) string or #f Single header value lookup
(request-close req) void No-op (connection already closed)

Utilities

Function Description
(parse-url url) Returns (values host port path)
(url-encode str) RFC 3986 percent-encoding
(flatten-request-headers hdrs) Flatten (name :: value) format to alist
(build-query-string params) Build URL query string from params

Response policy

(http-client-config) returns the active bounded response policy. Set startup limits with options such as max-header-bytes:, max-headers:, max-body:, max-chunk:, max-chunked-wire:, idle-timeout:, and total-timeout:. Values must be positive exact integers. Configure the policy before issuing concurrent requests.

Features

  • HTTPS via OpenSSL (TLS 1.2/1.3)
  • SNI and hostname verification
  • Streaming, bounded chunked transfer decoding
  • Strict duplicate/conflicting response-framing rejection
  • Header, decoded-body, raw-chunked-body, chunk-size, idle, and total limits
  • RFC-token/control-character validation before request serialization
  • 100 Continue handling
  • Binary response body preservation (critical for gzip/binary downloads)
  • Configurable HTTPD worker count, listen backlog, queue capacity, request timeout, response timeout, header count, and body size limits
  • Bounded TLS handshake workers, queue, short handshake deadline, and global/per-IP pre-authentication limits
  • Descriptor-pinned static-file serving with canonical containment and inode identity verification
  • S3-compatible header format (:: separator convention)
  • URL encoding (RFC 3986)
  • Automatic SSL initialization

Testing

make test

The tests include a local self-signed TLS peer for hostile response framing and deadline cases. Interpreter-based development explicitly opts into loading jerboa-ssl from its canonical absolute directory; production binaries should statically register the TLS shim.

Release Evidence

The HTTPD surface is private until the daemon release gate is complete. Run:

make release-evidence

The release bundle includes SBOM, reproducibility, TLS dependency, HTTPD fuzz-evidence, and HTTPD soak status under dist/release-evidence/. Default fuzz evidence records fixed adversarial cases, a 2048-case generated deterministic HTTPD corpus, and a present cargo-fuzz harness for the sandboxed HTTP parser. Run with JHTTPS_RUN_COVERAGE_FUZZ=1 to record bounded local coverage evidence; production release still requires longer release-host fuzz evidence or a signed exception. Default local soak evidence records load and queue-exhaustion soak as blocked/not-run. Opt-in local soak evidence records deterministic slow-client coverage plus bounded load/queue smokes, but production release still requires target-host sustained load evidence. HTTPD TLS/proxy policy is documented in docs/tls-proxy-policy.md and copied into dist/release-evidence/tls-proxy-policy.txt.

Architecture

chez-https (this library)
    │
    └── jerboa-ssl (TLS transport)
            │
            └── OpenSSL (libssl, libcrypto)

chez-https is Scheme on top of chez-ssl for I/O. The HTTPD parser boundary uses a small Rust/WASM sandbox for request lines, header lines, and chunk sizes when the Jerboa WASM sandbox is available; JHTTPS_REQUIRE_WASM_HTTP=1 makes that boundary fail closed for production deployments.