MockServerを利用して光の速さでDebug用のProxyサーバーを作ってみる

## MockServerとは？
MockServerは、こちらのページ\(https://www.mock-server.com) で公開されているHTTP Request/Responseに関する Debug を支援してくれるソフトウェアです。機能の1つとして、Debug用のProxyサーバーとして起動して、受け取ったHTTP Request/Responseを平文でファイルに出力することができます。
この記事ではLinux環境で、このDebug用のProxyサーバーを光の速さで作って利用する方法を紹介しています。

## MockServerを光の速さで作ってみる

今回はJava(Zulu 1.8.0_372-b07)を利用しています。あらかじめ環境変数 __JDK_HOME__ を設定した状態で次のコマンドを実行するとMockServerを起動できます。
```
#初回
mkdir ~/software/
wget -O ~/software/mockserver-netty-5.11.1-jar-with-dependencies.jar https://search.maven.org/remotecontent?filepath=org/mock-server/mockserver-netty/5.11.1/mockserver-netty-5.11.1-jar-with-dependencies.jar

#開始コマンド
kill -9 `pgrep -f mockserver.*8888` ; rm -rf ~/MockServer8888.out && nohup ${JDK_HOME}/bin/java -Xmx4096m -jar ~/software/mockserver-netty-5.11.1-jar-with-dependencies.jar -serverPort 8888 -logLevel DEBUG 2>&1 > ~/MockServer8888.out &
```

開始コマンドでは次の処理を実行しています。
- すでにPORT=8888を利用するMockServerが起動していれば強制停止
- MockServerのトレースファイル(~/MockServer8888.out)が存在していたら削除
- MockServerをPORT=8888を指定してnohupで起動
- トレースファイルを~/MockServer8888.outに出力

MockServerが正常に起動すると、Webブラウザで __https://\<MockServerを起動した環境のIPアドレス/ホスト名\>:8888/mockserver/dashboard__ にアクセスすることでコンソールを表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/26834443-25d8-844a-9486-eb5a0335ebe4.png)

## curlコマンドで動作確認してみる
次のコマンド実行して、MockServerの動作を確認してみます(curlコマンド利用時にMockServerをProxyサーバーとして指定してます)。
```
curl -k https://dns.google/ -x <MockServerを起動した環境のIPアドレス/ホスト名>:8888
```
MockServerのコンソールを見ると次のように受け取ったHTTP Request(dns.googleに対するGET操作)やResponseを確認できます(▼の箇所をクリックして情報を展開しています)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/f9786207-7eb0-2aa0-80a5-1ebf813f0208.png)

トレースファイル(~/MockServer8888.out)には次のログが出力されています。こちらの出力からもHTTP Request(dns.googleに対するGET操作)やResponseを確認できます。
```
2024-11-27 17:21:31 5.11.1 INFO 8888 returning response:

  {
    "statusCode" : 200,
    "reasonPhrase" : "OK",
    "headers" : {
      "Content-Security-Policy" : [ "object-src 'none';base-uri 'self';script-src 'nonce-yDRU3pIHGvRMwLt_Fg1uIA' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/honest_dns/1_0;frame-ancestors 'none'" ],
      "Strict-Transport-Security" : [ "max-age=31536000; includeSubDomains; preload" ],
      "X-Content-Type-Options" : [ "nosniff" ],
      "Content-Type" : [ "text/html; charset=UTF-8" ],
      "Content-Security-Policy-Report-Only" : [ "script-src 'none'; form-action 'none'; frame-src 'none'; report-uri https://csp.withgoogle.com/csp/scaffolding/ntdsgswbsc:55:0" ],
      "Cross-Origin-Opener-Policy-Report-Only" : [ "same-origin; report-to=coop_reporting" ],
      "Report-To" : [ "{\"group\":\"coop_reporting\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/scaffolding/ntdsgswbsc:55:0\"}],}" ],
      "Date" : [ "Wed, 27 Nov 2024 11:51:31 GMT" ],
      "Server" : [ "scaffolding on HTTPServer2" ],
      "X-XSS-Protection" : [ "0" ],
      "X-Frame-Options" : [ "SAMEORIGIN" ],
      "Alt-Svc" : [ "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" ],
      "content-length" : [ "1381" ]
    },
    "body" : "<!DOCTYPE html>\n<html lang=\"en\"> <head> <title>Google Public DNS</title>  <meta charset=\"UTF-8\"> <link href=\"/static/93dd5954/favicon.png\" rel=\"shortcut icon\" type=\"image/png\"> <link href=\"/static/e6eca759/matter.min.css\" rel=\"stylesheet\"> <link href=\"/static/f85675c0/shared.css\" rel=\"stylesheet\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">  <link href=\"/static/d05cd6ba/root.css\" rel=\"stylesheet\"> </head> <body> <span class=\"filler top\"></span>   <div class=\"logo\" title=\"Google Public DNS\"> <div class=\"logo-text\"><span>Public DNS</span></div> </div>  <form action=\"/query\" method=\"GET\">  <div class=\"row\"> <label class=\"matter-textfield-outlined\"> <input type=\"text\" name=\"name\" placeholder=\"&nbsp;\"> <span>DNS Name</span> <p class=\"help\"> Enter a domain (like example.com) or IP address (like 8.8.8.8 or 2001:4860:4860::8844) here. </p> </label> <button class=\"matter-button-contained matter-primary\" type=\"submit\">Resolve</button> </div> </form>  <span class=\"filler bottom\"></span> <footer class=\"row\"> <a href=\"https://developers.google.com/speed/public-dns\">Help</a> <a href=\"/cache\">Cache Flush</a> <span class=\"filler\"></span> <a href=\"https://developers.google.com/speed/public-dns/docs/using\"> Get Started with Google Public DNS </a> </footer>   <script nonce=\"yDRU3pIHGvRMwLt_Fg1uIA\">document.forms[0].name.focus();</script> </body> </html>"
  }

 for forwarded request

 in json:

  {
    "method" : "GET",
    "path" : "/",
    "headers" : {
      "Host" : [ "dns.google" ],
      "User-Agent" : [ "curl/7.61.1" ],
      "Accept" : [ "*/*" ],
      "content-length" : [ "0" ]
    },
    "keepAlive" : true,
    "secure" : true
  }
```

今回はcurlコマンドを自分で実行しているため、実行しているHTTP Request/Responseは明確ですが、エンタープライズ製品ではそうとも限りません。エンタープライズ製品側でHTTP Request/ResponseをトレースするDebugオプションがあれば良いのですが、そうでない場合にはMockServerを利用することで動作解析を進めることができます。

:::note info
エンタープライズ製品・既存製品においてMockServerを利用するためには、MockServerをProxyサーバーとして利用する設定が必要です。
:::


# MockServerを停止するには
前述のコマンドで起動したMockServerは次のコマンドで停止できます。
```
kill -9 `pgrep -f mockserver.*8888`
```

## おわりに
この記事では、Debug用のProxyサーバーとしてMockServerを紹介させてもらいました。Debug用のProxyサーバーとしてではなく、単純にProxyサーバーを使いたいという場合にも光の速さでサーバーを作れるので便利です。
なお、今回はLinux環境をベースに利用方法を紹介しましたが、MockServerはWindows環境でも利用できます。プラットフォームによらず利用できる点も魅力の1つだと思っています。