mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-04-12 03:38:30 +00:00
Documentation Site on GitHub Pages (#2376)
* Add initial documentations * Update documentation for Basic Client and add WebSocket section * feat: add a static site generator with multi-language support - Introduced a new Rust-based static site generator in the `docs-gen` directory. - Implemented core functionality for building sites from markdown files, including: - Configuration loading from `config.toml`. - Markdown rendering with frontmatter support. - Navigation generation based on page structure. - Static file copying and output directory management. - Added templates for base layout, pages, and portal. - Created a CSS file for styling and a JavaScript file for interactive features like language selection and theme toggling. - Updated documentation source with new configuration and example pages in English and Japanese. - Added a `justfile` target for building the documentation site. * Add language/theme toggle functionality - Created a new Japanese tour index page at docs/ja/tour/index.html - Implemented navigation links for various sections of the cpp-httplib tutorial - Added a language selector to switch between English and Japanese - Introduced theme toggle functionality to switch between light and dark modes - Added mobile sidebar toggle for better navigation on smaller screens
This commit is contained in:
73
docs/ja/cookbook/index.html
Normal file
73
docs/ja/cookbook/index.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Cookbook - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/cookbook/" class="nav-section-title active">Cookbook</a>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Cookbook</h1>
|
||||
<p>This section is under construction.</p>
|
||||
<p>Check back soon for a collection of recipes organized by topic.</p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
72
docs/ja/index.html
Normal file
72
docs/ja/index.html
Normal file
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>cpp-httplib - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout no-sidebar">
|
||||
|
||||
<main class="content portal">
|
||||
<article>
|
||||
<h1>cpp-httplib</h1>
|
||||
<p><a href="https://github.com/yhirose/cpp-httplib">cpp-httplib</a>は、C++用のHTTP/HTTPSライブラリです。<a href="https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h"><code>httplib.h</code></a> というヘッダーファイルを1枚コピーするだけで使えます。</p>
|
||||
<p>C++でちょっとしたHTTPサーバーやクライアントが必要になったとき、すぐに動くものが欲しいですよね。cpp-httplibはまさにそのために作られました。サーバーもクライアントも、数行のコードで書き始められます。</p>
|
||||
<p>APIはラムダ式をベースにした直感的な設計で、C++11以降のコンパイラーがあればどこでも動きます。Windows、macOS、Linux — お使いの環境をそのまま使えます。</p>
|
||||
<p>HTTPSも使えます。OpenSSLやmbedTLSをリンクするだけで、サーバー・クライアントの両方がTLSに対応します。Content-Encoding(gzip, brotli等)、ファイルアップロードなど、実際の開発で必要になる機能もひと通り揃っています。WebSocketもサポートしています。</p>
|
||||
<p>内部的にはブロッキングI/Oとスレッドプールを使っています。大量の同時接続を捌くような用途には向きませんが、APIサーバーやツールの組み込みHTTP、テスト用のモックサーバーなど、多くのユースケースで十分な性能を発揮します。</p>
|
||||
<p>「今日の課題を、今日中に解決する」— cpp-httplibが目指しているのは、そういうシンプルさです。</p>
|
||||
<h2>ドキュメント</h2>
|
||||
<ul>
|
||||
<li><a href="tour/">A Tour of cpp-httplib</a> — 基本を順を追って学べるチュートリアル。初めての方はここから</li>
|
||||
<li><a href="cookbook/">Cookbook</a> — 目的別のレシピ集。必要なトピックから読めます</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
198
docs/ja/tour/01-getting-started/index.html
Normal file
198
docs/ja/tour/01-getting-started/index.html
Normal file
@@ -0,0 +1,198 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Getting Started - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="active">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Getting Started</h1>
|
||||
<p>cpp-httplibを始めるのに必要なのは、<code>httplib.h</code>とC++コンパイラーだけです。ファイルをダウンロードして、Hello Worldサーバーを動かすところまでやってみましょう。</p>
|
||||
<h2>httplib.h の入手</h2>
|
||||
<p>GitHubから直接ダウンロードできます。常に最新版を使ってください。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -LO</span><span style="color:#d3d0c8;"> https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -LO</span><span style="color:#4f5b66;"> https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>ダウンロードした <code>httplib.h</code> をプロジェクトのディレクトリに置けば、準備完了です。</p>
|
||||
<h2>コンパイラーの準備</h2>
|
||||
<table><thead><tr><th>OS</th><th>開発環境</th><th>セットアップ</th></tr></thead><tbody>
|
||||
<tr><td>macOS</td><td>Apple Clang</td><td>Xcode Command Line Tools (<code>xcode-select --install</code>)</td></tr>
|
||||
<tr><td>Ubuntu</td><td>clang++ または g++</td><td><code>apt install clang</code> または <code>apt install g++</code></td></tr>
|
||||
<tr><td>Windows</td><td>MSVC</td><td>Visual Studio 2022 以降(C++ コンポーネントを含めてインストール)</td></tr>
|
||||
</tbody></table>
|
||||
<h2>Hello World サーバー</h2>
|
||||
<p>次のコードを <code>server.cpp</code> として保存しましょう。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request&, httplib::Response& res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello, World!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request&, httplib::Response& res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello, World!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>たった数行で、HTTPリクエストに応答するサーバーが書けます。</p>
|
||||
<h2>コンパイルと実行</h2>
|
||||
<p>このチュートリアルのサンプルコードは、コードを簡潔に書けるC++17で書いています。cpp-httplib自体はC++11でもコンパイルできます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;"># macOS
|
||||
</span><span style="color:#6699cc;">clang++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -o</span><span style="color:#d3d0c8;"> server server.cpp
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Linux
|
||||
</span><span style="color:#747369;"># `-pthread`: cpp-httplibは内部でスレッドを使用
|
||||
</span><span style="color:#6699cc;">clang++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -pthread -o</span><span style="color:#d3d0c8;"> server server.cpp
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#747369;"># `/EHsc`: C++例外処理を有効化
|
||||
</span><span style="color:#6699cc;">cl</span><span style="color:#d3d0c8;"> /EHsc /std:c++17 server.cpp
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;"># macOS
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#4f5b66;">=c++17</span><span style="color:#bf616a;"> -o</span><span style="color:#4f5b66;"> server server.cpp
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;"># Linux
|
||||
</span><span style="color:#a7adba;"># `-pthread`: cpp-httplibは内部でスレッドを使用
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#4f5b66;">=c++17</span><span style="color:#bf616a;"> -pthread -o</span><span style="color:#4f5b66;"> server server.cpp
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#a7adba;"># `/EHsc`: C++例外処理を有効化
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#4f5b66;"> /EHsc /std:c++17 server.cpp
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>コンパイルできたら実行します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;"># macOS / Linux
|
||||
</span><span style="color:#6699cc;">./server
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Windows
|
||||
</span><span style="color:#6699cc;">server.exe
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;"># macOS / Linux
|
||||
</span><span style="color:#8fa1b3;">./server
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;"># Windows
|
||||
</span><span style="color:#8fa1b3;">server.exe
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>ブラウザで <code>http://localhost:8080</code> を開いてください。"Hello, World!" と表示されれば成功です。</p>
|
||||
<p><code>curl</code> でも確認できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080/
|
||||
</span><span style="color:#747369;"># Hello, World!
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> http://localhost:8080/
|
||||
</span><span style="color:#a7adba;"># Hello, World!
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>サーバーを停止するには、ターミナルで <code>Ctrl+C</code> を押します。</p>
|
||||
<h2>次のステップ</h2>
|
||||
<p>サーバーの基本がわかりましたね。次は、クライアント側を見てみましょう。cpp-httplibはHTTPクライアント機能も備えています。</p>
|
||||
<p><strong>次:</strong> <a href="../02-basic-client">Basic Client</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
491
docs/ja/tour/02-basic-client/index.html
Normal file
491
docs/ja/tour/02-basic-client/index.html
Normal file
@@ -0,0 +1,491 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Basic Client - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="active">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Basic Client</h1>
|
||||
<p>cpp-httplibはサーバーだけでなく、HTTPクライアント機能も備えています。<code>httplib::Client</code> を使って、GETやPOSTリクエストを送ってみましょう。</p>
|
||||
<h2>テスト用サーバーの準備</h2>
|
||||
<p>クライアントの動作を確認するために、リクエストを受け付けるサーバーを用意します。次のコードを保存し、前章と同じ手順でコンパイル・実行してください。サーバーの詳しい解説は次章で行います。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/search</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> q = req.</span><span style="color:#6699cc;">get_param_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">q</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Query: </span><span style="color:#d3d0c8;">" + q, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(req.</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/submit</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> std::string result;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">for </span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&[key, val] : req.</span><span style="color:#f2777a;">params</span><span style="color:#d3d0c8;">) {
|
||||
</span><span style="color:#d3d0c8;"> result += key + "</span><span style="color:#99cc99;"> = </span><span style="color:#d3d0c8;">" + val + "</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">";
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(result, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> f = req.</span><span style="color:#f2777a;">form</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">get_file</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> content = f.</span><span style="color:#f2777a;">filename </span><span style="color:#d3d0c8;">+ "</span><span style="color:#99cc99;"> (</span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::to_string</span><span style="color:#d3d0c8;">(f.</span><span style="color:#f2777a;">content</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()) + "</span><span style="color:#99cc99;"> bytes)</span><span style="color:#d3d0c8;">";
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(content, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/users/:id</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">id</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">User ID: </span><span style="color:#d3d0c8;">" + id, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">"(</span><span style="color:#99cc99;">/files/(\d+)</span><span style="color:#d3d0c8;">)", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">matches</span><span style="color:#d3d0c8;">[</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">];
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">File ID: </span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">(id), "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Listening on port 8080...</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">q</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#4f5b66;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> std::string result;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">for </span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#4f5b66;">) {
|
||||
</span><span style="color:#4f5b66;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#4f5b66;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#4f5b66;">";
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#4f5b66;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#4f5b66;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#4f5b66;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#4f5b66;">";
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">id</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#4f5b66;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">R</span><span style="color:#4f5b66;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#4f5b66;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#4f5b66;">[</span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">];
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#4f5b66;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#4f5b66;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#4f5b66;">" << std::endl;
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>GETリクエスト</h2>
|
||||
<p>サーバーが起動したら、別のターミナルを開いて試してみましょう。まず、最もシンプルなGETリクエストです。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:8080</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Hello!
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// 200
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// Hello!
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>httplib::Client</code> のコンストラクターにサーバーのアドレスを渡し、<code>Get()</code> でリクエストを送ります。戻り値の <code>res</code> からステータスコードやボディを取得できます。</p>
|
||||
<p>対応する <code>curl</code> コマンドはこうなります。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080/hi
|
||||
</span><span style="color:#747369;"># Hello!
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> http://localhost:8080/hi
|
||||
</span><span style="color:#a7adba;"># Hello!
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>レスポンスの確認</h2>
|
||||
<p>レスポンスには、ステータスコードとボディ以外にもヘッダー情報が含まれています。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// ステータスコード
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// ボディ
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Hello!
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// ヘッダー
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#6699cc;">get_header_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Content-Type</span><span style="color:#d3d0c8;">") << std::endl; </span><span style="color:#747369;">// text/plain
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// ステータスコード
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// 200
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// ボディ
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// Hello!
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// ヘッダー
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Content-Type</span><span style="color:#4f5b66;">") << std::endl; </span><span style="color:#a7adba;">// text/plain
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>res->body</code> は <code>std::string</code> なので、JSON レスポンスをパースしたい場合は <a href="https://github.com/nlohmann/json">nlohmann/json</a> などの JSON ライブラリにそのまま渡せます。</p>
|
||||
<h2>クエリパラメーター</h2>
|
||||
<p>GETリクエストにクエリパラメーターを付けるには、URLに直接書くか、<code>httplib::Params</code> を使います。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/search</span><span style="color:#d3d0c8;">", httplib::Params{{"</span><span style="color:#99cc99;">q</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">cpp-httplib</span><span style="color:#d3d0c8;">"}});
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Query: cpp-httplib
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#4f5b66;">", httplib::Params{{"</span><span style="color:#a3be8c;">q</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">cpp-httplib</span><span style="color:#4f5b66;">"}});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// Query: cpp-httplib
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>httplib::Params</code> を使うと、特殊文字のURLエンコードを自動で行ってくれます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">http://localhost:8080/search?q=cpp-httplib</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#747369;"># Query: cpp-httplib
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">http://localhost:8080/search?q=cpp-httplib</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#a7adba;"># Query: cpp-httplib
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>パスパラメーター</h2>
|
||||
<p>URLのパスに値を直接埋め込む場合も、クライアント側は特別なAPIは不要です。パスをそのまま <code>Get()</code> に渡すだけです。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/users/42</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// User ID: 42
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/users/42</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// User ID: 42
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080/users/42
|
||||
</span><span style="color:#747369;"># User ID: 42
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> http://localhost:8080/users/42
|
||||
</span><span style="color:#a7adba;"># User ID: 42
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>テスト用サーバーには、正規表現でIDを数字のみに絞った <code>/files/(\d+)</code> もあります。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/files/42</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// File ID: 42
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/files/42</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// File ID: 42
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080/files/42
|
||||
</span><span style="color:#747369;"># File ID: 42
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> http://localhost:8080/files/42
|
||||
</span><span style="color:#a7adba;"># File ID: 42
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>/files/abc</code> のように数字以外を渡すと404が返ります。仕組みは次章で解説します。</p>
|
||||
<h2>リクエストヘッダー</h2>
|
||||
<p>カスタムHTTPヘッダーを付けるには、<code>httplib::Headers</code> を渡します。<code>Get()</code> や <code>Post()</code> のどちらでも使えます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">", httplib::Headers{
|
||||
</span><span style="color:#d3d0c8;"> {"</span><span style="color:#99cc99;">Authorization</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">Bearer my-token</span><span style="color:#d3d0c8;">"}
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">", httplib::Headers{
|
||||
</span><span style="color:#4f5b66;"> {"</span><span style="color:#a3be8c;">Authorization</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">Bearer my-token</span><span style="color:#4f5b66;">"}
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -H </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">Authorization: Bearer my-token</span><span style="color:#d3d0c8;">" http://localhost:8080/hi
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -H </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">Authorization: Bearer my-token</span><span style="color:#4f5b66;">" http://localhost:8080/hi
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>POSTリクエスト</h2>
|
||||
<p>テキストデータをPOSTしてみましょう。<code>Post()</code> の第2引数にボディ、第3引数にContent-Typeを指定します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">Hello, Server!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Hello, Server!
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">Hello, Server!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// 200
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// Hello, Server!
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>テスト用サーバーの <code>/post</code> はボディをそのまま返すので、送った文字列がそのまま返ってきます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -X</span><span style="color:#d3d0c8;"> POST</span><span style="color:#f2777a;"> -H </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">Content-Type: text/plain</span><span style="color:#d3d0c8;">"</span><span style="color:#f2777a;"> -d </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">Hello, Server!</span><span style="color:#d3d0c8;">" http://localhost:8080/post
|
||||
</span><span style="color:#747369;"># Hello, Server!
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -X</span><span style="color:#4f5b66;"> POST</span><span style="color:#bf616a;"> -H </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">Content-Type: text/plain</span><span style="color:#4f5b66;">"</span><span style="color:#bf616a;"> -d </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">Hello, Server!</span><span style="color:#4f5b66;">" http://localhost:8080/post
|
||||
</span><span style="color:#a7adba;"># Hello, Server!
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>フォームデータの送信</h2>
|
||||
<p>HTMLフォームのように、キーと値のペアを送ることもできます。<code>httplib::Params</code> を使います。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/submit</span><span style="color:#d3d0c8;">", httplib::Params{
|
||||
</span><span style="color:#d3d0c8;"> {"</span><span style="color:#99cc99;">name</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">Alice</span><span style="color:#d3d0c8;">"},
|
||||
</span><span style="color:#d3d0c8;"> {"</span><span style="color:#99cc99;">age</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">30</span><span style="color:#d3d0c8;">"}
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// age = 30
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// name = Alice
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#4f5b66;">", httplib::Params{
|
||||
</span><span style="color:#4f5b66;"> {"</span><span style="color:#a3be8c;">name</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">Alice</span><span style="color:#4f5b66;">"},
|
||||
</span><span style="color:#4f5b66;"> {"</span><span style="color:#a3be8c;">age</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">30</span><span style="color:#4f5b66;">"}
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// age = 30
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// name = Alice
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>これは <code>application/x-www-form-urlencoded</code> 形式で送信されます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -X</span><span style="color:#d3d0c8;"> POST</span><span style="color:#f2777a;"> -d </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">name=Alice&age=30</span><span style="color:#d3d0c8;">" http://localhost:8080/submit
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -X</span><span style="color:#4f5b66;"> POST</span><span style="color:#bf616a;"> -d </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">name=Alice&age=30</span><span style="color:#4f5b66;">" http://localhost:8080/submit
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>ファイルのPOST</h2>
|
||||
<p>ファイルをアップロードするには、<code>httplib::UploadFormDataItems</code> を使ってマルチパートフォームデータとして送信します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">", httplib::UploadFormDataItems{
|
||||
</span><span style="color:#d3d0c8;"> {"</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">Hello, File!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">hello.txt</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">"}
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// hello.txt (12 bytes)
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">", httplib::UploadFormDataItems{
|
||||
</span><span style="color:#4f5b66;"> {"</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">Hello, File!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">hello.txt</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">"}
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// hello.txt (12 bytes)
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>UploadFormDataItems</code> の各要素は <code>{name, content, filename, content_type}</code> の4つのフィールドで構成されます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -F </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">file=Hello, File!;filename=hello.txt;type=text/plain</span><span style="color:#d3d0c8;">" http://localhost:8080/upload
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -F </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">file=Hello, File!;filename=hello.txt;type=text/plain</span><span style="color:#4f5b66;">" http://localhost:8080/upload
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>エラーハンドリング</h2>
|
||||
<p>ネットワーク通信では、サーバーに接続できない場合があります。<code>res</code> が有効かどうかを必ず確認しましょう。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:9999</span><span style="color:#d3d0c8;">"); </span><span style="color:#747369;">// 存在しないポート
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(!res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// 接続エラー
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Error: </span><span style="color:#d3d0c8;">" << </span><span style="color:#6699cc;">httplib::to_string</span><span style="color:#d3d0c8;">(res.</span><span style="color:#6699cc;">error</span><span style="color:#d3d0c8;">()) << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// Error: Connection
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// ここに到達すればレスポンスを受信できている
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;">!= </span><span style="color:#f99157;">200</span><span style="color:#d3d0c8;">) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">HTTP Error: </span><span style="color:#d3d0c8;">" << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:9999</span><span style="color:#4f5b66;">"); </span><span style="color:#a7adba;">// 存在しないポート
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(!res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// 接続エラー
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#4f5b66;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#4f5b66;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#4f5b66;">()) << std::endl;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// Error: Connection
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;">// ここに到達すればレスポンスを受信できている
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;">!= </span><span style="color:#d08770;">200</span><span style="color:#4f5b66;">) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">HTTP Error: </span><span style="color:#4f5b66;">" << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl;
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>エラーには2つのレベルがあります。</p>
|
||||
<ul>
|
||||
<li><strong>接続エラー</strong>: サーバーに到達できなかった場合。<code>res</code> が偽になり、<code>res.error()</code> でエラーの種類を取得できます</li>
|
||||
<li><strong>HTTPエラー</strong>: サーバーからエラーステータス(404、500など)が返ってきた場合。<code>res</code> は真ですが、<code>res->status</code> を確認する必要があります</li>
|
||||
</ul>
|
||||
<h2>次のステップ</h2>
|
||||
<p>クライアントからリクエストを送る方法がわかりました。次は、サーバー側をもっと詳しく見てみましょう。ルーティングやパスパラメータなど、サーバーの機能を掘り下げます。</p>
|
||||
<p><strong>次:</strong> <a href="../03-basic-server">Basic Server</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
446
docs/ja/tour/03-basic-server/index.html
Normal file
446
docs/ja/tour/03-basic-server/index.html
Normal file
@@ -0,0 +1,446 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Basic Server - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="active">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Basic Server</h1>
|
||||
<p>前章ではクライアントからリクエストを送りました。そのとき、テスト用サーバーを用意しましたね。この章では、あのサーバーの仕組みをひとつずつ紐解いていきます。</p>
|
||||
<h2>サーバーの起動</h2>
|
||||
<p>ルーティングを登録したら、最後に <code>svr.listen()</code> を呼んでサーバーを起動します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>第1引数はホスト、第2引数はポート番号です。<code>"0.0.0.0"</code> を指定すると、すべてのネットワークインターフェースでリクエストを受け付けます。自分のマシンからのアクセスだけに限定したいときは <code>"127.0.0.1"</code> を使います。</p>
|
||||
<p><code>listen()</code> はブロッキング呼び出しです。サーバーが停止するまで、この行から先には進みません。ターミナルで <code>Ctrl+C</code> を押すか、別スレッドから <code>svr.stop()</code> を呼ぶまでサーバーは動き続けます。</p>
|
||||
<h2>ルーティング</h2>
|
||||
<p>サーバーの核になるのは「ルーティング」です。どのURLに、どのHTTPメソッドでアクセスされたら、何をするか。それを登録する仕組みです。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &req, httplib::Response &res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request &req, httplib::Response &res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>svr.Get()</code> は、GETリクエストに対するハンドラーを登録します。第1引数がパス、第2引数がハンドラー関数です。<code>/hi</code> にGETリクエストが来たら、このラムダが呼ばれます。</p>
|
||||
<p>HTTPメソッドごとにメソッドが用意されています。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">", handler); </span><span style="color:#747369;">// GET
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">", handler); </span><span style="color:#747369;">// POST
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Put</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">", handler); </span><span style="color:#747369;">// PUT
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Delete</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">", handler); </span><span style="color:#747369;">// DELETE
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">", handler); </span><span style="color:#a7adba;">// GET
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">", handler); </span><span style="color:#a7adba;">// POST
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Put</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">", handler); </span><span style="color:#a7adba;">// PUT
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Delete</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">", handler); </span><span style="color:#a7adba;">// DELETE
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>ハンドラーのシグネチャは <code>(const httplib::Request &req, httplib::Response &res)</code> です。<code>auto</code> を使って短く書くこともできます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>パスが一致したときだけハンドラーが呼ばれます。登録されていないパスにアクセスすると、自動的に404が返ります。</p>
|
||||
<h2>リクエストオブジェクト</h2>
|
||||
<p>ハンドラーの第1引数 <code>req</code> から、クライアントが送ってきた情報を読み取れます。</p>
|
||||
<h3>ボディ</h3>
|
||||
<p><code>req.body</code> でリクエストボディを取得できます。型は <code>std::string</code> です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// クライアントが送ったボディをそのまま返す
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(req.</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// クライアントが送ったボディをそのまま返す
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>ヘッダー</h3>
|
||||
<p><code>req.get_header_value()</code> でリクエストヘッダーの値を取得できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/check</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> auth = req.</span><span style="color:#6699cc;">get_header_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Authorization</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Auth: </span><span style="color:#d3d0c8;">" + auth, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/check</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> auth = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Authorization</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Auth: </span><span style="color:#4f5b66;">" + auth, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>クエリパラメーターとフォームデータ</h3>
|
||||
<p><code>req.get_param_value()</code> でパラメーターを取得できます。GETのクエリパラメーターと、POSTのフォームデータの両方に使えます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/search</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> q = req.</span><span style="color:#6699cc;">get_param_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">q</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Query: </span><span style="color:#d3d0c8;">" + q, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">q</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#4f5b66;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>/search?q=cpp-httplib</code> にアクセスすると、<code>q</code> の値は <code>"cpp-httplib"</code> になります。</p>
|
||||
<p>すべてのパラメーターをループで処理したいときは、<code>req.params</code> を使います。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/submit</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> std::string result;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">for </span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&[key, val] : req.</span><span style="color:#f2777a;">params</span><span style="color:#d3d0c8;">) {
|
||||
</span><span style="color:#d3d0c8;"> result += key + "</span><span style="color:#99cc99;"> = </span><span style="color:#d3d0c8;">" + val + "</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">";
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(result, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> std::string result;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">for </span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#4f5b66;">) {
|
||||
</span><span style="color:#4f5b66;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#4f5b66;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#4f5b66;">";
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>ファイルアップロード</h3>
|
||||
<p>マルチパートフォームでアップロードされたファイルは、<code>req.form.get_file()</code> で取得します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> f = req.</span><span style="color:#f2777a;">form</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">get_file</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> content = f.</span><span style="color:#f2777a;">filename </span><span style="color:#d3d0c8;">+ "</span><span style="color:#99cc99;"> (</span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::to_string</span><span style="color:#d3d0c8;">(f.</span><span style="color:#f2777a;">content</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()) + "</span><span style="color:#99cc99;"> bytes)</span><span style="color:#d3d0c8;">";
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(content, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#4f5b66;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#4f5b66;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#4f5b66;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#4f5b66;">";
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>f.filename</code> でファイル名、<code>f.content</code> でファイルの中身にアクセスできます。</p>
|
||||
<h2>パスパラメーター</h2>
|
||||
<p>URLの一部を変数として受け取りたいことがあります。たとえば <code>/users/42</code> の <code>42</code> を取得したい場合です。<code>:param</code> 記法を使うと、URLの一部をキャプチャできます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/users/:id</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">id</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">User ID: </span><span style="color:#d3d0c8;">" + id, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">id</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#4f5b66;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>/users/42</code> にアクセスすると、<code>req.path_params.at("id")</code> は <code>"42"</code> を返します。<code>/users/100</code> なら <code>"100"</code> です。</p>
|
||||
<p>複数のパスパラメーターも使えます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/users/:user_id/posts/:post_id</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> user_id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">user_id</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> post_id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">post_id</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">User: </span><span style="color:#d3d0c8;">" + user_id + "</span><span style="color:#99cc99;">, Post: </span><span style="color:#d3d0c8;">" + post_id, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/users/:user_id/posts/:post_id</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> user_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">user_id</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> post_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">post_id</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">User: </span><span style="color:#4f5b66;">" + user_id + "</span><span style="color:#a3be8c;">, Post: </span><span style="color:#4f5b66;">" + post_id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>正規表現パターン</h3>
|
||||
<p><code>:param</code> の代わりに正規表現をパスに書くこともできます。キャプチャグループの値は <code>req.matches</code> で取得します。型は <code>std::smatch</code> です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// 数字のみのIDを受け付ける
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">"(</span><span style="color:#99cc99;">/files/(\d+)</span><span style="color:#d3d0c8;">)", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">matches</span><span style="color:#d3d0c8;">[</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">]; </span><span style="color:#747369;">// 最初のキャプチャグループ
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">File ID: </span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">(id), "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;">// 数字のみのIDを受け付ける
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">R</span><span style="color:#4f5b66;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#4f5b66;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#4f5b66;">[</span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">]; </span><span style="color:#a7adba;">// 最初のキャプチャグループ
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#4f5b66;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#4f5b66;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>/files/42</code> にはマッチしますが、<code>/files/abc</code> にはマッチしません。入力値を絞り込みたいときに便利です。</p>
|
||||
<h2>レスポンスの組み立て</h2>
|
||||
<p>ハンドラーの第2引数 <code>res</code> を使って、クライアントに返すレスポンスを組み立てます。</p>
|
||||
<h3>ボディとContent-Type</h3>
|
||||
<p><code>res.set_content()</code> でボディとContent-Typeを設定します。これだけでステータスコード200のレスポンスが返ります。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>ステータスコード</h3>
|
||||
<p>ステータスコードを変えたいときは、<code>res.status</code> に代入します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/not-found</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;">= </span><span style="color:#f99157;">404</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Not found</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/not-found</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;">= </span><span style="color:#d08770;">404</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Not found</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>レスポンスヘッダー</h3>
|
||||
<p><code>res.set_header()</code> でレスポンスヘッダーを追加できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/with-header</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_header</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">X-Custom</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">my-value</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/with-header</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">X-Custom</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">my-value</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>前章のサーバーを読み解く</h2>
|
||||
<p>ここまでの知識を使って、前章で用意したテスト用サーバーを改めて見てみましょう。</p>
|
||||
<h3>GET /hi</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>最もシンプルなハンドラーです。リクエストの情報は使わないので、<code>req</code> の変数名を省略しています。<code>"Hello!"</code> というテキストをそのまま返します。</p>
|
||||
<h3>GET /search</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/search</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> q = req.</span><span style="color:#6699cc;">get_param_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">q</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Query: </span><span style="color:#d3d0c8;">" + q, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">q</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#4f5b66;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>req.get_param_value("q")</code> でクエリパラメーター <code>q</code> の値を取り出します。<code>/search?q=cpp-httplib</code> なら、レスポンスは <code>"Query: cpp-httplib"</code> になります。</p>
|
||||
<h3>POST /post</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(req.</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>クライアントが送ったリクエストボディを、そのままレスポンスとして返すエコーサーバーです。<code>req.body</code> にボディが丸ごと入っています。</p>
|
||||
<h3>POST /submit</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/submit</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> std::string result;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">for </span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&[key, val] : req.</span><span style="color:#f2777a;">params</span><span style="color:#d3d0c8;">) {
|
||||
</span><span style="color:#d3d0c8;"> result += key + "</span><span style="color:#99cc99;"> = </span><span style="color:#d3d0c8;">" + val + "</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">";
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(result, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> std::string result;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">for </span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#4f5b66;">) {
|
||||
</span><span style="color:#4f5b66;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#4f5b66;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#4f5b66;">";
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>フォームデータとして送られたキーと値のペアを、<code>req.params</code> でループ処理しています。構造化束縛 <code>auto &[key, val]</code> を使って、各ペアを取り出しています。</p>
|
||||
<h3>POST /upload</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> f = req.</span><span style="color:#f2777a;">form</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">get_file</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> content = f.</span><span style="color:#f2777a;">filename </span><span style="color:#d3d0c8;">+ "</span><span style="color:#99cc99;"> (</span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::to_string</span><span style="color:#d3d0c8;">(f.</span><span style="color:#f2777a;">content</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()) + "</span><span style="color:#99cc99;"> bytes)</span><span style="color:#d3d0c8;">";
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(content, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#4f5b66;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#4f5b66;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#4f5b66;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#4f5b66;">";
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>マルチパートフォームで送られたファイルを受け取ります。<code>req.form.get_file("file")</code> で <code>"file"</code> という名前のフィールドを取得し、<code>f.filename</code> と <code>f.content.size()</code> でファイル名とサイズを返しています。</p>
|
||||
<h3>GET /users/:id</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/users/:id</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">id</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">User ID: </span><span style="color:#d3d0c8;">" + id, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">id</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#4f5b66;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>:id</code> の部分がパスパラメーターです。<code>req.path_params.at("id")</code> で値を取り出しています。<code>/users/42</code> なら <code>"42"</code>、<code>/users/alice</code> なら <code>"alice"</code> が得られます。</p>
|
||||
<h3>GET /files/(\d+)</h3>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">"(</span><span style="color:#99cc99;">/files/(\d+)</span><span style="color:#d3d0c8;">)", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">matches</span><span style="color:#d3d0c8;">[</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">];
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">File ID: </span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">(id), "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">R</span><span style="color:#4f5b66;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#4f5b66;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#4f5b66;">[</span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">];
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#4f5b66;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#4f5b66;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>正規表現 <code>(\d+)</code> で数字だけのIDにマッチします。<code>/files/42</code> にはマッチしますが、<code>/files/abc</code> は404になります。<code>req.matches[1]</code> で最初のキャプチャグループの値を取得しています。</p>
|
||||
<h2>次のステップ</h2>
|
||||
<p>サーバーの基本がわかりましたね。ルーティング、リクエストの読み取り、レスポンスの組み立て。これだけで、十分に実用的なAPIサーバーが作れます。</p>
|
||||
<p>次は、静的ファイルの配信を見てみましょう。HTMLやCSSを配信するサーバーを作ります。</p>
|
||||
<p><strong>次:</strong> <a href="../04-static-file-server">Static File Server</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
269
docs/ja/tour/04-static-file-server/index.html
Normal file
269
docs/ja/tour/04-static-file-server/index.html
Normal file
@@ -0,0 +1,269 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Static File Server - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="active">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Static File Server</h1>
|
||||
<p>cpp-httplibは、HTMLやCSS、画像ファイルなどの静的ファイルも配信できます。面倒な設定は要りません。<code>set_mount_point()</code> を1行呼ぶだけです。</p>
|
||||
<h2>set_mount_point の基本</h2>
|
||||
<p>さっそくやってみましょう。<code>set_mount_point()</code> は、URLのパスとローカルディレクトリを紐づけます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./html</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Listening on port 8080...</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">./html</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#4f5b66;">" << std::endl;
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>第1引数がURLのマウントポイント、第2引数がローカルのディレクトリパスです。この例だと、<code>/</code> へのリクエストを <code>./html</code> ディレクトリから配信します。</p>
|
||||
<p>試してみましょう。まず <code>html</code> ディレクトリを作って、<code>index.html</code> を置きます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">mkdir</span><span style="color:#d3d0c8;"> html
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">mkdir</span><span style="color:#4f5b66;"> html
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;"><!</span><span style="color:#f2777a;">DOCTYPE</span><span style="color:#d3d0c8;"> html>
|
||||
</span><span style="color:#d3d0c8;"><</span><span style="color:#f2777a;">html</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;"><</span><span style="color:#f2777a;">head</span><span style="color:#d3d0c8;">><</span><span style="color:#f2777a;">title</span><span style="color:#d3d0c8;">>My Page</</span><span style="color:#f2777a;">title</span><span style="color:#d3d0c8;">></</span><span style="color:#f2777a;">head</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;"><</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;"> <</span><span style="color:#f2777a;">h1</span><span style="color:#d3d0c8;">>Hello from cpp-httplib!</</span><span style="color:#f2777a;">h1</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;"> <</span><span style="color:#f2777a;">p</span><span style="color:#d3d0c8;">>This is a static file.</</span><span style="color:#f2777a;">p</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;"></</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;"></</span><span style="color:#f2777a;">html</span><span style="color:#d3d0c8;">>
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;"><!</span><span style="color:#bf616a;">DOCTYPE</span><span style="color:#4f5b66;"> html>
|
||||
</span><span style="color:#4f5b66;"><</span><span style="color:#bf616a;">html</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;"><</span><span style="color:#bf616a;">head</span><span style="color:#4f5b66;">><</span><span style="color:#bf616a;">title</span><span style="color:#4f5b66;">>My Page</</span><span style="color:#bf616a;">title</span><span style="color:#4f5b66;">></</span><span style="color:#bf616a;">head</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;"><</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;"> <</span><span style="color:#bf616a;">h1</span><span style="color:#4f5b66;">>Hello from cpp-httplib!</</span><span style="color:#bf616a;">h1</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;"> <</span><span style="color:#bf616a;">p</span><span style="color:#4f5b66;">>This is a static file.</</span><span style="color:#bf616a;">p</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;"></</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;"></</span><span style="color:#bf616a;">html</span><span style="color:#4f5b66;">>
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>コンパイルして起動します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">g++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -o</span><span style="color:#d3d0c8;"> server server.cpp</span><span style="color:#f2777a;"> -pthread
|
||||
</span><span style="color:#6699cc;">./server
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">g++</span><span style="color:#bf616a;"> -std</span><span style="color:#4f5b66;">=c++17</span><span style="color:#bf616a;"> -o</span><span style="color:#4f5b66;"> server server.cpp</span><span style="color:#bf616a;"> -pthread
|
||||
</span><span style="color:#8fa1b3;">./server
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>ブラウザで <code>http://localhost:8080</code> を開いてみてください。<code>html/index.html</code> の内容が表示されるはずです。<code>http://localhost:8080/index.html</code> でも同じページが返ります。</p>
|
||||
<p>もちろん、前章のクライアントコードや <code>curl</code> でもアクセスできますよ。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:8080</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// HTMLが表示される
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// HTMLが表示される
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> http://localhost:8080
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>複数のマウントポイント</h2>
|
||||
<p><code>set_mount_point()</code> は何回でも呼べます。URLのパスごとに、別々のディレクトリを割り当てられます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./public</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/assets</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./static/assets</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/docs</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./documentation</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/assets</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">./static/assets</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/docs</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">./documentation</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>/assets/style.css</code> なら <code>./static/assets/style.css</code> を、<code>/docs/guide.html</code> なら <code>./documentation/guide.html</code> を配信します。</p>
|
||||
<h2>ハンドラーとの組み合わせ</h2>
|
||||
<p>静的ファイルの配信と、前章で学んだルーティングハンドラーは共存できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// APIエンドポイント
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/api/hello</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">"(</span><span style="color:#99cc99;">{"message":"Hello!"}</span><span style="color:#d3d0c8;">)", "</span><span style="color:#99cc99;">application/json</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// 静的ファイル配信
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./public</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;">// APIエンドポイント
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/api/hello</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">R</span><span style="color:#4f5b66;">"(</span><span style="color:#a3be8c;">{"message":"Hello!"}</span><span style="color:#4f5b66;">)", "</span><span style="color:#a3be8c;">application/json</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;">// 静的ファイル配信
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>ハンドラーが先に評価されます。<code>/api/hello</code> にはハンドラーが応答し、それ以外のパスは <code>./public</code> ディレクトリからファイルを探します。</p>
|
||||
<h2>レスポンスヘッダーの追加</h2>
|
||||
<p><code>set_mount_point()</code> の第3引数にヘッダーを渡すと、静的ファイルのレスポンスにカスタムヘッダーを付けられます。キャッシュ制御に便利です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./public</span><span style="color:#d3d0c8;">", {
|
||||
</span><span style="color:#d3d0c8;"> {"</span><span style="color:#99cc99;">Cache-Control</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">max-age=3600</span><span style="color:#d3d0c8;">"}
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#4f5b66;">", {
|
||||
</span><span style="color:#4f5b66;"> {"</span><span style="color:#a3be8c;">Cache-Control</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">max-age=3600</span><span style="color:#4f5b66;">"}
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>こうすると、ブラウザは配信されたファイルを1時間キャッシュします。</p>
|
||||
<h2>静的ファイルサーバー用のDockerファイル</h2>
|
||||
<p>cpp-httplibのリポジトリには、静的ファイルサーバー用の <code>Dockerfile</code> が含まれています。Docker Hubにビルド済みイメージも公開しているので、1コマンドで起動できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">> docker run</span><span style="color:#f2777a;"> -p</span><span style="color:#d3d0c8;"> 8080:80</span><span style="color:#f2777a;"> -v</span><span style="color:#d3d0c8;"> ./my-site:/html yhirose4dockerhub/cpp-httplib-server
|
||||
</span><span style="color:#6699cc;">Serving</span><span style="color:#d3d0c8;"> HTTP on 0.0.0.0:80
|
||||
</span><span style="color:#6699cc;">Mount</span><span style="color:#d3d0c8;"> point: / -> ./html
|
||||
</span><span style="color:#6699cc;">Press</span><span style="color:#d3d0c8;"> Ctrl+C to shutdown gracefully...
|
||||
</span><span style="color:#6699cc;">192.168.65.1</span><span style="color:#d3d0c8;"> - - </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">22/Feb/2026:12:00:00 +0000</span><span style="color:#cc99cc;">] </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">GET / HTTP/1.1</span><span style="color:#d3d0c8;">" 200 256 "</span><span style="color:#99cc99;">-</span><span style="color:#d3d0c8;">" "</span><span style="color:#99cc99;">Mozilla/5.0 ...</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#6699cc;">192.168.65.1</span><span style="color:#d3d0c8;"> - - </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">22/Feb/2026:12:00:00 +0000</span><span style="color:#cc99cc;">] </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">GET /style.css HTTP/1.1</span><span style="color:#d3d0c8;">" 200 1024 "</span><span style="color:#99cc99;">-</span><span style="color:#d3d0c8;">" "</span><span style="color:#99cc99;">Mozilla/5.0 ...</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#6699cc;">192.168.65.1</span><span style="color:#d3d0c8;"> - - </span><span style="color:#cc99cc;">[</span><span style="color:#d3d0c8;">22/Feb/2026:12:00:01 +0000</span><span style="color:#cc99cc;">] </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">GET /favicon.ico HTTP/1.1</span><span style="color:#d3d0c8;">" 404 152 "</span><span style="color:#99cc99;">-</span><span style="color:#d3d0c8;">" "</span><span style="color:#99cc99;">Mozilla/5.0 ...</span><span style="color:#d3d0c8;">"
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">> docker run</span><span style="color:#bf616a;"> -p</span><span style="color:#4f5b66;"> 8080:80</span><span style="color:#bf616a;"> -v</span><span style="color:#4f5b66;"> ./my-site:/html yhirose4dockerhub/cpp-httplib-server
|
||||
</span><span style="color:#8fa1b3;">Serving</span><span style="color:#4f5b66;"> HTTP on 0.0.0.0:80
|
||||
</span><span style="color:#8fa1b3;">Mount</span><span style="color:#4f5b66;"> point: / -> ./html
|
||||
</span><span style="color:#8fa1b3;">Press</span><span style="color:#4f5b66;"> Ctrl+C to shutdown gracefully...
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#4f5b66;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#4f5b66;">22/Feb/2026:12:00:00 +0000</span><span style="color:#b48ead;">] </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">GET / HTTP/1.1</span><span style="color:#4f5b66;">" 200 256 "</span><span style="color:#a3be8c;">-</span><span style="color:#4f5b66;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#4f5b66;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#4f5b66;">22/Feb/2026:12:00:00 +0000</span><span style="color:#b48ead;">] </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">GET /style.css HTTP/1.1</span><span style="color:#4f5b66;">" 200 1024 "</span><span style="color:#a3be8c;">-</span><span style="color:#4f5b66;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#4f5b66;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#4f5b66;">22/Feb/2026:12:00:01 +0000</span><span style="color:#b48ead;">] </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">GET /favicon.ico HTTP/1.1</span><span style="color:#4f5b66;">" 404 152 "</span><span style="color:#a3be8c;">-</span><span style="color:#4f5b66;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#4f5b66;">"
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>./my-site</code> ディレクトリの中身が、そのままポート8080で配信されます。NGINXと同じログ形式で、アクセスの様子を確認できますよ。</p>
|
||||
<h2>次のステップ</h2>
|
||||
<p>静的ファイルの配信ができるようになりましたね。HTMLやCSS、JavaScriptを配信するWebサーバーが、これだけのコードで作れます。</p>
|
||||
<p>次は、HTTPSで暗号化通信をしてみましょう。まずはTLSライブラリのセットアップからです。</p>
|
||||
<p><strong>次:</strong> <a href="../05-tls-setup">TLS Setup</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
193
docs/ja/tour/05-tls-setup/index.html
Normal file
193
docs/ja/tour/05-tls-setup/index.html
Normal file
@@ -0,0 +1,193 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>TLS Setup - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="active">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>TLS Setup</h1>
|
||||
<p>ここまではHTTP(平文)でやってきましたが、実際のWebではHTTPS(暗号化通信)が当たり前ですよね。cpp-httplibでHTTPSを使うには、TLSライブラリが必要です。</p>
|
||||
<p>このTourではOpenSSLを使います。最も広く使われていて、情報も豊富です。</p>
|
||||
<h2>OpenSSLのインストール</h2>
|
||||
<p>お使いのOSに合わせてインストールしましょう。</p>
|
||||
<table><thead><tr><th>OS</th><th>インストール方法</th></tr></thead><tbody>
|
||||
<tr><td>macOS</td><td><a href="https://brew.sh/">Homebrew</a> (<code>brew install openssl</code>)</td></tr>
|
||||
<tr><td>Ubuntu / Debian</td><td><code>sudo apt install libssl-dev</code></td></tr>
|
||||
<tr><td>Windows</td><td><a href="https://vcpkg.io/">vcpkg</a> (<code>vcpkg install openssl</code>)</td></tr>
|
||||
</tbody></table>
|
||||
<h2>コンパイルオプション</h2>
|
||||
<p>TLS機能を有効にするには、<code>CPPHTTPLIB_OPENSSL_SUPPORT</code> マクロを定義してコンパイルします。前章までのコンパイルコマンドに、いくつかオプションが増えます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;"># macOS (Homebrew)
|
||||
</span><span style="color:#6699cc;">clang++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#d3d0c8;">\
|
||||
</span><span style="color:#f2777a;"> -I</span><span style="color:#d3d0c8;">$</span><span style="color:#f2777a;">(</span><span style="color:#6699cc;">brew</span><span style="color:#f2777a;"> --prefix openssl)</span><span style="color:#d3d0c8;">/include \
|
||||
</span><span style="color:#f2777a;"> -L</span><span style="color:#d3d0c8;">$</span><span style="color:#f2777a;">(</span><span style="color:#6699cc;">brew</span><span style="color:#f2777a;"> --prefix openssl)</span><span style="color:#d3d0c8;">/lib \
|
||||
</span><span style="color:#f2777a;"> -lssl -lcrypto </span><span style="color:#d3d0c8;">\
|
||||
</span><span style="color:#f2777a;"> -framework</span><span style="color:#d3d0c8;"> CoreFoundation</span><span style="color:#f2777a;"> -framework</span><span style="color:#d3d0c8;"> Security \
|
||||
</span><span style="color:#f2777a;"> -o</span><span style="color:#d3d0c8;"> server server.cpp
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Linux
|
||||
</span><span style="color:#6699cc;">clang++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -pthread -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#d3d0c8;">\
|
||||
</span><span style="color:#f2777a;"> -lssl -lcrypto </span><span style="color:#d3d0c8;">\
|
||||
</span><span style="color:#f2777a;"> -o</span><span style="color:#d3d0c8;"> server server.cpp
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#6699cc;">cl</span><span style="color:#d3d0c8;"> /EHsc /std:c++17 /DCPPHTTPLIB_OPENSSL_SUPPORT server.cpp libssl.lib libcrypto.lib
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;"># macOS (Homebrew)
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#4f5b66;">=c++17</span><span style="color:#bf616a;"> -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#4f5b66;">\
|
||||
</span><span style="color:#bf616a;"> -I</span><span style="color:#4f5b66;">$</span><span style="color:#bf616a;">(</span><span style="color:#8fa1b3;">brew</span><span style="color:#bf616a;"> --prefix openssl)</span><span style="color:#4f5b66;">/include \
|
||||
</span><span style="color:#bf616a;"> -L</span><span style="color:#4f5b66;">$</span><span style="color:#bf616a;">(</span><span style="color:#8fa1b3;">brew</span><span style="color:#bf616a;"> --prefix openssl)</span><span style="color:#4f5b66;">/lib \
|
||||
</span><span style="color:#bf616a;"> -lssl -lcrypto </span><span style="color:#4f5b66;">\
|
||||
</span><span style="color:#bf616a;"> -framework</span><span style="color:#4f5b66;"> CoreFoundation</span><span style="color:#bf616a;"> -framework</span><span style="color:#4f5b66;"> Security \
|
||||
</span><span style="color:#bf616a;"> -o</span><span style="color:#4f5b66;"> server server.cpp
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;"># Linux
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#4f5b66;">=c++17</span><span style="color:#bf616a;"> -pthread -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#4f5b66;">\
|
||||
</span><span style="color:#bf616a;"> -lssl -lcrypto </span><span style="color:#4f5b66;">\
|
||||
</span><span style="color:#bf616a;"> -o</span><span style="color:#4f5b66;"> server server.cpp
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#4f5b66;"> /EHsc /std:c++17 /DCPPHTTPLIB_OPENSSL_SUPPORT server.cpp libssl.lib libcrypto.lib
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>それぞれのオプションの役割を見てみましょう。</p>
|
||||
<ul>
|
||||
<li><strong><code>-DCPPHTTPLIB_OPENSSL_SUPPORT</code></strong> — TLS機能を有効にするマクロ定義</li>
|
||||
<li><strong><code>-lssl -lcrypto</code></strong> — OpenSSLのライブラリをリンク</li>
|
||||
<li><strong><code>-I</code> / <code>-L</code></strong>(macOSのみ)— Homebrew版OpenSSLのパスを指定</li>
|
||||
<li><strong><code>-framework CoreFoundation -framework Security</code></strong>(macOSのみ)— Keychainからシステム証明書を自動で読み込むために必要です</li>
|
||||
</ul>
|
||||
<h2>動作確認</h2>
|
||||
<p>ちゃんと動くか確認してみましょう。<code>httplib::Client</code> にHTTPSのURLを渡してアクセスするだけのプログラムです。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#define </span><span style="color:#d3d0c8;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://www.google.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Status: </span><span style="color:#d3d0c8;">" << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span><span style="color:#d3d0c8;"> } </span><span style="color:#cc99cc;">else </span><span style="color:#d3d0c8;">{
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Error: </span><span style="color:#d3d0c8;">" << </span><span style="color:#6699cc;">httplib::to_string</span><span style="color:#d3d0c8;">(res.</span><span style="color:#6699cc;">error</span><span style="color:#d3d0c8;">()) << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#4f5b66;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://www.google.com</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Status: </span><span style="color:#4f5b66;">" << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl;
|
||||
</span><span style="color:#4f5b66;"> } </span><span style="color:#b48ead;">else </span><span style="color:#4f5b66;">{
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#4f5b66;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#4f5b66;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#4f5b66;">()) << std::endl;
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>コンパイルして実行してみてください。<code>Status: 200</code> と表示されれば、セットアップ完了です。</p>
|
||||
<h2>他のTLSバックエンド</h2>
|
||||
<p>cpp-httplibはOpenSSL以外にも、Mbed TLSとwolfSSLに対応しています。マクロ定義とリンクするライブラリを変えるだけで切り替えられます。</p>
|
||||
<table><thead><tr><th style="text-align: left">バックエンド</th><th style="text-align: left">マクロ定義</th><th style="text-align: left">リンクするライブラリ</th></tr></thead><tbody>
|
||||
<tr><td style="text-align: left">OpenSSL</td><td style="text-align: left"><code>CPPHTTPLIB_OPENSSL_SUPPORT</code></td><td style="text-align: left"><code>libssl</code>, <code>libcrypto</code></td></tr>
|
||||
<tr><td style="text-align: left">Mbed TLS</td><td style="text-align: left"><code>CPPHTTPLIB_MBEDTLS_SUPPORT</code></td><td style="text-align: left"><code>libmbedtls</code>, <code>libmbedx509</code>, <code>libmbedcrypto</code></td></tr>
|
||||
<tr><td style="text-align: left">wolfSSL</td><td style="text-align: left"><code>CPPHTTPLIB_WOLFSSL_SUPPORT</code></td><td style="text-align: left"><code>libwolfssl</code></td></tr>
|
||||
</tbody></table>
|
||||
<p>このTourではOpenSSLを前提に進めますが、APIはどのバックエンドでも共通です。</p>
|
||||
<h2>次のステップ</h2>
|
||||
<p>TLSの準備ができましたね。次は、HTTPSサイトにリクエストを送ってみましょう。</p>
|
||||
<p><strong>次:</strong> <a href="../06-https-client">HTTPS Client</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
251
docs/ja/tour/06-https-client/index.html
Normal file
251
docs/ja/tour/06-https-client/index.html
Normal file
@@ -0,0 +1,251 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>HTTPS Client - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="active">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>HTTPS Client</h1>
|
||||
<p>前章でOpenSSLのセットアップが済んだので、さっそくHTTPSクライアントを使ってみましょう。2章で使った <code>httplib::Client</code> がそのまま使えます。コンストラクタに <code>https://</code> 付きのURLを渡すだけです。</p>
|
||||
<h2>GETリクエスト</h2>
|
||||
<p>実在するHTTPSサイトにアクセスしてみましょう。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#define </span><span style="color:#d3d0c8;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://nghttp2.org</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">substr</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">100</span><span style="color:#d3d0c8;">) << std::endl; </span><span style="color:#747369;">// HTMLの先頭部分
|
||||
</span><span style="color:#d3d0c8;"> } </span><span style="color:#cc99cc;">else </span><span style="color:#d3d0c8;">{
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Error: </span><span style="color:#d3d0c8;">" << </span><span style="color:#6699cc;">httplib::to_string</span><span style="color:#d3d0c8;">(res.</span><span style="color:#6699cc;">error</span><span style="color:#d3d0c8;">()) << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#4f5b66;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// 200
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">substr</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">0</span><span style="color:#4f5b66;">, </span><span style="color:#d08770;">100</span><span style="color:#4f5b66;">) << std::endl; </span><span style="color:#a7adba;">// HTMLの先頭部分
|
||||
</span><span style="color:#4f5b66;"> } </span><span style="color:#b48ead;">else </span><span style="color:#4f5b66;">{
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#4f5b66;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#4f5b66;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#4f5b66;">()) << std::endl;
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>2章では <code>httplib::Client cli("http://localhost:8080")</code> と書きましたよね。スキームを <code>https://</code> に変えるだけです。<code>Get()</code> や <code>Post()</code> など、2章で学んだAPIはすべてそのまま使えます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>ポートの指定</h2>
|
||||
<p>HTTPSのデフォルトポートは443です。別のポートを使いたい場合は、URLにポートを含めます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://localhost:8443</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>CA証明書の検証</h2>
|
||||
<p><code>httplib::Client</code> はHTTPS接続時、デフォルトでサーバー証明書を検証します。信頼できるCA(認証局)が発行した証明書を持つサーバーにしか接続しません。</p>
|
||||
<p>CA証明書は、macOSならKeychain、LinuxならシステムのCA証明書ストア、WindowsならWindowsの証明書ストアから自動で読み込みます。ほとんどの場合、追加の設定は要りません。</p>
|
||||
<h3>CA証明書ファイルの指定</h3>
|
||||
<p>環境によってはシステムのCA証明書が見つからないこともあります。そのときは <code>set_ca_cert_path()</code> でパスを直接指定してください。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://nghttp2.org</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_ca_cert_path</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/etc/ssl/certs/ca-certificates.crt</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_ca_cert_path</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/etc/ssl/certs/ca-certificates.crt</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> --cacert</span><span style="color:#d3d0c8;"> /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> --cacert</span><span style="color:#4f5b66;"> /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>証明書検証の無効化</h3>
|
||||
<p>開発中、自己署名証明書のサーバーに接続したいときは、検証を無効にできます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://localhost:8443</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">enable_server_certificate_verification</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">false</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">enable_server_certificate_verification</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">false</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -k</span><span style="color:#d3d0c8;"> https://localhost:8443/
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -k</span><span style="color:#4f5b66;"> https://localhost:8443/
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>本番では絶対に無効にしないでください。中間者攻撃のリスクがあります。</p>
|
||||
<h2>リダイレクトの追跡</h2>
|
||||
<p>HTTPSサイトへのアクセスでは、リダイレクトに遭遇することがよくあります。たとえば <code>http://</code> から <code>https://</code> へ、あるいは <code>www</code> なしから <code>www</code> ありへ転送されるケースです。</p>
|
||||
<p>デフォルトではリダイレクトを追跡しません。リダイレクト先は <code>Location</code> ヘッダーで確認できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://nghttp2.org</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/httpbin/redirect/3</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 302
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#6699cc;">get_header_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Location</span><span style="color:#d3d0c8;">") << std::endl;
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/httpbin/redirect/3</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// 302
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Location</span><span style="color:#4f5b66;">") << std::endl;
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#4f5b66;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>set_follow_location(true)</code> を設定すると、リダイレクトを自動で追跡して、最終的なレスポンスを返してくれます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://nghttp2.org</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_follow_location</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/httpbin/redirect/3</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200(最終的なレスポンス)
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_follow_location</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/httpbin/redirect/3</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// 200(最終的なレスポンス)
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -L</span><span style="color:#d3d0c8;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -L</span><span style="color:#4f5b66;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>次のステップ</h2>
|
||||
<p>HTTPSクライアントの使い方がわかりましたね。次は自分でHTTPSサーバーを立ててみましょう。自己署名証明書の作り方から始めます。</p>
|
||||
<p><strong>次:</strong> <a href="../07-https-server">HTTPS Server</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
240
docs/ja/tour/07-https-server/index.html
Normal file
240
docs/ja/tour/07-https-server/index.html
Normal file
@@ -0,0 +1,240 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>HTTPS Server - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="active">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>HTTPS Server</h1>
|
||||
<p>前章ではHTTPSクライアントを使いました。今度は自分でHTTPSサーバーを立ててみましょう。3章の <code>httplib::Server</code> を <code>httplib::SSLServer</code> に置き換えるだけです。</p>
|
||||
<p>ただし、TLSサーバーにはサーバー証明書と秘密鍵が必要です。まずはそこから準備しましょう。</p>
|
||||
<h2>自己署名証明書の作成</h2>
|
||||
<p>開発やテスト用なら、自己署名証明書(いわゆるオレオレ証明書)で十分です。OpenSSLのコマンドでサクッと作れます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">openssl</span><span style="color:#d3d0c8;"> req</span><span style="color:#f2777a;"> -x509 -noenc -keyout</span><span style="color:#d3d0c8;"> key.pem</span><span style="color:#f2777a;"> -out</span><span style="color:#d3d0c8;"> cert.pem</span><span style="color:#f2777a;"> -subj</span><span style="color:#d3d0c8;"> /CN=localhost
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">openssl</span><span style="color:#4f5b66;"> req</span><span style="color:#bf616a;"> -x509 -noenc -keyout</span><span style="color:#4f5b66;"> key.pem</span><span style="color:#bf616a;"> -out</span><span style="color:#4f5b66;"> cert.pem</span><span style="color:#bf616a;"> -subj</span><span style="color:#4f5b66;"> /CN=localhost
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>これで2つのファイルができます。</p>
|
||||
<ul>
|
||||
<li><strong><code>cert.pem</code></strong> — サーバー証明書</li>
|
||||
<li><strong><code>key.pem</code></strong> — 秘密鍵</li>
|
||||
</ul>
|
||||
<h2>最小のHTTPSサーバー</h2>
|
||||
<p>証明書ができたら、さっそくサーバーを書いてみましょう。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#define </span><span style="color:#d3d0c8;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::SSLServer </span><span style="color:#6699cc;">svr</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">cert.pem</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">key.pem</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello, HTTPS!</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Listening on https://localhost:8443</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8443</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#4f5b66;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::SSLServer </span><span style="color:#8fa1b3;">svr</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">key.pem</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello, HTTPS!</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Listening on https://localhost:8443</span><span style="color:#4f5b66;">" << std::endl;
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8443</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>httplib::SSLServer</code> のコンストラクタに証明書と秘密鍵のパスを渡すだけです。ルーティングの書き方は3章の <code>httplib::Server</code> とまったく同じですよ。</p>
|
||||
<p>コンパイルして起動しましょう。</p>
|
||||
<h2>動作確認</h2>
|
||||
<p>サーバーが起動したら、<code>curl</code> でアクセスしてみましょう。自己署名証明書なので、<code>-k</code> オプションで証明書検証をスキップします。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#f2777a;"> -k</span><span style="color:#d3d0c8;"> https://localhost:8443/
|
||||
</span><span style="color:#747369;"># Hello, HTTPS!
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -k</span><span style="color:#4f5b66;"> https://localhost:8443/
|
||||
</span><span style="color:#a7adba;"># Hello, HTTPS!
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>ブラウザで <code>https://localhost:8443</code> を開くと、「この接続は安全ではありません」と警告が出ます。自己署名証明書なので正常です。気にせず進めてください。</p>
|
||||
<h2>クライアントからの接続</h2>
|
||||
<p>前章の <code>httplib::Client</code> で接続してみましょう。自己署名証明書のサーバーに接続するには、2つの方法があります。</p>
|
||||
<h3>方法1: 証明書検証を無効にする</h3>
|
||||
<p>開発時の手軽な方法です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#define </span><span style="color:#d3d0c8;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://localhost:8443</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> cli.</span><span style="color:#6699cc;">enable_server_certificate_verification</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">false</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Hello, HTTPS!
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#4f5b66;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> cli.</span><span style="color:#8fa1b3;">enable_server_certificate_verification</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">false</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// Hello, HTTPS!
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<h3>方法2: 自己署名証明書をCA証明書として指定する</h3>
|
||||
<p>こちらのほうが安全です。<code>cert.pem</code> をCA証明書として信頼するよう指定します。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#define </span><span style="color:#d3d0c8;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://localhost:8443</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> cli.</span><span style="color:#6699cc;">set_ca_cert_path</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">cert.pem</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Hello, HTTPS!
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#4f5b66;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> cli.</span><span style="color:#8fa1b3;">set_ca_cert_path</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#4f5b66;"><< std::endl; </span><span style="color:#a7adba;">// Hello, HTTPS!
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>この方法なら、指定した証明書のサーバーにだけ接続を許可して、なりすましを防げます。テスト環境でもなるべくこちらを使いましょう。</p>
|
||||
<h2>Server と SSLServer の比較</h2>
|
||||
<p>3章で学んだ <code>httplib::Server</code> のAPIは、<code>httplib::SSLServer</code> でもそのまま使えます。違いはコンストラクタだけです。</p>
|
||||
<table><thead><tr><th></th><th><code>httplib::Server</code></th><th><code>httplib::SSLServer</code></th></tr></thead><tbody>
|
||||
<tr><td>コンストラクタ</td><td>引数なし</td><td>証明書と秘密鍵のパス</td></tr>
|
||||
<tr><td>プロトコル</td><td>HTTP</td><td>HTTPS</td></tr>
|
||||
<tr><td>ポート(慣例)</td><td>8080</td><td>8443</td></tr>
|
||||
<tr><td>ルーティング</td><td>共通</td><td>共通</td></tr>
|
||||
</tbody></table>
|
||||
<p>HTTPサーバーをHTTPSに切り替えるには、コンストラクタを変えるだけです。</p>
|
||||
<h2>次のステップ</h2>
|
||||
<p>HTTPSサーバーが動きましたね。これでHTTP/HTTPSのクライアントとサーバー、両方の基本がそろいました。</p>
|
||||
<p>次は、cpp-httplibに新しく加わったWebSocket機能を見てみましょう。</p>
|
||||
<p><strong>次:</strong> <a href="../08-websocket">WebSocket</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
292
docs/ja/tour/08-websocket/index.html
Normal file
292
docs/ja/tour/08-websocket/index.html
Normal file
@@ -0,0 +1,292 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>WebSocket - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="active">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>WebSocket</h1>
|
||||
<p>cpp-httplibはWebSocketにも対応しています。HTTPのリクエスト/レスポンスと違い、WebSocketはサーバーとクライアントが双方向にメッセージをやり取りできます。チャットやリアルタイム通知に便利です。</p>
|
||||
<p>さっそく、エコーサーバーとクライアントを作ってみましょう。</p>
|
||||
<h2>エコーサーバー</h2>
|
||||
<p>受け取ったメッセージをそのまま返すエコーサーバーです。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">WebSocket</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/ws</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">(ws.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg)) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg); </span><span style="color:#747369;">// 受け取ったメッセージをそのまま返す
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Listening on port 8080...</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#4f5b66;"> std::string msg;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">while </span><span style="color:#4f5b66;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#4f5b66;">(msg)) {
|
||||
</span><span style="color:#4f5b66;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#4f5b66;">(msg); </span><span style="color:#a7adba;">// 受け取ったメッセージをそのまま返す
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#4f5b66;">" << std::endl;
|
||||
</span><span style="color:#4f5b66;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>svr.WebSocket()</code> でWebSocketハンドラーを登録します。3章の <code>svr.Get()</code> や <code>svr.Post()</code> と同じ感覚ですね。</p>
|
||||
<p>ハンドラーの中では、<code>ws.read(msg)</code> でメッセージを待ちます。接続が閉じられると <code>read()</code> が <code>false</code> を返すので、ループを抜けます。<code>ws.send(msg)</code> でメッセージを送り返します。</p>
|
||||
<h2>クライアントからの接続</h2>
|
||||
<p><code>httplib::ws::WebSocketClient</code> を使ってサーバーに接続してみましょう。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::ws::WebSocketClient </span><span style="color:#6699cc;">client</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">ws://localhost:8080/ws</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(!client.</span><span style="color:#6699cc;">connect</span><span style="color:#d3d0c8;">()) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Connection failed</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// メッセージを送信
|
||||
</span><span style="color:#d3d0c8;"> client.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello, WebSocket!</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// サーバーからの応答を受信
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(client.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg)) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << msg << std::endl; </span><span style="color:#747369;">// Hello, WebSocket!
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> client.</span><span style="color:#6699cc;">close</span><span style="color:#d3d0c8;">();
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#4f5b66;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#4f5b66;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#4f5b66;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#4f5b66;">>
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#4f5b66;">() {
|
||||
</span><span style="color:#4f5b66;"> httplib::ws::WebSocketClient </span><span style="color:#8fa1b3;">client</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">ws://localhost:8080/ws</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(!client.</span><span style="color:#8fa1b3;">connect</span><span style="color:#4f5b66;">()) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << "</span><span style="color:#a3be8c;">Connection failed</span><span style="color:#4f5b66;">" << std::endl;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// メッセージを送信
|
||||
</span><span style="color:#4f5b66;"> client.</span><span style="color:#8fa1b3;">send</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello, WebSocket!</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// サーバーからの応答を受信
|
||||
</span><span style="color:#4f5b66;"> std::string msg;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(client.</span><span style="color:#8fa1b3;">read</span><span style="color:#4f5b66;">(msg)) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << msg << std::endl; </span><span style="color:#a7adba;">// Hello, WebSocket!
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> client.</span><span style="color:#8fa1b3;">close</span><span style="color:#4f5b66;">();
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>コンストラクタには <code>ws://host:port/path</code> 形式のURLを渡します。<code>connect()</code> で接続を開始し、<code>send()</code> と <code>read()</code> でメッセージをやり取りします。</p>
|
||||
<h2>テキストとバイナリ</h2>
|
||||
<p>WebSocketにはテキストとバイナリの2種類のメッセージがあります。<code>read()</code> の戻り値で区別できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">WebSocket</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/ws</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> httplib::ws::ReadResult ret;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">((ret = ws.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg))) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(ret == httplib::ws::Binary) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg.</span><span style="color:#6699cc;">data</span><span style="color:#d3d0c8;">(), msg.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()); </span><span style="color:#747369;">// バイナリとして送信
|
||||
</span><span style="color:#d3d0c8;"> } </span><span style="color:#cc99cc;">else </span><span style="color:#d3d0c8;">{
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg); </span><span style="color:#747369;">// テキストとして送信
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#4f5b66;"> std::string msg;
|
||||
</span><span style="color:#4f5b66;"> httplib::ws::ReadResult ret;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">while </span><span style="color:#4f5b66;">((ret = ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#4f5b66;">(msg))) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(ret == httplib::ws::Binary) {
|
||||
</span><span style="color:#4f5b66;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#4f5b66;">(msg.</span><span style="color:#8fa1b3;">data</span><span style="color:#4f5b66;">(), msg.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">()); </span><span style="color:#a7adba;">// バイナリとして送信
|
||||
</span><span style="color:#4f5b66;"> } </span><span style="color:#b48ead;">else </span><span style="color:#4f5b66;">{
|
||||
</span><span style="color:#4f5b66;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#4f5b66;">(msg); </span><span style="color:#a7adba;">// テキストとして送信
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<ul>
|
||||
<li><code>ws.send(const std::string &)</code> — テキストメッセージとして送信</li>
|
||||
<li><code>ws.send(const char *, size_t)</code> — バイナリメッセージとして送信</li>
|
||||
</ul>
|
||||
<p>クライアント側も同じAPIです。</p>
|
||||
<h2>リクエスト情報へのアクセス</h2>
|
||||
<p>ハンドラーの第1引数 <code>req</code> から、ハンドシェイク時のHTTPリクエスト情報を読み取れます。認証トークンの確認などに便利です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">WebSocket</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/ws</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &req, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> token = req.</span><span style="color:#6699cc;">get_header_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Authorization</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(token.</span><span style="color:#6699cc;">empty</span><span style="color:#d3d0c8;">()) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">close</span><span style="color:#d3d0c8;">(httplib::ws::CloseStatus::PolicyViolation, "</span><span style="color:#99cc99;">unauthorized</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">(ws.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg)) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg);
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request &req, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> token = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Authorization</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(token.</span><span style="color:#8fa1b3;">empty</span><span style="color:#4f5b66;">()) {
|
||||
</span><span style="color:#4f5b66;"> ws.</span><span style="color:#8fa1b3;">close</span><span style="color:#4f5b66;">(httplib::ws::CloseStatus::PolicyViolation, "</span><span style="color:#a3be8c;">unauthorized</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;"> std::string msg;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">while </span><span style="color:#4f5b66;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#4f5b66;">(msg)) {
|
||||
</span><span style="color:#4f5b66;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#4f5b66;">(msg);
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>WSSで使う</h2>
|
||||
<p>HTTPS上のWebSocket(WSS)にも対応しています。サーバー側は <code>httplib::SSLServer</code> にWebSocketハンドラーを登録するだけです。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::SSLServer </span><span style="color:#6699cc;">svr</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">cert.pem</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">key.pem</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">WebSocket</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/ws</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">(ws.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg)) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg);
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8443</span><span style="color:#d3d0c8;">);
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::SSLServer </span><span style="color:#8fa1b3;">svr</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">key.pem</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#4f5b66;"> std::string msg;
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">while </span><span style="color:#4f5b66;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#4f5b66;">(msg)) {
|
||||
</span><span style="color:#4f5b66;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#4f5b66;">(msg);
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8443</span><span style="color:#4f5b66;">);
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>クライアント側は <code>wss://</code> スキームを使います。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::ws::WebSocketClient </span><span style="color:#6699cc;">client</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">wss://localhost:8443/ws</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::ws::WebSocketClient </span><span style="color:#8fa1b3;">client</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">wss://localhost:8443/ws</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>次のステップ</h2>
|
||||
<p>WebSocketの基本がわかりましたね。ここまでで Tourは終わりです。</p>
|
||||
<p>次のページでは、Tourで取り上げなかった機能をまとめて紹介します。</p>
|
||||
<p><strong>次:</strong> <a href="../09-whats-next">What's Next</a></p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
424
docs/ja/tour/09-whats-next/index.html
Normal file
424
docs/ja/tour/09-whats-next/index.html
Normal file
@@ -0,0 +1,424 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>What's Next - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="active">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>What's Next</h1>
|
||||
<p>Tourお疲れさまでした! cpp-httplibの基本はひと通り押さえましたね。でも、まだまだ便利な機能があります。Tourで取り上げなかった機能をカテゴリー別に紹介します。</p>
|
||||
<h2>Streaming API</h2>
|
||||
<p>LLMのストリーミング応答や大きなファイルのダウンロードでは、レスポンス全体をメモリに載せたくないですよね。<code>stream::Get()</code> を使えば、データをチャンクごとに処理できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:11434</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> result = </span><span style="color:#6699cc;">httplib::stream::Get</span><span style="color:#d3d0c8;">(cli, "</span><span style="color:#99cc99;">/api/generate</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(result) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">(result.</span><span style="color:#6699cc;">next</span><span style="color:#d3d0c8;">()) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout.</span><span style="color:#6699cc;">write</span><span style="color:#d3d0c8;">(result.</span><span style="color:#6699cc;">data</span><span style="color:#d3d0c8;">(), result.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">());
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:11434</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> result = </span><span style="color:#8fa1b3;">httplib::stream::Get</span><span style="color:#4f5b66;">(cli, "</span><span style="color:#a3be8c;">/api/generate</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#4f5b66;">(result) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">while </span><span style="color:#4f5b66;">(result.</span><span style="color:#8fa1b3;">next</span><span style="color:#4f5b66;">()) {
|
||||
</span><span style="color:#4f5b66;"> std::cout.</span><span style="color:#8fa1b3;">write</span><span style="color:#4f5b66;">(result.</span><span style="color:#8fa1b3;">data</span><span style="color:#4f5b66;">(), result.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">());
|
||||
</span><span style="color:#4f5b66;"> }
|
||||
</span><span style="color:#4f5b66;">}
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>Get()</code> に <code>content_receiver</code> コールバックを渡す方法もあります。こちらはKeep-Aliveと併用できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:8080</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/stream</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const char </span><span style="color:#d3d0c8;">*data, size_t len) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout.</span><span style="color:#6699cc;">write</span><span style="color:#d3d0c8;">(data, len);
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/stream</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const char </span><span style="color:#4f5b66;">*data, size_t len) {
|
||||
</span><span style="color:#4f5b66;"> std::cout.</span><span style="color:#8fa1b3;">write</span><span style="color:#4f5b66;">(data, len);
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>サーバー側には <code>set_content_provider()</code> と <code>set_chunked_content_provider()</code> があります。サイズがわかっているなら前者、不明なら後者を使ってください。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// サイズ指定あり(Content-Length が設定される)
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/file</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> size = </span><span style="color:#6699cc;">get_file_size</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">large.bin</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content_provider</span><span style="color:#d3d0c8;">(size, "</span><span style="color:#99cc99;">application/octet-stream</span><span style="color:#d3d0c8;">",
|
||||
</span><span style="color:#d3d0c8;"> [](size_t offset, size_t length, httplib::DataSink &sink) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// offset から length バイト分を送る
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// サイズ不明(Chunked Transfer Encoding)
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/stream</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_chunked_content_provider</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">",
|
||||
</span><span style="color:#d3d0c8;"> [](size_t offset, httplib::DataSink &sink) {
|
||||
</span><span style="color:#d3d0c8;"> sink.</span><span style="color:#6699cc;">write</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">chunk</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">6</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">; </span><span style="color:#747369;">// falseを返すと終了
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;">// サイズ指定あり(Content-Length が設定される)
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/file</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> size = </span><span style="color:#8fa1b3;">get_file_size</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">large.bin</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content_provider</span><span style="color:#4f5b66;">(size, "</span><span style="color:#a3be8c;">application/octet-stream</span><span style="color:#4f5b66;">",
|
||||
</span><span style="color:#4f5b66;"> [](size_t offset, size_t length, httplib::DataSink &sink) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// offset から length バイト分を送る
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#a7adba;">// サイズ不明(Chunked Transfer Encoding)
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/stream</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_chunked_content_provider</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">",
|
||||
</span><span style="color:#4f5b66;"> [](size_t offset, httplib::DataSink &sink) {
|
||||
</span><span style="color:#4f5b66;"> sink.</span><span style="color:#8fa1b3;">write</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">chunk</span><span style="color:#96b5b4;">\n</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">6</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">; </span><span style="color:#a7adba;">// falseを返すと終了
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>大きなファイルのアップロードには <code>make_file_provider()</code> が便利です。ファイルを全部メモリに読み込まず、ストリーミングで送れます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:8080</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">", {}, {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#6699cc;">httplib::make_file_provider</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">/path/to/large-file.zip</span><span style="color:#d3d0c8;">")
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">", {}, {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#8fa1b3;">httplib::make_file_provider</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">/path/to/large-file.zip</span><span style="color:#4f5b66;">")
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>Server-Sent Events (SSE)</h2>
|
||||
<p>SSEクライアントも用意しています。自動再接続や <code>Last-Event-ID</code> による再開にも対応しています。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:8080</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">httplib::sse::SSEClient </span><span style="color:#6699cc;">sse</span><span style="color:#d3d0c8;">(</span><span style="color:#f2777a;">cli</span><span style="color:#d3d0c8;">, "</span><span style="color:#99cc99;">/events</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">sse.</span><span style="color:#6699cc;">on_message</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << msg.</span><span style="color:#f2777a;">event </span><span style="color:#d3d0c8;"><< "</span><span style="color:#99cc99;">: </span><span style="color:#d3d0c8;">" << msg.</span><span style="color:#f2777a;">data </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">sse.</span><span style="color:#6699cc;">start</span><span style="color:#d3d0c8;">(); </span><span style="color:#747369;">// ブロッキング、自動再接続あり
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">httplib::sse::SSEClient </span><span style="color:#8fa1b3;">sse</span><span style="color:#4f5b66;">(</span><span style="color:#bf616a;">cli</span><span style="color:#4f5b66;">, "</span><span style="color:#a3be8c;">/events</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">sse.</span><span style="color:#8fa1b3;">on_message</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << msg.</span><span style="color:#bf616a;">event </span><span style="color:#4f5b66;"><< "</span><span style="color:#a3be8c;">: </span><span style="color:#4f5b66;">" << msg.</span><span style="color:#bf616a;">data </span><span style="color:#4f5b66;"><< std::endl;
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">sse.</span><span style="color:#8fa1b3;">start</span><span style="color:#4f5b66;">(); </span><span style="color:#a7adba;">// ブロッキング、自動再接続あり
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>イベントタイプごとにハンドラーを分けることもできますよ。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">sse.</span><span style="color:#6699cc;">on_event</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">update</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// "update" イベントだけ処理
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">sse.</span><span style="color:#8fa1b3;">on_event</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">update</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// "update" イベントだけ処理
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>認証</h2>
|
||||
<p>クライアントにはBasic認証、Bearer Token認証、Digest認証のヘルパーを用意しています。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://api.example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_basic_auth</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">user</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">password</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_bearer_token_auth</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">my-token</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://api.example.com</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_basic_auth</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">user</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">password</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_bearer_token_auth</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">my-token</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>圧縮</h2>
|
||||
<p>gzip、Brotli、Zstandardによる圧縮・展開に対応しています。使いたい方式のマクロを定義してコンパイルしましょう。</p>
|
||||
<table><thead><tr><th>圧縮方式</th><th>マクロ定義</th></tr></thead><tbody>
|
||||
<tr><td>gzip</td><td><code>CPPHTTPLIB_ZLIB_SUPPORT</code></td></tr>
|
||||
<tr><td>Brotli</td><td><code>CPPHTTPLIB_BROTLI_SUPPORT</code></td></tr>
|
||||
<tr><td>Zstandard</td><td><code>CPPHTTPLIB_ZSTD_SUPPORT</code></td></tr>
|
||||
</tbody></table>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_compress</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// リクエストボディを圧縮
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_decompress</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// レスポンスボディを展開
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_compress</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">); </span><span style="color:#a7adba;">// リクエストボディを圧縮
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_decompress</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">); </span><span style="color:#a7adba;">// レスポンスボディを展開
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>プロキシ</h2>
|
||||
<p>HTTPプロキシ経由で接続できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_proxy</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">proxy.example.com</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_proxy_basic_auth</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">user</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">password</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_proxy</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">proxy.example.com</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_proxy_basic_auth</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">user</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">password</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>タイムアウト</h2>
|
||||
<p>接続・読み取り・書き込みのタイムアウトを個別に設定できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_connection_timeout</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">5</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// 5秒
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_read_timeout</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">10</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// 10秒
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_write_timeout</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">10</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// 10秒
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_connection_timeout</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">5</span><span style="color:#4f5b66;">, </span><span style="color:#d08770;">0</span><span style="color:#4f5b66;">); </span><span style="color:#a7adba;">// 5秒
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_read_timeout</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">10</span><span style="color:#4f5b66;">, </span><span style="color:#d08770;">0</span><span style="color:#4f5b66;">); </span><span style="color:#a7adba;">// 10秒
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_write_timeout</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">10</span><span style="color:#4f5b66;">, </span><span style="color:#d08770;">0</span><span style="color:#4f5b66;">); </span><span style="color:#a7adba;">// 10秒
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>Keep-Alive</h2>
|
||||
<p>同じサーバーに何度もリクエストするなら、Keep-Aliveを有効にしましょう。TCP接続を再利用するので効率的です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_keep_alive</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">);
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_keep_alive</span><span style="color:#4f5b66;">(</span><span style="color:#d08770;">true</span><span style="color:#4f5b66;">);
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>サーバーのミドルウェア</h2>
|
||||
<p>リクエスト処理の前後にフックを挟めます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_pre_routing_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// すべてのリクエストの前に実行される
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return</span><span style="color:#d3d0c8;"> httplib::Server::HandlerResponse::Unhandled; </span><span style="color:#747369;">// 通常のルーティングに進む
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_post_routing_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// レスポンスが返された後に実行される
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_header</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">X-Server</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">cpp-httplib</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_pre_routing_handler</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// すべてのリクエストの前に実行される
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return</span><span style="color:#4f5b66;"> httplib::Server::HandlerResponse::Unhandled; </span><span style="color:#a7adba;">// 通常のルーティングに進む
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_post_routing_handler</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// レスポンスが返された後に実行される
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">X-Server</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">cpp-httplib</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p><code>req.user_data</code> を使うと、ミドルウェアからハンドラーにデータを渡せます。認証トークンのデコード結果を共有するときに便利です。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_pre_routing_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> req.</span><span style="color:#f2777a;">user_data</span><span style="color:#d3d0c8;">["</span><span style="color:#99cc99;">auth_user</span><span style="color:#d3d0c8;">"] = </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">alice</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return</span><span style="color:#d3d0c8;"> httplib::Server::HandlerResponse::Unhandled;
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/me</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> user = std::</span><span style="color:#6699cc;">any_cast</span><span style="color:#d3d0c8;"><std::string>(req.</span><span style="color:#f2777a;">user_data</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">auth_user</span><span style="color:#d3d0c8;">"));
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello, </span><span style="color:#d3d0c8;">" + user, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_pre_routing_handler</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> req.</span><span style="color:#bf616a;">user_data</span><span style="color:#4f5b66;">["</span><span style="color:#a3be8c;">auth_user</span><span style="color:#4f5b66;">"] = </span><span style="color:#8fa1b3;">std::string</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">alice</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">return</span><span style="color:#4f5b66;"> httplib::Server::HandlerResponse::Unhandled;
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/me</span><span style="color:#4f5b66;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> user = std::</span><span style="color:#8fa1b3;">any_cast</span><span style="color:#4f5b66;"><std::string>(req.</span><span style="color:#bf616a;">user_data</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">auth_user</span><span style="color:#4f5b66;">"));
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Hello, </span><span style="color:#4f5b66;">" + user, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>エラーや例外のハンドラーもカスタマイズできますよ。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_error_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Custom Error Page</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/html</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_exception_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res, std::exception_ptr ep) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;">= </span><span style="color:#f99157;">500</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Internal Server Error</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_error_handler</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Custom Error Page</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/html</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_exception_handler</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&res, std::exception_ptr ep) {
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;">= </span><span style="color:#d08770;">500</span><span style="color:#4f5b66;">;
|
||||
</span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">Internal Server Error</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>ロギング</h2>
|
||||
<p>サーバーでもクライアントでもロガーを設定できます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_logger</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << req.</span><span style="color:#f2777a;">method </span><span style="color:#d3d0c8;"><< " " << req.</span><span style="color:#f2777a;">path </span><span style="color:#d3d0c8;"><< " " << res.</span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_logger</span><span style="color:#4f5b66;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&req, </span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&res) {
|
||||
</span><span style="color:#4f5b66;"> std::cout << req.</span><span style="color:#bf616a;">method </span><span style="color:#4f5b66;"><< " " << req.</span><span style="color:#bf616a;">path </span><span style="color:#4f5b66;"><< " " << res.</span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;"><< std::endl;
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>Unix Domain Socket</h2>
|
||||
<p>TCP以外に、Unix Domain Socketでの通信にも対応しています。同じマシン上のプロセス間通信に使えます。</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// サーバー
|
||||
</span><span style="color:#d3d0c8;">httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_address_family</span><span style="color:#d3d0c8;">(AF_UNIX);
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/tmp/httplib.sock</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">);
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;">// サーバー
|
||||
</span><span style="color:#4f5b66;">httplib::Server svr;
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">set_address_family</span><span style="color:#4f5b66;">(AF_UNIX);
|
||||
</span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/tmp/httplib.sock</span><span style="color:#4f5b66;">", </span><span style="color:#d08770;">0</span><span style="color:#4f5b66;">);
|
||||
</span></pre>
|
||||
</div><div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// クライアント
|
||||
</span><span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_address_family</span><span style="color:#d3d0c8;">(AF_UNIX);
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_hostname_addr_map</span><span style="color:#d3d0c8;">({{"</span><span style="color:#99cc99;">localhost</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">/tmp/httplib.sock</span><span style="color:#d3d0c8;">"}});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span></pre>
|
||||
</div><div class="code-light"><pre style="background-color:#eff1f5;">
|
||||
<span style="color:#a7adba;">// クライアント
|
||||
</span><span style="color:#4f5b66;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">http://localhost</span><span style="color:#4f5b66;">");
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_address_family</span><span style="color:#4f5b66;">(AF_UNIX);
|
||||
</span><span style="color:#4f5b66;">cli.</span><span style="color:#8fa1b3;">set_hostname_addr_map</span><span style="color:#4f5b66;">({{"</span><span style="color:#a3be8c;">localhost</span><span style="color:#4f5b66;">", "</span><span style="color:#a3be8c;">/tmp/httplib.sock</span><span style="color:#4f5b66;">"}});
|
||||
</span><span style="color:#4f5b66;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">("</span><span style="color:#a3be8c;">/</span><span style="color:#4f5b66;">");
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>さらに詳しく</h2>
|
||||
<p>もっと詳しく知りたいときは、以下を参照してください。</p>
|
||||
<ul>
|
||||
<li>Cookbook — よくあるユースケースのレシピ集</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README.md">README</a> — 全APIのリファレンス</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README-sse.md">README-sse</a> — Server-Sent Eventsの使い方</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README-stream.md">README-stream</a> — Streaming APIの使い方</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README-websocket.md">README-websocket</a> — WebSocketサーバーの使い方</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
105
docs/ja/tour/index.html
Normal file
105
docs/ja/tour/index.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>A Tour of cpp-httplib - cpp-httplib</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script>
|
||||
(function() {
|
||||
var t = localStorage.getItem('preferred-theme');
|
||||
if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/ja/">Home</a>
|
||||
<a href="/ja/tour/">Tour</a>
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">JA</button>
|
||||
<ul class="lang-popup">
|
||||
|
||||
<li><a href="#" data-lang="en">EN</a></li>
|
||||
|
||||
<li><a href="#" data-lang="ja">JA</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div class="layout has-sidebar">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
|
||||
<div class="nav-section">
|
||||
<a href="/ja/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/ja/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/ja/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/ja/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/ja/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/ja/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/ja/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>A Tour of cpp-httplib</h1>
|
||||
<p>cpp-httplibの基本を、順番に学んでいくチュートリアルです。各章は前の章の内容を踏まえて進む構成なので、1章から順に読んでください。</p>
|
||||
<ol>
|
||||
<li><a href="01-getting-started">Getting Started</a> — httplib.h の入手とHello Worldサーバー</li>
|
||||
<li><a href="02-basic-client">Basic Client</a> — GET/POST・パスパラメーターのリクエスト送信</li>
|
||||
<li><a href="03-basic-server">Basic Server</a> — ルーティング、パスパラメーター、レスポンスの組み立て</li>
|
||||
<li><a href="04-static-file-server">Static File Server</a> — 静的ファイルの配信</li>
|
||||
<li><a href="05-tls-setup">TLS Setup</a> — OpenSSL / mbedTLS のセットアップ</li>
|
||||
<li><a href="06-https-client">HTTPS Client</a> — HTTPSサイトへのリクエスト</li>
|
||||
<li><a href="07-https-server">HTTPS Server</a> — HTTPSサーバーの構築</li>
|
||||
<li><a href="08-websocket">WebSocket</a> — WebSocket通信の基本</li>
|
||||
<li><a href="09-whats-next">What's Next</a> — さらなる機能の紹介</li>
|
||||
</ol>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user