Skip to content

stephenl03/http-status

Repository files navigation

http-status

A small, dependency-free Go service that returns the HTTP status code you ask for — for testing how clients, proxies, and integrations handle different responses. It is a from-scratch rebuild of the discontinued httpstat.us.

Live: https://http-stat.us · Status: https://status.http-stat.us

Usage

Add a status code to the URL and the service returns that status:

curl https://http-stat.us/200      # 200 OK
curl https://http-stat.us/404      # 404 Not Found
curl https://http-stat.us/503      # 503 Service Unavailable

Get JSON by sending an Accept: application/json header:

curl -H 'Accept: application/json' https://http-stat.us/200
# {"code":200,"description":"OK"}

Pick a random code from a range (comma-separated numbers or inclusive spans):

curl https://http-stat.us/random/200,201,500-504

Delay the response (milliseconds, up to the configured maximum):

curl 'https://http-stat.us/200?sleep=2000'

Reflect a custom response header (the X-HttpStatus-Response- prefix is stripped):

curl -H 'X-HttpStatus-Response-Foo: Bar' https://http-stat.us/200
# response includes: Foo: Bar

Status and random endpoints accept GET, PUT, POST, DELETE, HEAD, OPTIONS, TRACE, PATCH, and the newer QUERY method, and allow all cross-origin requests. The homepage at / lists the full 87-entry catalog.

What it does

  • Returns any three-digit status with its catalog metadata, special headers, and a plain-text or JSON body.
  • Random-range selection, delayed and dribbled bodies, body suppression, and best-effort connection-abort modes for resilient-client testing.
  • Per-client and global fair-use admission control (token buckets plus non-queued semaphores) so slow-request abuse cannot starve ordinary traffic.
  • Ships as a static, non-root scratch container with all assets embedded — no database, no runtime dependencies, no outbound calls.

Known limitations

  • Terminal 1xx responses are unsupported: Go's server cannot emit them as final responses across HTTP versions, so 100199 return a transparent 501.
  • TRACE through a CDN edge — Cloudflare and most edges block TRACE with a 405 (cross-site-tracing protection), so it is not exercisable through the public edge even though the service accepts it directly. See compatibility.
  • No custom HTTP reason phrase (HTTP/2 has none); rely on the numeric code, headers, and body.

Run it locally

Requires Go 1.26+ (standard library only):

go run ./cmd/http-status
curl http://localhost:8080/200
go test ./...

Or with Docker (static scratch image, runs as a non-root user):

docker build -t http-status .
docker run -p 8080:8080 http-status

The server listens on :8080 by default. PORT sets the port when HTTP_STATUS_ADDR is unset, and flags override environment configuration.

Configuration

Flag Environment variable Default
-addr HTTP_STATUS_ADDR or PORT :8080
-public-base-url HTTP_STATUS_PUBLIC_BASE_URL https://http-stat.us
-max-timing HTTP_STATUS_MAX_TIMING 30s
-trusted-proxy-cidrs HTTP_STATUS_TRUSTED_PROXY_CIDRS empty
-ordinary-requests-per-minute HTTP_STATUS_ORDINARY_REQUESTS_PER_MINUTE 120
-ordinary-burst HTTP_STATUS_ORDINARY_BURST 30
-delayed-per-client HTTP_STATUS_DELAYED_PER_CLIENT 2
-delayed-starts-per-minute HTTP_STATUS_DELAYED_STARTS_PER_MINUTE 6
-delayed-starts-burst HTTP_STATUS_DELAYED_STARTS_BURST 2
-delay-budget-per-minute HTTP_STATUS_DELAY_BUDGET_PER_MINUTE 1m
-global-delayed-operations HTTP_STATUS_GLOBAL_DELAYED_OPERATIONS 100

Startup fails on invalid durations, negative limits, bad listener addresses, or host-bit proxy CIDRs. Each request-rate/burst pair must be both zero (disabled) or both positive. The binary trusts X-Forwarded-For only when its direct peer is in HTTP_STATUS_TRUSTED_PROXY_CIDRS, so direct clients cannot forge their limiter key. Per-client exhaustion returns 429 with Retry-After; global slow-work exhaustion returns 503 with Retry-After. GET /metrics exposes aggregate fair-use counters for a private operations network and must not be public. On SIGINT/SIGTERM, in-flight responses get the maximum timing budget plus a 15-second transport grace to finish.

Deployment

The Go listener is a private origin; run it behind a public edge (WAF, DDoS absorption, coarse rate limits) and a reverse proxy.

Documentation

License

MIT. The original httpstatus project is also MIT licensed by Aaron Powell; see NOTICE for retained attribution.

About

Test how your code handles HTTP status codes — request any status with delays, custom headers, JSON, and random ranges. Live at http-stat.us

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors