Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Request bin

A request bin is a URL that records everything sent to it. Point a webhook sender, a gateway's HTTP logging plugin, a mirroring policy or a callback at it, then inspect what arrived.

RoutePurpose
POST /binCreate a bin (201) and get its URLs
GET /binList the bins owned by your session
ANY /bin/{id} and ANY /bin/{id}/{*path}Capture a request (except DELETE /bin/{id}, which deletes the bin)
GET /bin/{id}/requestsCaptured requests, newest first (?limit=, default 50)
GET /bin/{id}/requests/{n}One request by sequence number
GET /bin/{id}/requests/streamLive feed (Server-Sent Events)

Creating a bin

The optional JSON body configures what the bin answers: status, headers (name to value), body (a string, or JSON which is serialised and labelled application/json) and delay_ms (capped by the instance delay limit). Without a body the bin answers 200 with {"ok": true, "bin": ..., "id": ..., "seq": n}. Every capture response carries X-Rustybin-Bin-Seq.

The bin belongs to the creating session (X-Rustybin-Session, else the client IP), which is what GET /bin lists; anyone who knows the id can send to it, read it or delete it.

POST {{base_url}}/bin
X-Rustybin-Session: docs-bin
Content-Type: application/json
{"status": 202, "headers": {"X-Bin": "demo"}, "body": {"accepted": true}, "delay_ms": 100}
HTTP 201
[Captures]
bin_id: jsonpath "$.id"
[Asserts]
jsonpath "$.url" == "{{base_url}}/bin/{{bin_id}}"
jsonpath "$.requests_url" endsWith "/requests"
jsonpath "$.stream_url" endsWith "/requests/stream"
jsonpath "$.response.status" == 202
jsonpath "$.limits.max_requests" == 100

Capturing and inspecting

Each capture records the method, the path below the bin (path) and the full path, query, headers, client IP, timestamp and the body (up to 64 KiB, as text or body_base64). The inspection routes are never captured themselves.

# Point a webhook (or a gateway's logging plugin) at any sub path of the bin.
POST {{base_url}}/bin/{{bin_id}}/hooks/orders?attempt=1
Content-Type: application/json
X-Gateway-Consumer: alice
{"event": "order.created"}
HTTP 202
[Asserts]
header "X-Bin" == "demo"
header "X-Rustybin-Bin-Seq" == "1"
jsonpath "$.accepted" == true
duration >= 100
GET {{base_url}}/bin/{{bin_id}}/requests
HTTP 200
[Asserts]
jsonpath "$.count" == 1
jsonpath "$.requests[0].method" == "POST"
jsonpath "$.requests[0].path" == "/hooks/orders"
jsonpath "$.requests[0].query" == "attempt=1"
jsonpath "$.requests[0].body" == "{\"event\": \"order.created\"}"
jsonpath "$.requests[0].headers[?(@.name == 'x-gateway-consumer')].value" nth 0 == "alice"

GET {{base_url}}/bin/{{bin_id}}/requests/1
HTTP 200
[Asserts]
jsonpath "$.seq" == 1
jsonpath "$.full_path" == "/bin/{{bin_id}}/hooks/orders"
GET {{base_url}}/bin
X-Rustybin-Session: docs-bin
HTTP 200
[Asserts]
jsonpath "$.bins[*].id" contains "{{bin_id}}"
POST {{base_url}}/bin
HTTP 201
[Captures]
plain_bin: jsonpath "$.id"

PUT {{base_url}}/bin/{{plain_bin}}
`anything at all`
HTTP 200
[Asserts]
jsonpath "$.ok" == true
jsonpath "$.seq" == 1

The live feed sends one request event per capture with the sequence number as event id; Last-Event-ID replays the stored requests after that number. It ends when the bin expires or is deleted (the example stops reading after two seconds):

curl -sN --max-time 2 "$BASE/bin/$bin/requests/stream"

To capture a DELETE, send it to a sub path: DELETE /bin/{id} deletes the bin.

DELETE {{base_url}}/bin/{{bin_id}}
HTTP 200

GET {{base_url}}/bin/{{bin_id}}/requests
HTTP 404

Limits

NormalPublic mode
Bins200100 (10 per session)
Requests kept per bin10050
Stored bytes per bin1 MiB256 KiB
Lifetime24 hours1 hour
Captured body64 KiB64 KiB

The oldest requests are evicted first when a bin is full.