mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
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.
104 lines
4.9 KiB
Markdown
104 lines
4.9 KiB
Markdown
---
|
||
title: "C16. プロキシを経由してリクエストを送る"
|
||
order: 16
|
||
status: "draft"
|
||
---
|
||
|
||
社内ネットワークや特定の経路を通したい場合、HTTPプロキシを経由してリクエストを送れます。`set_proxy()`でプロキシのホストとポートを指定するだけです。
|
||
|
||
## 基本の使い方
|
||
|
||
```cpp
|
||
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()`を使います。
|
||
|
||
```cpp
|
||
cli.set_proxy("proxy.internal", 8080);
|
||
cli.set_proxy_basic_auth("user", "password");
|
||
```
|
||
|
||
```cpp
|
||
cli.set_proxy_bearer_token_auth("token");
|
||
```
|
||
|
||
OpenSSL(または他のTLSバックエンド)付きでビルドしていれば、Digest認証も使えます。
|
||
|
||
```cpp
|
||
cli.set_proxy_digest_auth("user", "password");
|
||
```
|
||
|
||
## エンドのサーバー認証と組み合わせる
|
||
|
||
プロキシ認証と、エンドサーバーへの認証([C05. Basic認証を使う](../c05-basic-auth)や[C06. BearerトークンでAPIを呼ぶ](../c06-bearer-token))は別物です。両方が必要なら、両方設定します。
|
||
|
||
```cpp
|
||
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()`で除外リストを指定できます。
|
||
|
||
```cpp
|
||
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`にも同じプロキシ設定があります。
|
||
|
||
```cpp
|
||
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()`に渡してください。
|
||
|
||
```cpp
|
||
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://httpoxy.org/))。`HTTPS_PROXY`と`NO_PROXY`は名前が`HTTP_`で始まらないので、どちらの大文字小文字でも安全です。
|