ローカルプロキシ mitmproxy による快適なデバッグ入門


Webアプリケーション開発において、デバッグはなくてはならない重要なプロセスです。デバッグにより不具合を検知し、問題を分析し、修正することでプロダクトの完成度や安全性を高めていきます。

特にWebアプリケーションはAPIとフロントエンドの連携で構成される事が多く、分析のために調査をする範囲が広いです。フロントエンド起因の不具合であったり、API(バックエンド)で発生している場合もあったり、APIから返される特定のデータでのみフロントエンド側で発現する複合的なエラーであったりと、調査は一筋縄ではいきません。

Gaji-Labo が手掛けるスタートアップ支援においてもデバッグはとても大切です。Webアプリケーションは成長するごとにロジックが複雑化・肥大化し、デバッグの難易度、かかるコストが上がっていくなかで、より効率的・効果的にデバッグする手法を常に模索しています。

この記事では、デバッグでの初手である「現象の再現」をするのに役立つローカルプロキシについて紹介していきます。

デバッグの想定ケース

デバッグを具体的にイメージしてもらうために、想定するケースを例示しておきます。

  • 商品詳細ページにおいて、描画されるべき情報が正しく描画されていない
  • ローカル環境(APIはモックサーバー使用)では問題ないが、リモートのBeta環境で不具合が発生している
  • 特定のデータでのみエラーが発生する(特定の商品でのみ発生する)
  • エラー発生の詳細な条件はまだ不明

まず不具合発生の条件を探るために、再現する環境を用意しなければなりません。ローカルではモックサーバーのデータで動作確認をしているため、モックサーバーに「特定のデータ」を返却させれば再現できるはずですが、例えばOpenAPIなどを使用している場合、定義のyamlをいちいち編集するのは面倒です。

そんな場面で役立つのがローカルプロキシと呼ばれるツールです。

ローカルプロキシについて

まずはプロキシサーバーについて簡単に紹介します。プロキシサーバーは、Webサーバーとクライアント端末の間に位置する中継サーバーです。Webサーバーへのリクエスト・Webサーバーからのレスポンスはプロキシサーバーの中を経由します。

プロキシサーバー

プロキシサーバーはデータをキャッシュしてパフォーマンスを向上させたり、セキュリティを強化したりする役割をもっています。

そして、ローカルプロキシはその名の通り、ローカル環境で動かすことのできるプロキシサーバーです。

ローカルプロキシは、主にアプリケーションの通信内容をテストおよびデバッグするために使用されます。例えば、Webアプリケーションが外部サーバーとやり取りする際のリクエストやレスポンスを監視・記録し、内容を確認したり変更したりすることができます。

このローカルプロキシを活用してデバッグを行っていきます。

ローカルプロキシでどのように検証するか

具体的に上のケースで、ローカルプロキシによるデバッグをイメージしてみましょう。

  1. 実際にエラーが発生するデータ(JSON)をBeta環境のAPIレスポンスから取得してローカルに保存する
  2. ローカルプロキシでモックサーバーに 1. のJSONを返却させる
  3. ローカルで再現できたらフロントエンドのコードベースで原因の調査を進める

ローカルプロキシツールの多くは、指定したURLへのリクエストを監視してレスポンスを差し替える機能を備えています。この機能を使ってモックサーバーに検証用のデータを返却させ、ローカルのコードベースで動作検証して不具合の原因を調査します。

mitmproxy を使ってデバッグを行う

実際にローカルプロキシを使って検証してみましょう。

今回使うのは mitmproxy というPythonで書かれたローカルプロキシです。ローカルプロキシツールは数多くありますが、中でも mitmproxy はこんな特徴を持っています。

mitmproxy – an interactive HTTPS proxy

  • オープンソース
  • 無料
  • クロスプラットフォーム
  • CUIで使える(Webインターフェースも用意されている)

特に「CUIで使える」つまりターミナルで起動できるのが大きな特徴です。ブラウザで開くWebインターフェースも用意されているため、「黒い画面」が苦手な方でも安心して使うことができます。

基本的な使い方

導入について詳しくは割愛しますが、他のローカルプロキシ同様に次のような手順で開始します。

  1. ローカルプロキシサーバーを起動する
  2. コンピューターの設定でプロキシのホスト・ポートを指定する

ローカルプロキシの多くでは 2. が自動化されています。mitmproxy は自動で設定変更はしないため、手作業での設定が必要です。自動でシステムの設定を変更してくれるのは楽ではありますが、自分の預かり知らないところで設定が書き換えられるのは不安もあるのでこれはメリットであるとも言えます。

