Files
cpp-httplib/docs-src/pages/ja/cookbook/c16-proxy.md
T
yhirose 9bfd2ddf1c Fix README and docs pages that no longer match the code
Bring the READMEs and the docs pages (en and ja) in line with the
current header:

- Fix the client sample that does not compile, the Transfer-Encoding
  statement for default headers, the verifier callback comment, the
  thread pool spawn rule, the sanitize_filename description, and the
  inverted Accept-Encoding sentence.
- Describe recent behaviour: TLS errors behind Read/Write failures,
  Host validation, Connection: close for a body without length,
  content_reader rules, refused CONNECT, WebSocketClient proxies,
  CPPHTTPLIB_INTERIM_RESPONSE_MAX_COUNT, the SSE event size limit, and
  the payload limit of the Stream API.
- Complete the API references of WebSocket, WebSocketClient and the
  stream:: helpers, and the SSE reconnect rules.
- Fix cookbook pages: keychain loading on every backend, received Close
  status, a multipart sample that trusted the client's file name, an
  echo sample that sent binary as text, SNI, pre-request handler scope,
  stop() with WebSocket handlers, and the thread pool notes.
- Restore the mutex in the LLM app's Chapter 5 code.
2026-10-18 10:13:57 -04:00

4.9 KiB
Raw Blame History

title, order, status
title order status
C16. プロキシを経由してリクエストを送る 16 draft

社内ネットワークや特定の経路を通したい場合、HTTPプロキシを経由してリクエストを送れます。set_proxy()でプロキシのホストとポートを指定するだけです。

基本の使い方

httplib::Client cli("https://api.example.com");
cli.set_proxy("proxy.internal", 8080);

auto res = cli.Get("/users");

プロキシ経由でリクエストが送られます。HTTPSの場合はCONNECTメソッドでトンネルが張られるので、cpp-httplib側で特別な設定は要りません。

プロキシがトンネルを拒否すると、リクエストはError::ProxyConnectionで失敗します。ただし407だけは例外で、レスポンスとして返ってきます。resはtruthyでres->statusは407ですが、res.error()はError::ProxyConnectionのままです。

プロキシに認証を設定する

プロキシ自体が認証を要求する場合は、set_proxy_basic_auth()やset_proxy_bearer_token_auth()を使います。

cli.set_proxy("proxy.internal", 8080);
cli.set_proxy_basic_auth("user", "password");
cli.set_proxy_bearer_token_auth("token");

OpenSSL(または他のTLSバックエンド)付きでビルドしていれば、Digest認証も使えます。

cli.set_proxy_digest_auth("user", "password");

エンドのサーバー認証と組み合わせる

プロキシ認証と、エンドサーバーへの認証(C05. Basic認証を使うやC06. BearerトークンでAPIを呼ぶ)は別物です。両方が必要なら、両方設定します。

cli.set_proxy("proxy.internal", 8080);
cli.set_proxy_basic_auth("proxy-user", "proxy-pass");

cli.set_bearer_token_auth("api-token"); // エンドサーバー向け

プロキシにはProxy-Authorization、エンドサーバーにはAuthorizationヘッダーが送られます。

特定のホストだけプロキシをバイパスする

社内エンドポイントなどはプロキシを経由させたくないことがあります。set_no_proxy()で除外リストを指定できます。

cli.set_proxy("proxy.internal", 8080);
cli.set_no_proxy({"internal.corp", "10.0.0.0/8", ".dev.local"});

エントリは次のいずれかです。

  • * — すべてのホストでバイパス
  • ホスト名サフィックス(例: example.com)— example.com本体と任意のサブドメイン(foo.example.com)にマッチ。先頭にドットを付けても同じ意味です(.example.com)。
  • 単一のIPリテラル(例: 192.168.1.1、::1)
  • CIDRブロック(例: 10.0.0.0/8、fe80::/10)

ホスト名のマッチは大文字小文字を区別せず、ドット境界でしか一致しません。たとえばexample.comというエントリはevilexample.comにはマッチしません。IPの比較はinet_ptonで正規化されるので、127.0.0.1を127.000.000.001のような別表記でバイパスすることはできません。マッチした場合、Proxy-Authorizationヘッダーも自動的に外れます。

不正な書式のエントリは黙って捨てられます。example.com:8080のようなポート指定エントリはサポート外です(cpp-httplibの他のホストキーAPIもホスト名のみを扱う設計のため)。

WebSocketでもプロキシを使う

ws::WebSocketClientにも同じプロキシ設定があります。

httplib::ws::WebSocketClient cli("wss://ws.example.com/chat");
cli.set_proxy("proxy.internal", 8080);
cli.set_proxy_basic_auth("user", "password");

auto res = cli.connect();

ws://でもwss://でも、CONNECTメソッドでトンネルを張ってからWebSocketのハンドシェイクを行います。set_no_proxy()も同じように使えます。

環境変数からプロキシ設定を読み込む

cpp-httplib本体はHTTP_PROXY / HTTPS_PROXY / NO_PROXYを読みません。set_ca_cert_path()と同じで、設定APIは常に明示的にしています。環境変数を反映させたい場合は、アプリ側で読んでset_proxy()やset_no_proxy()に渡してください。

if (const char *v = std::getenv("no_proxy")) {
  std::vector<std::string> patterns;
  std::stringstream ss(v);
  for (std::string item; std::getline(ss, item, ',');) {
    if (!item.empty()) { patterns.push_back(item); }
  }
  cli.set_no_proxy(patterns);
}

HTTP_PROXYも自分で読むなら、小文字のhttp_proxyだけを採用してください。大文字の方はCGI/FastCGI環境でProxy:リクエストヘッダーから汚染される可能性があります(CVE-2016-5385 / "httpoxy")。HTTPS_PROXYとNO_PROXYは名前がHTTP_で始まらないので、どちらの大文字小文字でも安全です。