mitmproxy実践ガイド:インストールからAndroid・Expoの通信障害テストまで

Programming

この記事でわかること

mitmproxyとは何かから、インストール、mitmwebの使い方、HTTP 500や「応答なし」の再現、Android・Expoアプリの通信テストまでを一通りまとめます。特に後半は、実際のアプリ開発で「正常通信 → 500エラー → タイムアウト」を繰り返し確認するために試行錯誤した内容です。

Webアプリやスマホアプリを作っていると、正常系だけでなく「サーバーが500を返した」「通信が途中で切れた」「いつまで待ってもレスポンスが返らない」といった異常系も確認する必要があります。

ところが、実際のサーバーをわざと壊してテストするのは面倒です。そこで便利なのが mitmproxy です。

mitmproxyとは

mitmproxyは、クライアントとサーバーの間に入ってHTTP/HTTPS通信を確認・変更できるオープンソースのインターセプティングプロキシです。HTTP/1、HTTP/2、WebSocketなどを扱え、リクエストやレスポンスの確認、変更、保存、リプレイ、Pythonによる自動処理などができます。

mitmproxy

ターミナル上で対話的に通信を確認・操作するUI。

mitmweb

ブラウザから操作できるGUI。初めて使う場合はこちらが分かりやすい。

mitmdump

非対話型のCLI。スクリプトや自動テストとの組み合わせに向く。

公式ドキュメント:mitmproxy Documentation

インストール方法

公式では、Windowsはインストーラー、macOSはHomebrew、Linuxは公式のスタンドアロンバイナリが推奨されています。Python環境から入れる場合は現在は uv を使う方法も案内されています。

Windows

公式サイトからWindows Installerを取得してインストールします。インストール後はPowerShellやWindows Terminalから mitmproxymitmwebmitmdump を起動できます。

macOS

brew install --cask mitmproxy

Linux

Linuxでは公式スタンドアロンバイナリが推奨です。Ubuntuなどのディストリビューションにもパッケージがある場合がありますが、公式ではディストリビューション側のパッケージは最新版より遅れる場合があると説明されています。

Python環境に入れる場合

uv tool install mitmproxy

公式インストールガイド:Installation

まずはmitmwebを起動する

最初はブラウザGUIの mitmweb が扱いやすいです。

mitmweb

通常のプロキシはデフォルトで localhost:8080 を待ち受けます。テスト対象のブラウザや端末でHTTPプロキシをmitmproxyが動いているPCへ向けると、通信がFlowとして表示されます。

HTTPSを見るには証明書が必要

HTTPS通信を復号して確認するには、テスト端末側でmitmproxyのCA証明書を信頼させる必要があります。プロキシ設定後に端末のブラウザから mitm.it を開くと、OSごとの証明書インストール画面を利用できます。

通信を見るだけでなく「壊す」のが便利

mitmproxyの面白いところはパケットキャプチャだけではありません。アプリとAPIの間に入って、意図的に異常なレスポンスを返せます。これにより、バックエンドを変更せずにフロント側のエラーハンドリングを確認できます。

テストしたい状態mitmproxyでの考え方確認ポイント
HTTP 500固定ステータスを返すサーバーエラー表示・リトライ
404 / 403block_list等でステータスを返すエラー種別ごとのUI
応答なし444またはFlowをDropタイムアウト・ネットワークエラー
遅い通信スクリプト等で遅延Loading表示・二重送信防止

block_listで特定APIだけを止める

block_list は、条件に一致するリクエストに固定のHTTPステータスを返す機能です。書式は概ね次の形です。

/flow-filter/status-code

例えば特定ドメインへの通信に404を返したり、特定URLだけを対象に500相当のテストを行えます。公式には特殊なステータス 444 を指定すると、HTTPレスポンスを送らず接続を閉じる動作になります。

:~d example.com$:444

これは「サーバーからエラーレスポンスが返った」状態とは違い、そもそも正常なHTTPレスポンスが返ってこない状態を再現するのに便利です。

公式:mitmproxy Features – Blocklist

実際にAndroid・Expoアプリのテストで使ってみた

私の場合は、React Native / Expoで作っているスマホアプリからFlask APIへアクセスする構成で、APIエラー時の表示を確認するためにmitmproxyを使いました。