ではまず mitmproxy を起動します。

$ mitmweb -p 8888

プロキシサーバー自体は mitmproxy コマンドで立ち上げられますが、今回は見やすいWebインターフェースを使用するため mitmweb コマンドを使います。 -p オプションでポートを指定することができます。デフォルトは 8080 ですが、良く使われがちなポートなので衝突を防ぐため今回は 8888 を指定しています。

mitmweb コマンドを叩くと、自動的にブラウザで http://127.0.0.1:8081 が開かれます。これがWebインターフェースの画面です。

mitmproxy Webインターフェース

コンピューターの設定でプロキシのホスト・ポートを指定することで、コンピューターのインターネットアクセスは全て mitmproxy サーバーを経由して行われるようになります。

Map Local を使う

それでは、レスポンスをローカルファイルで差し替える機能である Map Local を使ってデバッグしてみましょう。 mitmweb で起動した場合は、Webインターフェースのオプションの中で Map Local の設定を変更することができます。

「Options」タブ →「Edit options」→ 「map_local」と辿ってアクセスできます。

Map Local の設定の仕方ですが、注釈にあるように決められたフォーマットに則って記述しなければなりません。

Map remote resources to a local file using a pattern of the form “[/flow-filter]/url-regex/file-or-directory-path”, where the separator can be any character.

“[/flow-filter]/url-regex/file-or-directory-path” 形式のパターンを使用して、リモート リソースをローカル ファイルにマップします。区切り文字には任意の文字を使用できます。

注釈の例では区切り文字にスラッシュ( / )が使われていますが、スラッシュはURLやファイルパスで使われているため、他の文字にすべきでしょう。例えば バーティカルバー ( | )などを使います。

|https://www.example.com/api/v1/hello|~/hello.json

この設定の場合、 https://www.example.com/api/v1/hello へのリクエストに対するレスポンスのボディが、 ユーザーホームディレクトリにある hello.json というファイルの中身に差し替えられます。

改行で区切ることで複数のマッピングルールを設定することができます。

|https://www.example.com/api/v1/foo|~/foo.json
|https://www.example.com/api/v1/bar|~/bar.json

あとは検証したいJSONファイルで差し替えてあげれば、ローカルでエラーの再現ができるはずです。

mitmproxy コマンドを使う

上では mitmweb コマンドでWebインターフェースを利用しましたが、CUIだけで済ませたい場合は mitmproxy コマンドを使います。

$ mitmproxy -p 8888

このような画面が開かれます。基本的にキーボードのみで操作することになりますが、Vimライクなキーバインドで画面上を移動できるので、Vimユーザーの方は試してみてください。

Shift + o でオプションリストが開き、map_local を選択して Enter で設定の編集ができます。

書式は同じです。入力して設定すれば、ローカルファイルにマッピングできます。手間としては mitmweb とほぼ変わりませんが、ブラウザで開いたWebインターフェースをうっかり閉じてしまったり、タブ切り替えが煩わしく感じる場合は mitmproxy を使ってみてください。

おわりに

今回は限定されたケースに絞ったデバッグ手順を紹介しましたが、もちろんローカルプロキシが出来ることはそこに留まりません。

インターネットアクセスの状況がすべて記録されるため、通信周りのデバッグには欠かせないものです。また、例に挙げたようなローカル環境でのデバッグではなく、リモート環境でのデバッグも Map Local や Map Remote を利用して行うことができます。

ローカルプロキシは想像力次第で大きな力を発揮します。これを上手に活用し、サービスの価値向上に大いに役立てていきましょう。

Gaji-Labo フロントエンドエンジニア向けご案内資料

Gaji-Labo は Next.js 開発の実績と知見があります

フロントエンド開発の専門家である私たちが御社の開発チームに入ることで、バックエンドも含めた全体の開発効率が上がります。

「既存のサイトを Next.js に移行したい」
「人手が足りず信頼できるエンジニアを探している」
「自分たちで手を付けてみたがいまいち上手くいかない」

フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にご相談ください。

オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。

フロントエンドの相談をする!

投稿者 Oikawa Hisashi

フロントエンドエンジニア。モダンなJavaScript開発に関心があります。 デザインからバックエンドまで網羅的にこなすマルチデザイナーとして長く活動してきた経験を活かして、これから関わる様々なものをデザインしていきたいです。チームもコミュニケーションもデザインするもの。ライフワークはピアノと水泳。