httpbin.org の便利な使い方

## 概要

HTTPのテストで用いる擬似的なバックエンドとして [httpbin.org](http://httpbin.org/)がある。簡単なテスト目的で利用していたが、調べてみると思いの外高機能だったので幾つかを紹介する。

## 0. 基本

基本的には作成したモジュールから https://httpbin.org/xxx に対し様々なリクエストを送り各種動作確認を行う。個人的には自作したプロキシの動作確認等でよく利用する。

### GET

`/get` エンドポイントにリクエストを投げる最もシンプルな例。

```bash
$ curl https://httpbin.org/get
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.2.1", 
    "X-Amzn-Trace-Id": "Root=1-6594009e-4274ba494714ce5829d0a672"
  }, 
  "origin": "114.148.80.191", 
  "url": "https://httpbin.org/get"
}
```

### POST

`/post` 等の更新系エンドポイントももちろん使える。

```bash
$ curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "key1=value1&key1=value2&key2=value3" https://httpbin.org/post
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key1": [
      "value1", 
      "value2"
    ], 
    "key2": "value3"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "35", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.2.1", 
    "X-Amzn-Trace-Id": "Root=1-65940296-501ee17e2d728da85dbb314b"
  }, 
  "json": null, 
  "origin": "114.148.80.191", 
  "url": "https://httpbin.org/post"
}

```

## 1. ローカル実行

一定の負荷の下で利用するためスロットリングに引っかかりたくない…等の事情のある人はローカル上でも環境を作ることができる。

公式のイメージが公開されているので、以下の様な **compose.yml** を用意して立ち上げれば起動する。

```yaml
services:
  httpbin:
    image: kennethreitz/httpbin
    port:
    - "80:80"
```


```bash
$ docker compose up -d

$ curl http://localhost:80/get
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "localhost", 
    "User-Agent": "curl/8.2.1"
  }, 
  "origin": "10.89.10.5", 
  "url": "http://localhost/get"
}

```

> podman を利用している場合 `podman-compose up` で実行


## 2. `delay`（遅延）の指定

Backend サーバーの応答が遅い際の挙動を確認したい場合、`/delay/{秒数}` エンドポイントが利用できる。URLパラメーターには秒単位で遅延を指定する。小数点の利用も可。最大値は`10s`。

```bash
$ curl http://httpbin.org/delay/0.5
```

試しに本当に遅延しているか `time`で確認すると `500ms`以上の待機時間を確認できる。

```bash
$ time curl -s http://localhost:80/delay/0.5 > /dev/null

real	0m0.507s
user	0m0.003s
sys	0m0.003s
```

> 余計な出力は `-s`（進行状況非表示）と `> /dev/null`（出力破棄）で表示にしている

## 3. `status`(ステータスコード）の指定

Backend がエラーを返してきた際の挙動を確認したい場合、`/status`エンドポイントを利用してステータスコードを指定してリクエストを送ることもできる。成功ステータス以外を返された際の動作確認に利用できる。

```bash
$ curl -I -X GET https://httpbin.org/status/403
HTTP/2 403 
date: Tue, 02 Jan 2024 12:59:11 GMT
content-type: text/html; charset=utf-8
content-length: 0
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
```

## 4.`response headers` レスポンスヘッダーの指定

Backend が任意のHeaderを返したときの挙動を確認したい場合、`/response-headers` エンドポイントの利用で解決できる。任意のHeader値はクエリパラメーターで指定する。複数設定も可能。

```bash
$ curl -s -i "https://httpbin.org/response-headers?RespKey1=RespVal1&RespKey1=RespVal2&RespKey2=RespVal3"
HTTP/2 200 
date: Tue, 02 Jan 2024 17:47:27 GMT
content-type: application/json
content-length: 150
server: gunicorn/19.9.0
respkey1: RespVal1
respkey1: RespVal2
respkey2: RespVal3
access-control-allow-origin: *
access-control-allow-credentials: true

{
  "Content-Length": "150", 
  "Content-Type": "application/json", 
  "RespKey1": [
    "RespVal1", 
    "RespVal2"
  ], 
  "RespKey2": "RespVal3"
}
```

> Cookie 操作系は別途存在するのでそれを用いる
>
> ```bash
> $ curl https://httpbin.org/cookies
> {
>   "cookies": {}
> }
> ```

## 5.`redirect` リダイレクトの指定

Backend が `3xx`系のレスポンスを返した際の挙動を確認したい場合、`/redirect` エンドポイントの利用で解決できる。

> 以下の例だと、ブラウザでアクセスすると Qiitaのトップにリダイレクトされる

```bash
$ curl -I https://httpbin.org/redirect-to?url=https://qiita.com
HTTP/2 302 
date: Tue, 02 Jan 2024 13:12:34 GMT
content-type: text/html; charset=utf-8
content-length: 0
location: https://qiita.com
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
```

## 6.`anything` リクエストの内容を全て返却

とりあえず投げた内容を返してくれと Methodも指定せずに 投げる際には `/anything` が対応してくれる。

```bash
$ curl -H 'HeaderKey1: HeaderVal1'  https://httpbin.org/anything?query-param-key1=query-param-val1
{
  "args": {
    "query-param-key1": "query-param-val1"
  }, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Headerkey1": "HeaderVal1", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.2.1", 
    "X-Amzn-Trace-Id": "Root=1-65945480-5bb8dcc64cba96800e5a34f3"
  }, 
  "json": null, 
  "method": "GET", 
  "origin": "114.148.80.191", 
  "url": "https://httpbin.org/anything?query-param-key1=query-param-val1"
}
```

## 7.`{ html | json | xml }` & `image/{ (None) | jpeg | png }` 主要なレスポンスフォーマット

具体的なページを用意しなくても、主要な Content-Typeのサンプルを返してくれる。一部のみ紹介するが、色々ある。

```bash
# HTML
$ curl https://httpbin.org/html
# JSON
$ curl https://httpbin.org/json
# XML
$ curl https://httpbin.org/xml
# Image
$ curl https://httpbin.org/image
$ curl https://httpbin.org/image/jpeg -o image.jpg
$ curl https://httpbin.org/image/png -o image.png
```

## 8. utility系

他の手段でも実現できるけど地味に便利なユーティリティ系の Endpointも存在する。

```bash
# ClientのGIPの確認
$ curl https://httpbin.org/ip
{
  "origin": "114.148.80.191"
}

# ClientのUser-Agentの確認
$ curl https://httpbin.org/user-agent
{
  "user-agent": "curl/8.2.1"
}

# Base64のデコード
$ curl https://httpbin.org/base64/aGVsbG8K
hello
```



## まとめ

httpbin が意外と便利だということを数点の利用頻度の高そうな機能と共に紹介した。


主観で面白いと思ったものを数点ピックアップしてみたが、他にも様々な機能があるので、一度 公式の[API仕様](http://httpbin.org/) を見て使えそうなものが無いか確認してほしい。お望みのものが見つかると良いね。