【ITニュース解説】HTTP entre pares
2026年10月29日に「Dev.to」が公開したITニュース「HTTP entre pares」について初心者にもわかりやすく解説しています。
ITニュース概要
P2PネットワークでHTTP通信を実現する技術だ。公開IP不要でNAT越えも可能。libp2pストリームを使い、ピアIDで相手を見つけHTTPリクエストを送受信する。既存HTTPクライアントからP2P上のサービスが利用できる。
ITニュース解説
私たちが普段インターネットでウェブサイトを閲覧するときに使っている「HTTP(Hypertext Transfer Protocol)」は、ウェブサーバーとクライアント(ブラウザなど)の間で情報をやり取りするための重要な通信規約である。しかし、このHTTP通信には一つの課題があった。それは、通常、サーバーはインターネット上に公開された「固定の住所」を持っている必要があるという点である。家庭や会社で使われている多くのコンピューターは「NAT(Network Address Translation)」と呼ばれる仕組みのルーターの内側にあり、直接インターネットからアクセスできる固定の住所を持っていない。そのため、これらのコンピューターがサーバーとしてインターネットにサービスを提供しようとすると、ルーターの特別な設定(ポート開放など)が必要になったり、インターネット上に公開された別のサーバーを借りて中継点にする必要があったりして、設定が複雑になったり、コストがかかったりする問題が生じていた。
このような問題を解決する技術の一つが、「P2P(Peer-to-Peer、ピアツーピア)」ネットワークの基盤となる「libp2p(ライブラリP2P)」である。P2Pネットワークでは、各コンピューターが対等な「ピア(peer)」として互いに直接通信し合う。この技術を使えば、従来のHTTPが抱えていた「固定の住所」問題やNAT越えの課題を解決し、ルーターの内側にあるコンピューター同士でも直接HTTP通信ができるようになる。
この仕組みの提案は、HTTPリクエストとレスポンスという、私たちが普段使っているHTTPの情報をそのままlibp2pが提供する「ストリーム」という通信路に乗せて運ぶというものである。ここで重要な役割を果たすのが「PeerId(ピアID)」である。PeerIdは、各ピアを一意に識別するためのIDで、インターネット上のIPアドレスのように固定された住所ではない。通信したい相手のPeerIdさえわかっていれば、libp2pはネットワークの複雑さを吸収して、その相手との間でストリームを確立できる。この方式では、HTTPの「メソッド(GETやPOSTなど)」、「URL(Uniform Resource Locator)のパス」、「ヘッダー(付加情報)」、「ボディ(実際のデータ)」といった内容は、通常のHTTPと全く同じ形式を保つため、HTTPそのものを変更する必要がない。
具体的な通信の流れは次のようになる。まず、HTTP通信を開始したいピア(クライアント側)が、相手のピアのPeerIdを使って接続を試みる。接続が成功すると、libp2pのストリームが開かれる。クライアントはこのストリームを通じて、通常のHTTPリクエストを送信する。相手のピア(サーバー側)は、このストリームからHTTPリクエストを受け取り、それを自身のアプリケーションで処理するか、または同じコンピューター上にある別の一般的なHTTPサーバー(localhost)に転送して処理させる。処理が完了すると、サーバー側はHTTPのステータスコード、ヘッダー、ボディを含むレスポンスをストリームを通じてクライアントに返す。これにより、外部から見ると、リモートのピアがまるで通常のHTTPサーバーであるかのように振る舞っているように見える。しかし、ネットワークの観点からは、この通信はlibp2pの「/http」というプロトコルを通じて行われており、同じホスト上で他のP2Pプロトコル(例えば、BitswapやKademliaといったデータ交換やピア探索のプロトコル)と共存している。
クライアントが相手のピアと通信するためには、そのピアのPeerIdだけでなく、ネットワーク上の「アドレス」も知っている必要がある。もしクライアントがすでに相手のアドレス情報(multiaddrsと呼ばれる、複数のネットワークアドレス形式を表現できるフォーマット)を持っていれば、それを利用して直接接続を試みる。しかし、もしアドレスが不明な場合でも、「DHT(Distributed Hash Table、分散ハッシュテーブル)」という仕組みが活躍する。DHTはP2Pネットワーク全体に分散して情報を保持するデータベースのようなもので、Kademliaプロトコルを使ってPeerIdからそのピアのアドレス情報を効率的に探し出すことができる。
さらに、既存のウェブブラウザやHTTPクライアントのような、P2Pの知識を持たない一般的なアプリケーションからでも、このP2P HTTPを利用できるようにするための「ローカルプロキシ」という仕組みも存在する。このプロキシは、同じコンピューター上で動作し、アプリケーションからのHTTPリクエストを受け取る。例えば、アプリケーションが「/p2p/<peerid>/http/<path>」のような特別な形式のURLにアクセスすると、プロキシはそのURLからPeerIdを抽出し、そのPeerIdを持つピアに対してlibp2p経由でHTTPリクエストを転送する。これにより、アプリケーションは「127.0.0.1(自分のコンピューター)」と通信している感覚で、裏側ではP2Pネットワークを介したHTTP通信を行えるようになる。
このP2P HTTPの実装例として、「Nabu(ナブー)」というプロジェクトがある。Nabuでは、「HttpProtocol.java」というファイルで「/http」というプロトコル識別子を登録している。これにより、Nabuは特定のPeerIdからの/httpプロトコルによる通信を認識し、処理できるようになる。Nabuの内部では、受信したHTTPリクエストを特定のソケットアドレスに転送する機能や、アプリケーションが直接リクエストを処理するための「HttpRequestProcessor」という機能を提供している。この実装では、一度に処理できるHTTPボディの最大サイズが8MiB(メガバイト)に制限されているが、これは一時的なもので、将来的にはより大きなデータを扱えるように改善される予定である。
NabuのP2P HTTPプロキシ機能は、設定ファイルにAddresses.ProxyTargetが指定されている場合に有効になる。この場合、Nabuプロセス自体がHTTPプロキシハンドラーとして機能し、「/p2p/<target_node_id>/http/<target_path>」形式のURLを処理する。プロキシは、指定されたtarget_node_id(PeerId)のアドレスをまず自身のピアリスト(caderno)で確認し、見つからなければDHTに問い合わせて、そのピアのアドレスを探し出す。この際、DHTへの問い合わせでは、キャッシュされた古いアドレスではなく、最新のアドレス情報を強制的に取得するように設定される。これにより、ピアがネットワーク上で移動した場合でも、古いアドレスに接続し続けてしまうことを防ぐ。
libp2pの通信路を多重化する「yamux」という仕組みには、データ転送を一時的に保持するバッファが割り当てられている。このP2P HTTPでの最大ボディサイズ8MiBを安全に扱うため、Nabuではこのyamuxのバッファサイズが128MiBに拡張されている。もしバッファが小さすぎると、複数のHTTPレスポンスが同時に送られてきた場合にバッファが溢れ、通信が途切れてしまう可能性があるためである。
このP2P HTTPの具体的な利用例として、「nabu-chat」というシンプルなチャットアプリケーションがある。このアプリケーションでは、ユーザーがチャットメッセージをPeerId経由で交換する。各チャットメッセージは、P2P HTTPのストリーム上で「POST /」というHTTPリクエストとして送信され、受信側のピアはそのリクエストを受け取ってメッセージを表示する。これは、HTTPプロトコルが単にウェブページをやり取りするだけでなく、P2Pネットワーク上で様々なアプリケーションのデータ交換にも応用できる可能性を示している。
ただし、この/httpプロトコルは、IPFS(InterPlanetary File System)のような分散ストレージネットワークのコンテンツを直接取得する「IPFSゲートウェイ」とは異なる点に注意が必要である。IPFSゲートウェイは「CID(Content Identifier)」や「IPNS(InterPlanetary Name System)」を使ってコンテンツを解決するが、/httpプロトコルはあくまで二つのピア間でHTTPデータを「そのまま」運ぶことを目的としている。また、現在の実装ではボディサイズの8MiBという制限があるため、これを超えるような非常に大きなファイルの転送には、別の設計が必要となる。
このように、libp2pとHTTPを組み合わせることで、従来のインターネットの制限を超え、より柔軟で直接的なピアツーピア通信が可能になる。これは、新しい種類の分散アプリケーションや、インターネットの通信インフラの進化に大きな可能性を秘めている。