Under construction

This documentation is still in progress. Some information may be incomplete or out of date. Please check back later.

Docs/Configuration

Running it

Configuration reference

httpjet is configured by a LiteSpeed-compatible XML tree selected with --root: conf/httpd_config.xml, the per-vhost files it references, and conf/mime.properties. An existing LiteSpeed or OpenLiteSpeed tree works as-is. On that base httpjet layers its own opt-in directives — marked httpjet — which LiteSpeed ignores. Operational overrides live on the command line, not in the XML.

The configuration tree

With no --root, httpjet uses /usr/local/lsws. The parser (hj-config) applies LiteSpeed value semantics faithfully:

layout · a server root
/usr/local/lsws/
├── conf/
│   ├── httpd_config.xml          # server, tuning, security, listeners, extProcessors, vhost declarations
│   ├── mime.properties           # mime/type = ext1, ext2   (best-effort)
│   └── vhosts/example.test.xml   # <virtualHostConfig>: docroot, contexts, rewrite, vhssl, cache, logging
└── logs/

Server and tuning

DirectiveDefaultMeaning
serverName$HOSTNAMEServer identity (else localhost).
user / groupnobodyRun-as credentials (the systemd unit usually sets these).
indexFilesindex.htmlDirectory-index candidates (vhost may override).
useIpInProxyHeader2Client-IP trust: 0 never · 1 always · 2 trusted peers only (+ CF-Connecting-IP) · 3 as 2 for IP purposes · 4 always. Restart-required through the write API.
<quic><quicEnable>0HTTP/3 master switch; also drives Alt-Svc. Needs the UDP port published.
<tuning>maxConnections65000Connection cap.
connTimeout / keepAliveTimeout60 / 5 sIdle / keep-alive timeouts.
maxKeepAliveReq1000Requests per keep-alive connection (0 = unlimited).
maxReqURLLen / maxReqHeaderSize8192 / 16380URL and header-block caps.
maxReqBodySize100MServer-wide request-body cap (413); per-context override below.
perIpRate · perIpRateWindowSecs httpjet0 · 1Per-client-IP request throttle (0 = off) and its fixed window. 429 on exceed; fail-open under state pressure.
bandwidthLimit httpjet0Per-connection egress throttle, bytes/s (0 = unlimited). H2 paces per connection; H3 unpaced.
maxCachedFileSize / totalInMemCacheSize4M / 4GSmall-file in-memory promotion threshold and budget (CacheCaps).
maxMMapFileSize / totalMMapCacheSize256K / 2GParsed for compatibility; the mmap file cache was removed.
fileETag28ETag bitmask (INODE|MTIME|SIZE → "size-mtime-inode;;;"); 0 = no ETag.
enable{Gzip,Br,Zstd}Compress (+Dyn)onStatic/dynamic compression per codec; zstdCompressLevel 3, brCompressLevel 5.
<expires>enableExpires, expiresByTypeoffimage/*=A604800, text/css=M86400 (A = access, M = modify). XML only; not honored in .htaccess. Authenticated responses get private, no-store when no explicit policy exists.
<cache>expireInSeconds · privateExpireInSeconds · cacheStatusCode · enablePostCache900 · 0 · 200,301 · offDefault public/private TTLs and cacheable statuses. cacheStorePath is parsed but deliberately unused (see --page-cache-store-path).

Security directives

DirectiveDefaultMeaning
<security><accessControl> allow/deny—ALL or CIDR lists, most-specific wins. A trailing T on an allow rule marks a trusted proxy.
<accessDenyDir><dir>—Globs never served; a malformed glob is a hard start/reload error.
<fileAccessControl>followSymbolLinkoffFolded into each vhost's effective allowSymbolLink; 2 fails closed.
geoipDBFile · geoAllow/geoDeny · asnAllow/asnDeny httpjetnoneOffline CidrList source and label lists; deny-first, allow-only = whitelist, unknown label = build error. →
<suexec>enable · uidMin · gidMin0 · 100 · 100suEXEC master gate and floors; uid/gid 0 always rejected.
<suexec><namespace> enable, mount, pid, net, uts, ipcoffNamespace isolation for PHP workers; pid is accepted but not honored.
<CGIRLimit> CPUSoftLimit/CPUHardLimit—Inherited by phpConfig; other rlimit fields are warned as no-ops.
lsrecaptcha, censorshipControl, permission masks—not enforced — check warns.

Listeners and TLS

DirectiveDefaultMeaning
name, address*:80ip:port / host:port. httpjet also unix:/path or uds:/path for an HTTP-over-Unix-socket listener (TLS over UDS is rejected). Listener names are the stable identity across reloads.
secure, keyFile, certFile, certChainoffTLS material; certChain=1 appends CACertFile to the served chain.
CACertFile · clientVerify · verifyDepthnone · 0 · 1Client-certificate verification (0 none · 1 optional · 2 required · 3 optional without CA) against the listener CA.
crlFile httpjetnonePEM CRL/bundle enforced by the client verifier.
enableStapling0Compatibility only; OCSP needs --features ocsp + --ocsp-responder.
proxyProtocol httpjet0PROXY v2/v1 required on this listener; fail-closed; never on a public bind.
vhostMapList/vhostMap vhost, domain—Host→vhost; domains lowercased; only bare * is a catch-all (*.example.com warns).
httpd_config.xml · a TLS listener with h3
<quic><quicEnable>1</quicEnable></quic>
<listenerList>
  <listener>
    <name>https</name>
    <address>*:443</address>
    <secure>1</secure>
    <keyFile>/etc/letsencrypt/live/example.test/privkey.pem</keyFile>
    <certFile>/etc/letsencrypt/live/example.test/fullchain.pem</certFile>
    <clientVerify>0</clientVerify>
    <vhostMapList><vhostMap><vhost>example.test</vhost><domain>example.test,www.example.test</domain></vhostMap></vhostMapList>
  </listener>
</listenerList>

External processors

An <extProcessor> (server-level <extProcessorList> or per-vhost) is a reverse-proxy upstream (proxy), an LSAPI app (lsapi), or httpjet a FastCGI app (fcgi/fastcgi). <phpConfig> configures the default PHP handler with the same pool knobs. Unknown legacy types (rails, appserver, …) keep proxy behavior; cgi contexts are not executed.

DirectiveDefaultMeaning
name, typerequiredproxy · lsapi · fcgi/fastcgi httpjet.
address (repeatable)requiredip:port, host:port, uds:///path, http://, https://, and httpjet h2:// (prior knowledge) / h2s:// (TLS, ALPN fail-closed). Additional addresses form a group: ordered failover by default, load-balanced with the options below.
loadBalancePolicy httpjetprimary-firstweighted-round-robin · weighted-least-active. Invalid on non-proxy processors.
addressWeights httpjetall 1One integer 1–1000 per address.
<healthCheck> mode · path · host · interval · timeout · rise · fall · expectedStatus httpjetconnect · / · — · 10 · 2 · 2 · 3 · 200Active probes; intervals 1–3600 s, timeout ≤ interval, thresholds 1–100, status 200–599. →
maxConns100Pool cap (LSAPI: worker count source unless --php-children overrides).
initTimeout / retryTimeout / pcKeepAliveTimeout60 / 0 / 60 sConnect timeout / bad-mark cooldown (retry dials fresh; a backend timeout is 504) / idle recycle.
respBuffer0Parsed; responses always stream (check warns if set).
clientCertFile / clientKeyFile httpjetnoneUpstream mTLS client identity for https:///h2s:// targets; must lie within an admin resource root when submitted via the API.
env (repeatable)—K=V worker environment. Server-computed CGI names are protected.
path, backlog, instances, autoStart, runOnStartUp— / 100 / 1 / 0 / 0LSAPI worker binary and supervision (instances>1 warns: one fixed upstream).
phpConfig additionally: phpHandler (command, suffixes), memSoftLimit/memHardLimit, maxProcessTime (0 = unlimited; --php-max-process-time-ms overrides), procSoftLimit/procHardLimit, extMaxIdleTime, backlog default 1024, detachedMode.

Virtual hosts

Declarations live in httpd_config.xml (name, vhRoot, configFile, allowSymbolLink, enableScript, restrained); behavior lives in the referenced <virtualHostConfig>. allowSymbolLink is a tri-state override (file > declaration > server); restrained confines the vhost to vhRoot and forces symlinks off; enableScript=0 disables script handlers for the vhost.

Vhost directiveMeaning
docRoot, indexFiles, enableExpires/expiresByTypeRoot and per-vhost overrides of the server settings.
<rewrite> enable, autoLoadHtaccess, base, rulesInline rules run before the .htaccess chain.
<htAccess> allowOverride, accessFileNameallowOverride 0 kills the whole chain; the access file name defaults to .htaccess.
<vhssl> keyFile, certFile, certChain, CACertFileThe SNI identity for this vhost's domains (chain material, not a client-verify root).
<cache> enableCache, enablePublicCache, enablePrivateCachePer-vhost page-cache gates (with --page-cache-standard-vhosts a missing block gets a default public policy).
<scriptHandlerList><scriptHandler> suffix, type, handlerSuffix routing to lsapi/php handlers or a cgi handler bound to a FastCGI processor.
<websocketList><websocket> uri, addressWebSocket relay maps (plain TCP HTTP/1 upstreams).
<logging> accessLog/errorLog with useServer=0, fileName, rollingSize, keepDays, logHeaders httpjetPer-vhost log files (default roll 50 MB, keep 30 days; logHeaders 7 = combined). Log paths are boot-owned.
setUIDMode (0/1/2), chrootMode (0/1/2), chrootPath, suexecUser/suexecGroup, <namespace>Per-vhost PHP isolation (needs the server <suexec> gate). Out-of-range modes are hard errors. →
<extProcessorList>Vhost-scoped processors (distinct scope from server-level ones).

Contexts

Contexts map URI prefixes to terminals (static, proxy, redirect, php/lsapi via handler) and carry per-context overrides:

Context directiveDefaultMeaning
type, uri, location, handler, enabled—Kind, prefix, on-disk location (static), processor name (proxy/lsapi).
extraHeaders—Additional response headers for the context.
addDefaultCharset / addDefaultCharsetCustomizedoffCharset appended to text types.
cachePolicy/*oncheckPublicCache, checkPrivateCache, respectCacheable, enableCache, enablePrivateCache, enablePostCache — the six LSWS gates, enforced on both cache tiers.
maxReqBodySize httpjetinheritPer-context body cap (413) on every terminal.
responseTimeout httpjetinheritUpstream response-head deadline, seconds (proxy paths).
bandwidthLimit httpjet0Egress throttle overriding the server-wide rate.
subFilter (repeatable) · subFilterOnce · subFilterTypes · subFilterMaxBody httpjet— · 0 · text/html · 4MSEARCH => REPLACEMENT literal body substitution. The => separator is mandatory — a rule missing it disables the whole context's sub_filter with a warning. →
vhost XML · a proxied API prefix with overrides
<contextList>
  <context>
    <type>proxy</type>
    <uri>/api/</uri>
    <handler>application</handler>
    <maxReqBodySize>2M</maxReqBodySize>
    <responseTimeout>15</responseTimeout>
    <subFilter>http://internal.example => https://example.test</subFilter>
    <subFilterTypes>text/html,application/json</subFilterTypes>
  </context>
</contextList>

Checking a configuration

check
httpjet --root /abs/root check            # summary: listeners, vhost map, fast-memo verdicts, warnings
httpjet --root /abs/root check --strict   # + topology lint, missing docroots, vhost-map-fingerprint; non-zero on findings

Run the check under the intended service identity as well as as root: readable-by-root is not proof the runtime user can read certificates or write logs and sockets. The same normalization runs for the write API's in-memory bundle (parse_bundle), which additionally refuses DTDs, more than 64 nesting levels, more than 128 vhosts, and 1 MiB of XML. A config file read from disk is capped at 16 MiB per file (ConfigError::TooLarge, 2026-10-06) — a bound on all readers, check included.

Environment variables

The full list, with the flags they pair with, is on the CLI reference. The ones most often set in a unit drop-in: HTTPJET_ACCESS_LOG_FORMAT=json, HTTPJET_ERROR_LOG_FORMAT=json, HTTPJET_SYSLOG_TARGET, CF_SEND_ZSTD=1, HJ_FAST_MEMO=0, HTTPJET_OTEL=1, RUST_LOG.

httpjet · documentation · synced to the source tree on 2026-10-13 (v0.0.5).
Source: github.com/faratech/httpjet · Home: httpjet.net · Found an error? Open an issue on the repository.