Testserver

A public test server for HTTP & friends, built as part of HTTP Toolkit.

Source code available at github.com/httptoolkit/testserver.

HTTP Endpoints

Request Inspection (7)
/{method} Returns request info for the specified HTTP method. Returns 405 if the request method does not match the path./get /post /put /patch /delete
/anything Returns JSON containing the parsed details of the request, including method, url, headers, args, data, files, form, and origin./anything/subpath
/echo Echoes back the raw HTTP request data. For HTTP/2, returns parsed frame data as JSON lines.
/headers Returns the request headers as JSON.
/ip Returns the client's IP address.
/trailers Tests HTTP trailers. Returns any received trailers and sends trailers back if the client indicated support via the TE header.
/user-agent Returns the User-Agent header from the request.
Custom Responses (3)
/info/{code} Sends a 1xx informational response (100, 102, or 103) before the final response. Supports all codes except 101 which is reserved for protocol upgrades (e.g. websockets). Use `?link=...` (repeatable) to attach Link headers for testing 103 Early Hints. Chains with other endpoints: e.g. /info/103/status/404 sends 103 then 404./info/102 /info/103?link=%3C/style.css%3E;rel=preload;as=style /info/110/info/199/echo
/response-headers Returns a response with headers set from the query parameters./response-headers?X-Custom=value /response-headers?freeform=hello&freeform=world
/status/{code} Returns a response with the specified HTTP status code./status/200 /status/404 /status/500
Redirects (4)
/absolute-redirect/{n} Redirects n times using absolute URLs, then returns /get./absolute-redirect/3
/redirect-to Redirects to the URL specified in the "url" query parameter, with an optional "status_code" (default 302)./redirect-to?url=/get /redirect-to?url=/get&status_code=301
/redirect/{n} Redirects n times using relative URLs (via /relative-redirect), then returns /get./redirect/3
/relative-redirect/{n} Redirects n times using relative URLs, then returns /get./relative-redirect/3
Caching (3)
/cache Returns 304 Not Modified if an If-Modified-Since or If-None-Match header is present, otherwise returns the same response as /get.
/cache/{n} Sets a Cache-Control header for n seconds, then returns the same response as /get./cache/60
/etag/{etag} Assumes the given etag for the resource and responds according to If-None-Match and If-Match request headers./etag/my-etag
Authentication (3)
/basic-auth/{username}/{password} Challenges with HTTP Basic Auth, expecting the username & password from the URL. Returns 200 with user info on success, 401 if unauthenticated, 403 if wrong credentials./basic-auth/admin/secret
/bearer Checks for a Bearer token in the Authorization header. Returns 200 with token info on success, 401 if missing.
/hidden-basic-auth/{username}/{password} Like /basic-auth but returns 404 instead of 401 on authentication failure./hidden-basic-auth/admin/secret
Cookies (3)
/cookies Returns the cookies sent with the request.
/cookies/delete Deletes cookies specified in query parameters, then redirects to /cookies./cookies/delete?name
/cookies/set Sets cookies via query parameters or path segments, then redirects to /cookies./cookies/set?name=value /cookies/set/name/value
Response Formats (7)
/deny Returns a page denied by robots.txt.
/encoding/utf8 Returns a UTF-8 encoded HTML page with various Unicode characters.
/html Returns an HTML page.
/json Returns a sample JSON document.
/robots.txt Returns a robots.txt file that disallows crawling of all paths except the root.
/xml Returns a sample XML document.
example Returns a copy of the example.com HTML page. Access via the example subdomain prefix.https://example.testserver.host/
Response Encoding (5)
/encoding/brotli Returns brotli-encoded JSON data.
/encoding/deflate Returns deflate-encoded JSON data.
/encoding/gzip Returns gzip-encoded JSON data.
/encoding/identity Returns uncompressed JSON data with content-encoding: identity.
/encoding/zstd Returns zstd-encoded JSON data.
Dynamic Data (7)
/base64/{value} Decodes a base64url-encoded string and returns the decoded value./base64/SGVsbG8gd29ybGQ=
/bytes/{n} Returns n random bytes. Supports an optional "seed" query parameter for deterministic output./bytes/1024
/delay/{seconds} Delays the response by the specified number of seconds (max 10). Can be chained with other endpoints./delay/1 /delay/5 /delay/2/status/200
/stream-bytes/{n} Streams n random bytes in chunks. Supports optional "chunk_size" (default 10240) and "seed" query parameters./stream-bytes/1024
/stream/{n} Streams n newline-delimited JSON objects, each containing request data with an incrementing id./stream/5
/uuid Returns a randomly generated UUID v4.
/version Returns the testserver.host server version hash as JSON.
TLS (3)
/tls/certs/{name} Download the TLS certificates used by the local CA configuration, in PEM format./tls/certs/untrusted-root /tls/certs/intermediate /tls/certs/self-signed
/tls/client-hello Returns the fully parsed TLS ClientHello. Requires HTTPS.
/tls/fingerprint Returns the TLS fingerprint (JA3 and JA4) of the client connection. Requires HTTPS.
Errors (2)
/error/close Immediately closes the connection without sending a response.
/error/reset Resets the connection (sends a TCP RST) without sending a response.

