Logo Httpbun

This is a service to help easily test the behaviour of HTTP clients like browsers, libraries, developer tools or anything else. Heavily inspired by the httpbin project. Canonical version available at httpbun.com, currently mirrored at httpbun.org as well.

Star this project on GitHub.

Endpoints

/get
Accepts GET requests and responds with a JSON object with query params, headers and a few other information about the request.
/post
/put
/patch
/delete
Accepts POST requests and responds with a JSON object with form body, query params, headers and a few other information about the request. There's also /put, /patch and /delete endpoints that behave similarly.
/headers
Responds with a JSON object with a single field, headers which is an object of all the headers in the request, as keys and values. If a header repeats in the request, then its values are concatenated with a comma and treated as a single header value.

Authentication

/basic-auth/{username}/{password}
Requires basic authentication with username and password as the credentials.
/bearer
/bearer/{expectedToken}
Requires bearer authentication. Which needs an Authorization header in the request, that takes the form Bearer some-auth-token-here. If no expectedToken is given, any token will be treated as valid.
/digest-auth/{qop}/{username}/{password}
Digest authentication. The endpoint /digest-auth/auth/scott/tiger requires to be authenticated with the credentials scott and tiger as username and password. The implementation is based on this example from Wikipedia. The value of qop is usually auth.

Client Details

/ip
Responds with a JSON object with a single field, origin, with the client's IP Address for value.
/user-agent
Responds with a JSON object with a single field, user-agent, with the client's user agent (as present in the User-Agent header) for value.

Caching

/cache
If the request contains an If-Modified-Since or If-None-Match header, returns a 304 response. Otherwise, it behaves the same as /get for GET requests, /post for POST requests, etc.
/cache/{age}
Sets a Cache-Control header for age seconds.
/etag/{etag}
Assumes the resource has the given etag and responds to If-None-Match and If-Match headers appropriately.

Client Tuned Response

/status/{codes}
Responds with the HTTP status as given by codes. It can be a comma-separated list of multiple status codes, of which a random one is chosen for the response.
/response-headers
Sends given query parameters as headers in the response. For example, in the response from /response-headers?one=two, there is a header called One, whose value is two. The response body contains all the headers again, in the form of a JSON object. (This JSON object in the response should be considered deprecated, and may be removed in the future.)
/deny
Returns page denied by robots.txt rules.
/html
Returns a small HTML document, sans CSS, sans Javascript. The same response is returned every time.
/json
Returns a small JSON object. The same response is returned every time.
/robots.txt
Returns some robots.txt rules.
/xml
Returns a small XML document. The same response is returned every time.
/base64
/base64/{encoded}
Decodes the encoded text with base64 encoding scheme. Defaults to SFRUUEJVTiBpcyBhd2Vzb21lciE=.
/bytes/{count}
Returns count random bytes in the response. The Content-Type header is set to application/octet-stream. The pseudo-randomness algorithem is not to be considered as cryptographically secure.
/delay/{seconds}
Respond with a delay of seconds seconds. The seconds parameter has to be an integer currently. Fractional delays are not yet supported.
/drip
/drip-lines
Drips data over a duration, with an interval between each piece of data. The piece of data is the * character. The following query params can be used to configure this endpoint: When using /drip-lines, a newline character is written after every piece of data.
Returns an HTML document with count links, which in turn respond with HTML documents with links again. You mostly want to use the first version (i.e., without offset).
/range/{count}
Returns count random bytes, that are generated with the same random seed every time. The value of count is capped to 1000.

Cookies

/cookies
Returns cookie data from the request headers.
/cookies/set
Sets cookies for all given query params.
/cookies/set/{name}/{value}
Set the cookie name to value.
/cookies/delete
Returns a response that will delete cookies in the browser. Cookies to be deleted should be given as query params. The values of these query params are ignored and can be empty.

Redirects

/redirect-to
Responds with a redirect to the URL given by the url query param. If a status_code query param is also given, it is used as the HTTP Status code in the response. Otherwise, 301 is used.
/redirect/{count}
/relative-redirect/{count}
Redirect count times. For example, /redirect/3 will redirect three times before settling on a response. The redirect URLs specified in the Location header will be relative URLs.
/absolute-redirect/{count}
Redirect count times. For example, /redirect/3 will redirect three times before settling on a response. The redirect URLs specified in the Location header will be absolute URLs.

Anything

/anything
/anything/{...}
Acts like /get, /post etc., but will work with any given method.

Frame embedding

/iframe?url={url}
Returns a small HTML page with an iframe, pointing to the given url. For example, opening /iframe?url=https://sharats.me in the browser will show a page that tries to open https://sharats.me in an iframe.

OAuth

/oauth/authorize
A dummy OAuth authorization endpoint. It can take a client_id, scope, state etc. that are required for a typical OAuth flow, and present the user a minimal UI to approve or decline, and then redirect to the URL specified by redirect_uri with appropriate details. You may try this out with the OAuthDebugger to understand the flow better.

Self Hosting

Running your own version of Httpbun is super-easy, particularly because it doesn't require any other services like a database or even a disk to write to. If you have Docker installed, the following command is all you need:
docker run -p 8008:80 ghcr.io/sharat87/httpbun

Environment

Httpbun can be configured in a limited way using the following environment variables:
HOST
The host to bind the server to. Defaults to localhost. Set it to 0.0.0.0 to make your instance accessible from non local clients.
PORT
The port on which to listen to. Defaults to 3090.
HTTPBUN_ALLOW_HOSTS
A comma separated list of hosts at which this instance will accept connections. Defaults to empty, which means it will allow any. An example: httpbun.com,httpbun.org.
HTTPBUN_FORCE_HTTPS
If set to 1, only accept connections coming in as https. By default, https is not forced.
HTTPBUN_INFO_ENABLED
If set to 1, the endpoint /info will be availble, which responds with various server information. By default, /info returns a 404 Not Found response.

Differences from Httpbin

Not all endpoints in httpbin are yet supported by httpbun. This will change as I get to spend more time on adding those features to httpbun, so be sure to check back.

The following though, are known incompatibilities with Httpbin, and are intended. These deviations are intentional and are unlikely to change (unless of course there's a compelling reason to).

  1. Headers are always in their canonical representation. That is, the header X-One is always represented as X-One, and never as x-one or any other casing.
  2. Almost all endpoints work with any HTTP method. Notable exceptions are the method endpoints themselves, i.e., /get, /post, etc.
  3. Not all endpoints are available. This will be fixed eventually, but if you need something, please open an issue on GitHub.
  4. The bytes returned by /range are not the same as those from httpbin.
  5. Written in Go. Mostly because I wanted to learn Go, and used this project as an excuse.

License

Httpbun is distributed with the Apache-2.0 License. Please refer to the LICENSE and NOTICE files present in the source distribution of this project.

Credits

  1. httpbin. This project might not have existed, if not for httpbin.
  2. Go's excellent documentation. This project might've taken a hell of a lot longer, if not for Go's docs.

This favicon was generated using the following graphics from Twitter Twemoji: