Files
cpp-httplib/docs-src/pages/ja/cookbook/c18-ssl-errors.md
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

60 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "C18. SSLエラーをハンドリングする"
order: 18
status: "draft"
---
HTTPSリクエストで失敗したとき、`res.error()`は`Error::SSLConnection`や`Error::SSLServerVerification`といった値を返します。ただ、これだけだと原因の切り分けが難しいこともあります。そんなときは`Result::ssl_error()`と`Result::ssl_backend_error()`が役に立ちます。
## SSLエラーの詳細を取得する
```cpp
httplib::Client cli("https://api.example.com");
auto res = cli.Get("/");
if (!res) {
auto err = res.error();
std::cerr << "error: " << httplib::to_string(err) << std::endl;
if (err == httplib::Error::SSLConnection ||
err == httplib::Error::SSLServerVerification ||
err == httplib::Error::Read || err == httplib::Error::Write) {
std::cerr << "ssl_error: " << res.ssl_error() << std::endl;
std::cerr << "ssl_backend_error: " << res.ssl_backend_error() << std::endl;
}
}
```
`ssl_error()`は、どのTLSバックエンドでも共通のエラー種別(`httplib::tls::ErrorCode`)を`int`で返します。`ssl_backend_error()`は、バックエンドが返したエラー値そのものです。OpenSSLなら、ハンドシェイクやその後の読み書きの失敗では`ERR_get_error()`の値が、証明書検証の失敗では検証結果のコード(`X509_V_ERR_*`)が入ります。
ハンドシェイクのあとで失敗したリクエストは、`Error::Read`や`Error::Write`を返します。その場合も、`ssl_error()`と`ssl_backend_error()`には原因となったTLSのエラーが入ります。たとえば、サーバーが要求するクライアント証明書を送らなかった場合、OpenSSLのエラーは「tlsv13 alert certificate required」になります。どちらの値もリクエストごとにリセットされ、TLSのエラーが絡んでいなければ`0`です。
## OpenSSLのエラーを文字列化する
`ssl_backend_error()`の値は、OpenSSLの関数で文字列にしておくとデバッグに便利です。使う関数は失敗の種類によって変わります。
```cpp
#include <openssl/err.h>
#include <openssl/x509.h>
if (res.error() == httplib::Error::SSLConnection) {
char buf[256];
ERR_error_string_n(res.ssl_backend_error(), buf, sizeof(buf));
std::cerr << "openssl: " << buf << std::endl;
} else if (res.error() == httplib::Error::SSLServerVerification ||
res.error() == httplib::Error::SSLServerHostnameVerification) {
auto code = static_cast<long>(res.ssl_backend_error());
std::cerr << "openssl: " << X509_verify_cert_error_string(code) << std::endl;
}
```
## よくある原因
| 症状 | ありがちな原因 |
| --- | --- |
| `SSLServerVerification` | CA証明書のパスが通っていない、自己署名証明書 |
| `SSLServerHostnameVerification` | 証明書のCN/SANとホスト名が一致しない |
| `SSLConnection` | TLSバージョンの不一致、対応スイートが無い |
> 証明書の検証設定を変えたい場合は[T02. SSL証明書の検証を制御する](../t02-cert-verification)を参照してください。