Compared to mendhak/http-https-echo¶
https-echo-server started as a Go rewrite of
mendhak/docker-http-https-echo
(Node/Express). Environment variable names were kept compatible wherever the
same feature exists in both projects, so it can act as a drop-in replacement
— but a lot has been added on top. This page is an inventory of what's new.
New capabilities¶
HTTP/2¶
h2 is negotiated via ALPN on the TLS listener, and cleartext h2c (both
prior-knowledge and Upgrade:) is accepted on the plaintext listener.
mendhak's image is HTTP/1.1 only. See Listeners &
HTTP/2.
HTTP2_ENABLED,HTTP2_H2C_ENABLED
Two extra TLS modes: on-the-fly CA and Vault PKI¶
mendhak only supports one mode: a static certificate/key pair served
identically for every connection, regardless of SNI. https-echo-server adds
two more, selected with TLS_MODE:
auto(default) — generates a local root CA once (or loads one you already placed atTLS_CA_CERT_FILE/TLS_CA_KEY_FILE), then mints a leaf certificate matching the client's SNI at handshake time, cached in memory. Useful for testing many hostnames against one instance without juggling certificate files.vault— same per-SNI behaviour, but leaf certificates are issued on demand by a HashiCorp Vault PKI secrets engine, with automatic re-issuance and stale-serving on transient Vault failures.
Both new modes also serve their CA chain on a plaintext download endpoint
(TLS_CA_ENDPOINT, default /ca) and print it at startup (TLS_CA_PRINT),
so curl --cacert / browser import needs no manual certificate handling.
See the TLS guide.
TLS_MODE,TLS_CA_CERT_FILE,TLS_CA_KEY_FILE,TLS_CA_PRINT,TLS_CA_ENDPOINT,TLS_CERT_TTL,TLS_CERT_CACHE_SIZE,VAULT_ADDR,VAULT_TOKEN,VAULT_NAMESPACE,VAULT_PKI_MOUNT,VAULT_PKI_ROLE,VAULT_PKI_TTL,VAULT_CACERT,VAULT_SKIP_VERIFY
Forwarding to a remote server, with both legs dumped¶
FORWARD_URL turns the daemon into a relay: it forwards each request to a
remote server, fully captures the remote response, logs both legs, and
relays the response back to the original client unchanged. Nothing like this
exists in mendhak — it's for dropping the daemon between two real
components to see exactly what they send each other. See Usage →
Forwarding.
FORWARD_URL,FORWARD_PRESERVE_HOST,FORWARD_TIMEOUT,FORWARD_SKIP_VERIFY
curl -v-style verbose wire dump¶
VERBOSE=true prints an atomic, human-readable trace of every exchange to
stdout — request and response, and both legs when forwarding — instead of
(or alongside) the structured JSON echo. See Usage → Verbose wire
dump.
VERBOSE
WebSocket echo¶
ws:// and wss:// upgrades are accepted on both listeners: the first
server message is the JSON echo of the upgrade request, then every
subsequent message is mirrored back unchanged, with no message-size limit.
mendhak has no WebSocket support.
WS_ENABLED
Structured, leveled logging¶
Logs are structured (JSON or human-friendly console) via
zap, with a configurable level
(debug/info/warn/error) and rich per-request/per-subsystem fields.
mendhak only offers a boolean DISABLE_REQUEST_LOGS toggle and
LOG_WITHOUT_NEWLINE on top of Express's fixed log-line format.
LOG_LEVEL,LOG_FORMAT
Configuration via CLI flags or a config file, not just env vars¶
Every option can be set as a --kebab-case flag, an environment variable, or
a key in a YAML/TOML/JSON config file (--config config.yaml), with
precedence flags > env > file > defaults. mendhak's image is configured
through environment variables only.
--config/CONFIG
Operational conveniences¶
- Graceful shutdown with a configurable drain window (
SHUTDOWN_TIMEOUT) instead of an immediate stop. - Independent listener toggles (
HTTP_ENABLED,HTTPS_ENABLED) and a configurable bind address (BIND_ADDRESS), rather than always binding both ports on all interfaces. - Single static binary (
CGO_ENABLED=0), with multi-arch (amd64/arm64) release binaries in addition to the distroless Docker image — no Node.js runtime required.
Behavioural differences (not regressions)¶
Header case is always preserved¶
mendhak lower-cases response headers by default and requires
PRESERVE_HEADER_CASE=true to keep the original case. https-echo-server
always echoes headers in canonical HTTP case — there is no option, and
none is needed.
No LOG_WITHOUT_NEWLINE¶
mendhak's Express logger could embed literal newlines in a log line, hence the flag to strip them. zap's JSON and console encoders never emit embedded newlines, so there's nothing to disable.
Feature parity¶
These behave the same way and use the same environment variable names as mendhak, so existing deployments migrate without changes:
| Feature | Env var(s) |
|---|---|
| Choose listener ports | HTTP_PORT, HTTPS_PORT |
| Bring your own certificate/key pair | HTTPS_CERT_FILE, HTTPS_KEY_FILE |
Trusted proxy IPs/CIDRs for X-Forwarded-* |
ADDITIONAL_TRUSTED_PROXIES |
| JWT header decoding | JWT_HEADER |
| Suppress per-request log lines | DISABLE_REQUEST_LOGS |
| Skip logging matching paths | LOG_IGNORE_PATH |
| JSON request body parsing/echo | (automatic) |
| Echo only to logs, empty response | ECHO_BACK_TO_CLIENT |
| Custom response status code | x-set-response-status-code (header or query) |
Custom response Content-Type |
x-set-response-content-type (header or query) |
| Artificial response delay | x-set-response-delay-ms (header or query) |
| Body-only response | response_body_only=true (query) |
| Include process env vars in the echo | ECHO_INCLUDE_ENV_VARS |
| CORS headers | CORS_ALLOW_ORIGIN, CORS_ALLOW_METHODS, CORS_ALLOW_HEADERS, CORS_ALLOW_CREDENTIALS |
| mTLS client certificate echo (no validation) | MTLS_ENABLE |
| Override response body from a file | OVERRIDE_RESPONSE_BODY_FILE_PATH |
| Maximum request header size | MAX_HEADER_SIZE |
| Cookies and signed cookies | COOKIE_SECRET |
| Prometheus metrics | PROMETHEUS_ENABLED and related PROMETHEUS_* variables |
See the configuration reference for the complete, current list of every flag/env var, and usage & endpoints for the echo response format.