Skip to content

rockdrilla/rngpotd

Repository files navigation

rngpotd

A minimal HTTP server that responds to every request with a randomly chosen — and often obscure — HTTP status code. A fun little tool for testing HTTP client resilience, benchmarking, or just exploring the weird corners of the HTTP spec.

build-status goreport docker-pulls license

Features

  • Returns a random status code from a curated selection of rare, odd, and non-standard codes.
  • HTTP/1.0 and HTTP/1.1 only (HTTP/2 stripped out at compile time via build tags).
  • No keep-alives — each request gets a fresh TCP connection.
  • Optional liveness and readiness probe endpoints.
  • Single-binary deployment, statically linked, distroless Docker image.

Usage

Flag Environment variable Default value Description
--listen LISTEN 0.0.0.0:8888 Listen endpoint (addr:port).
--readiness-path READINESS_PATH "" Readiness probe path.
--liveness-path LIVENESS_PATH "" Liveness probe path.

Quick start

# 1st shell
make
./rngpotd
# 2nd shell
curl -v http://localhost:8888/

Status codes served

Code Message Notes
203 Non-Authoritative Information
204 No Content
205 Reset Content
207 Multi-Status
208 Already Reported
226 IM Used
267 Doubtful But Okay Proposal (internet meme/joke)
306 Switch Proxy gone; reserved in RFC 2616
402 Payment Required
406 Not Acceptable
407 Proxy Authentication Required
409 Conflict
410 Gone
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
418 I'm a teapot RFC 2324 (April 1st joke from IETF)
421 Misdirected Request
422 Unprocessable Entity
423 Locked
424 Failed Dependency
425 Too Early
426 Upgrade Required
428 Precondition Required
429 Too Many Requests
431 Request Header Fields Too Large
444 Connection Closed Without Response nginx-specific internal code
451 Unavailable For Legal Reasons
499 Client Closed Request nginx-specific internal code

Build

make

The binary is statically linked with CGO disabled. HTTP/2 support is stripped from the build (nethttpomithttp2 build tag) to reduce binary size.

Docker

docker build -t rngpotd .

The Docker image is based on gcr.io/distroless/static-debian13:nonroot and runs as a non-root user.

Build tags

Tag Effect
nethttpomithttp2 Excludes HTTP/2 from net/http.

Development build

Enables the race detector and CGO:

make dev-build

Benchmarking

Since the server is HTTP/1.x only, good old ab (ApacheBench) works perfectly:

# 50k requests, 100 concurrent
ab -n 50000 -c 100 http://localhost:8888/

Or try hey for a modern alternative:

hey -n 50000 -c 100 http://localhost:8888/

Each request opens and closes a new connection. Disabling keep-alives like this makes the benchmark a good test of TCP connection handling under load.

How it works

  1. httpAnyRequest() picks a random status code from the rngRetCodes array.
  2. Looks up the corresponding status text via httpStatusText() (supports non-standard codes).
  3. Responds with text/plain, the status text as the body, and a playful Server: nginx/X.Y.Z header.

That's it. One endpoint, random responses.

Health probes

If configured via --liveness-path or --readiness-path, the server registers dedicated endpoints that respond with HTTP 200 OK and a plain-text OK body. Probes use the real server identity (rngpotd/X.Y.Z) in the Server header, distinct from the fake nginx/X.Y.Z served on the main endpoint.

License

Apache 2.0 | spdx.org | opensource.org

About

Fun&dumb HTTP response generator

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors