HTTP経由の大容量ファイルをApiCatcherがキャプチャする仕組み

HTTP経由の大容量ファイルをApiCatcherがキャプチャする仕組み

iOS向けのHTTPSパケットキャプチャツールを多数試してきましたが、静的リソースファイルのキャプチャに対応しているものはなく、リクエストやレスポンスのボディが一定サイズを超えると単に破棄されてしまいます。ファイルアップロードの権限問題を調査するために、リクエストの完全なURLをキャプチャしてドメインやプロジェクトを特定したいと思っても、それすらできませんでした。

ApiCatcherの開発過程で初めて知ったのですが、iOSはネットワーク拡張(Network Extension)プロセスにメモリ制限を課しています。各種資料によると、システムはネットワーク拡張プロセスに対し最大約50MBのメモリしか許容せず、これを超えるとプロセスが強制終了されます。ただし、この閾値はOSバージョンによって異なる可能性があり、実際のテストでは約80MBまで正常に動作しました。

このメモリ制限のため、多くのキャプチャツールは独自のパケット破棄戦略を実装し、ボディサイズが一定を超えたリクエストを破棄しています。

ではApiCatcherはこの問題をどのように解決したのでしょうか?

静的リソースファイルに対しては、通常ボディの書き換えやスクリプトによる変更が必要になることはありません。そのため、リクエストやレスポンスのボディをメモリ上にバッファリングする必要はなく、代わりに直接ファイルに書き込みます。受信バッファから読み取ったバイトデータをそのままディスクに書き出し、メモリ上には保持しません。

もう一つ重要なポイントは、大きなHTTPペイロードはTCP層で断片化されることです。1MBのファイル転送であっても、TCPセグメントは最大64KB程度です。各セグメントを到着次第ディスクに書き込むことで、同時に消費するメモリはわずか64KBであり、1MB全体を保持する必要はありません。リクエストまたはレスポンスが完了したら、データベースのレコードにはファイルパスのみを保存します。

この方式のトレードオフとして、ユーザーがリクエストレコードを削除する際に、対応するボディファイルを特定して削除する必要があり、データの整合性を自前で管理しなければなりません。これがApiCatcherのデータ削除がやや遅い理由です。しかし、削除操作は頻繁に行われるものではなく、1万件程度のデータであれば約5秒で完了するため、このトレードオフは十分に価値があると考えています。

大容量ファイルのキャプチャに対応した上で、ApiCatcherはさらに、画像・動画・音声をアプリ内で直接レンダリングし、ワンタップで再生できます。また、プレビューと一括書き出し専用の画面も用意しており、テスト素材の抽出とエクスポートが容易です。

iOS、Windows、macOSのすべてのプラットフォームで同じストリーミング書き込み方式を採用しています。デスクトップ版にはメモリ制限がないものの、この設計により全プラットフォームで優れたパフォーマンスを実現しています。

ApiCatcher for iOS のスクリーンショット: ApiCatcher for iOS | Capture Images/Videos/Audio

ApiCatcher for macOS のスクリーンショット: ApiCatcher for macOS | Capture Images/Videos/Audio