Android実機
    ↓
mitmproxy / mitmweb
    ↓
Flask API
    ↓
MySQL / Redis

開発環境ではDocker ComposeでAPI、DB、Redis、Mailhogなどを起動しています。ここへmitmproxyを追加すると、アプリ側のコードを変えずに通信条件を切り替えられます。

テストしたかったこと

正常通信では通常どおり画面を表示し、HTTP 500ではサーバーエラーの案内を出し、応答なしではタイムアウトとして扱う。この3種類を何度も切り替えてReact Queryや独自fetch処理の挙動を確認するのが目的でした。

実際にハマったポイント

1. 8081ポートがExpoと競合した

Expoの開発サーバーとmitmweb側で使いたいポートが重なり、起動時に競合しました。開発環境では「何番を誰が使うか」を先に決めておくのが重要です。私の場合はExpo側を8082へずらすなどして整理しました。

2. DropとHTTPエラーは別物

mitmwebでFlowを Drop すると、HTTP 500のようなレスポンスが返るわけではありません。通信自体が成立しない方向のテストになります。「500を受け取った場合」と「レスポンスが来ない場合」はアプリ側でも別のエラーになるため、分けてテストする必要があります。

3. 444はHTTPステータス444をアプリへ返す意味ではない

ここは最初に混乱しやすいところでした。mitmproxyの 444 は特殊値で、通常のHTTPレスポンスとして「Status 444」を返すためのものではなく、接続を閉じてレスポンスを返さないための指定です。通信不能やタイムアウト系を確認したいときに使います。

4. 毎回Optionsを書き換えるのが面倒

正常系と異常系を何度も往復していると、毎回 block_list を設定・削除する作業が面倒になります。ここまで来ると、Python addonなどを使って「エラーON/OFF」を切り替えられる仕組みにした方がテスト効率は上がります。

実運用でおすすめのテスト順

①正常通信 → ②HTTP 500 → ③404/403 → ④応答なし → ⑤遅延 の順に確認すると、エラーの種類とアプリ側の表示を対応付けやすくなります。特にReact Queryのretryを設定している場合は「1回の失敗」が実際には複数回のAPIアクセスになるため、mitmwebのFlowを見ると挙動を理解しやすくなります。

Dockerで使う場合の考え方

バックエンド自体がDocker Compose内にある場合、mitmproxyもコンテナとして組み込む方法があります。そうすると開発環境を立ち上げるだけでAPI・DB・Mailhog・mitmproxyをまとめて用意できます。

Android / Browser
       ↓
    mitmproxy
       ↓
   api:5000
       ↓
 MySQL / Redis

ただしDocker内のサービス名、ホスト側のポート、Android実機から見たアドレスはそれぞれ別物です。localhost が「どのマシンのlocalhostなのか」を意識して構成する必要があります。

mitmproxyが特に便利な場面

単にAPIの内容を見るだけならブラウザのDevToolsでも十分な場合があります。しかし、スマホ実機の通信を見る、レスポンスを書き換える、特定APIだけ500にする、接続を途中で切る、同じ通信を再現するといった用途ではmitmproxyが非常に便利です。

目的DevToolsmitmproxy
ブラウザ通信を見る
スマホ実機の通信を見る
レスポンス改変
通信障害の再現
Pythonで自動制御×

まとめ

mitmproxyは「通信を見るツール」というより、通信を自由に観察・変更して、アプリの異常系を作り出せるテストツールとして使うと価値が分かりやすいです。

特にスマホアプリでは、実際の通信断やサーバー障害を毎回用意するのは大変です。mitmproxyを間に置けば、正常系・500・応答なしなどを意図的に作り、エラー表示、リトライ、タイムアウト、ローディング処理を繰り返し確認できます。

最初はmitmwebでFlowを眺めるところから始め、慣れてきたら block_list、レスポンス編集、Python addonによるON/OFF制御へ進むのがおすすめです。


参考:mitmproxy公式ドキュメント。記事中の開発環境・トラブル事例は、実際のAndroid / Expoアプリ開発時に行った検証をもとに整理しています。アイキャッチ写真:Jefferson Santos / Unsplash.

タイトルとURLをコピーしました