WebSocket Endpoints

Connect via wss://{hostname}/ws/...

Messaging (3)
/ws/echo Echoes back any messages received.
/ws/message/{text} Sends the specified message to the client upon connection. Can be chained with other WS endpoints./ws/message/hello /ws/message/hello/echo
/ws/repeat/{message}/{intervalMs} Repeatedly sends the specified message at the given interval (in milliseconds). Can be chained with other WS endpoints./ws/repeat/ping/1000 /ws/repeat/heartbeat/5000/echo
Connection (3)
/ws/close/{code} Closes the WebSocket connection with the specified close code (1000-4999). Optional reason via query parameter./ws/close /ws/close/1001 /ws/close/4000?reason=custom
/ws/no-subprotocol Explicitly omits the Sec-WebSocket-Protocol header from the upgrade response, overriding the default behavior where the server auto-selects the first client-offered protocol./ws/no-subprotocol/echo
/ws/subprotocol/{name} Forces the specified subprotocol in the upgrade response Sec-WebSocket-Protocol header, regardless of what the client requested./ws/subprotocol/graphql-ws/echo /ws/subprotocol/mqtt/message/hello/close/1000
Timing (1)
/ws/delay/{seconds} Delays WebSocket connection handling by the specified seconds (max 10). Can be chained with other WS endpoints./ws/delay/1/echo /ws/delay/5/close
Errors (1)
/ws/error/reset Destroys the WebSocket connection abruptly without a proper close handshake.

TLS Endpoints

The TLS endpoint(s) to use are specified by subdomain, e.g. expired.{domain}.

Endpoints can be combined using double-dashes, e.g. expired--revoked--http2--tls-v1-2.{domain} will return an expired and revoked certificate, use TLSv1.2, and then negotiate HTTP/2 on the connection.

These can also be combined with the HTTP or WebSocket handlers above, which can be independently specified in the request path.

The untrusted-root, intermediate & self-signed certificates used by some endpoints here can be downloaded separately from the /tls/certs/* HTTP endpoints.

example An example subdomain that serves an exact copy of the classic example.com page as the root page (instead of these docs).https://example.testserver.host/
no-tls Rejects the TLS handshake with a connection reset, simulating a server that does not support TLS.https://no-tls.testserver.host/
Certificate Modes (7)
expired Serves an expired TLS certificate.https://expired.testserver.host/
incomplete-chain Serves a TLS certificate without the required intermediate certificate.https://incomplete-chain.testserver.host/
no-common-name Serves a TLS certificate with no Common Name (Subject Alternative Name only). Local CA only.https://no-common-name.testserver.host/
revoked Serves a revoked TLS certificate (reported via OCSP).https://revoked.testserver.host/
self-signed Serves a self-signed TLS certificate.https://self-signed.testserver.host/
untrusted-root Serves a TLS certificate signed by an untrusted root CA.https://untrusted-root.testserver.host/
wrong-host Serves a TLS certificate for a different hostname.https://wrong-host.testserver.host/
Protocol Negotiation (2)

Endpoints that negotiate specific protocols via ALPN. These can be used together, to simulate a server supporting specific combinations of protocols, in the preference order specified.

http1 Forces HTTP/1.1 protocol via ALPN negotiation.https://http1.testserver.host/
http2 Forces HTTP/2 protocol via ALPN negotiation.https://http2.testserver.host/
TLS Versions (4)

Endpoints that only accept specific TLS versions. These can be used together, to simulate a server supporting any specific combination of versions.

tls-v1-0 Accepts only TLS 1.0 connections.https://tls-v1-0.testserver.host/
tls-v1-1 Accepts only TLS 1.1 connections.https://tls-v1-1.testserver.host/
tls-v1-2 Accepts only TLS 1.2 connections.https://tls-v1-2.testserver.host/
tls-v1-3 Accepts only TLS 1.3 connections.https://tls-v1-3.testserver.host/