mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-04-12 11:48: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:
198
docs/en/tour/01-getting-started/index.html
Normal file
198
docs/en/tour/01-getting-started/index.html
Normal file
@@ -0,0 +1,198 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="active">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Getting Started</h1>
|
||||
<p>All you need to get started with cpp-httplib is <code>httplib.h</code> and a C++ compiler. Let's download the file and get a Hello World server running.</p>
|
||||
<h2>Getting httplib.h</h2>
|
||||
<p>You can download it directly from GitHub. Always use the latest version.</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>Place the downloaded <code>httplib.h</code> in your project directory and you're good to go.</p>
|
||||
<h2>Setting Up Your Compiler</h2>
|
||||
<table><thead><tr><th>OS</th><th>Development Environment</th><th>Setup</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++ or g++</td><td><code>apt install clang</code> or <code>apt install g++</code></td></tr>
|
||||
<tr><td>Windows</td><td>MSVC</td><td>Visual Studio 2022 or later (install with C++ components)</td></tr>
|
||||
</tbody></table>
|
||||
<h2>Hello World Server</h2>
|
||||
<p>Save the following code as <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>In just a few lines, you have a server that responds to HTTP requests.</p>
|
||||
<h2>Compiling and Running</h2>
|
||||
<p>The sample code in this tutorial is written in C++17 for cleaner, more concise code. cpp-httplib itself can compile with C++11 as well.</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 uses threads internally
|
||||
</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`: Enable C++ exception handling
|
||||
</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 uses threads internally
|
||||
</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`: Enable C++ exception handling
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#4f5b66;"> /EHsc /std:c++17 server.cpp
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>Once it compiles, run it.</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>Open <code>http://localhost:8080</code> in your browser. If you see "Hello, World!", you're all set.</p>
|
||||
<p>You can also verify with <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>To stop the server, press <code>Ctrl+C</code> in your terminal.</p>
|
||||
<h2>Next Steps</h2>
|
||||
<p>Now you know the basics of running a server. Next, let's look at the client side. cpp-httplib also comes with HTTP client functionality.</p>
|
||||
<p><strong>Next:</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/en/tour/02-basic-client/index.html
Normal file
491
docs/en/tour/02-basic-client/index.html
Normal file
@@ -0,0 +1,491 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="active">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/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 isn't just for servers -- it also comes with a full HTTP client. Let's use <code>httplib::Client</code> to send GET and POST requests.</p>
|
||||
<h2>Preparing a Test Server</h2>
|
||||
<p>To try out the client, you need a server that accepts requests. Save the following code, then compile and run it the same way you did in the previous chapter. We'll cover the server details in the next chapter.</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 Request</h2>
|
||||
<p>Once the server is running, open a separate terminal and give it a try. Let's start with the simplest GET request.</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>Pass the server address to the <code>httplib::Client</code> constructor, then call <code>Get()</code> to send a request. You can retrieve the status code and body from the returned <code>res</code>.</p>
|
||||
<p>Here's the equivalent <code>curl</code> command.</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>Checking the Response</h2>
|
||||
<p>A response contains header information in addition to the status code and body.</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;">// Status code
|
||||
</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;">// Body
|
||||
</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;">// Headers
|
||||
</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;">// Status code
|
||||
</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;">// Body
|
||||
</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;">// Headers
|
||||
</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> is a <code>std::string</code>, so if you want to parse a JSON response, you can pass it directly to a JSON library like <a href="https://github.com/nlohmann/json">nlohmann/json</a>.</p>
|
||||
<h2>Query Parameters</h2>
|
||||
<p>To add query parameters to a GET request, you can either write them directly in the URL or use <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> automatically URL-encodes special characters for you.</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>Path Parameters</h2>
|
||||
<p>When values are embedded directly in the URL path, no special client API is needed. Just pass the path to <code>Get()</code> as-is.</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>The test server also has a <code>/files/(\d+)</code> route that uses a regex to accept numeric IDs only.</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>Pass a non-numeric ID like <code>/files/abc</code> and you'll get a 404. We'll cover how that works in the next chapter.</p>
|
||||
<h2>Request Headers</h2>
|
||||
<p>To add custom HTTP headers, pass an <code>httplib::Headers</code> object. This works with both <code>Get()</code> and <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 Request</h2>
|
||||
<p>Let's POST some text data. Pass the body as the second argument to <code>Post()</code> and the Content-Type as the third.</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>The test server's <code>/post</code> endpoint echoes the body back, so you get the same string you sent.</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>Sending Form Data</h2>
|
||||
<p>You can send key-value pairs just like an HTML form. Use <code>httplib::Params</code> for this.</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>This sends the data in <code>application/x-www-form-urlencoded</code> format.</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>POSTing a File</h2>
|
||||
<p>To upload a file, use <code>httplib::UploadFormDataItems</code> to send it as multipart form data.</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>Each element in <code>UploadFormDataItems</code> has four fields: <code>{name, content, filename, content_type}</code>.</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>Error Handling</h2>
|
||||
<p>Network communication can fail -- the server might not be reachable. Always check whether <code>res</code> is valid.</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;">// Non-existent port
|
||||
</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;">// Connection error
|
||||
</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;">// If we reach here, we have a response
|
||||
</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;">// Non-existent port
|
||||
</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;">// Connection error
|
||||
</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;">// If we reach here, we have a response
|
||||
</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>There are two levels of errors.</p>
|
||||
<ul>
|
||||
<li><strong>Connection error</strong>: The client couldn't reach the server. <code>res</code> evaluates to false, and you can call <code>res.error()</code> to find out what went wrong.</li>
|
||||
<li><strong>HTTP error</strong>: The server returned an error status (404, 500, etc.). <code>res</code> evaluates to true, but you need to check <code>res->status</code>.</li>
|
||||
</ul>
|
||||
<h2>Next Steps</h2>
|
||||
<p>Now you know how to send requests from a client. Next, let's take a closer look at the server side. We'll dig into routing, path parameters, and more.</p>
|
||||
<p><strong>Next:</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/en/tour/03-basic-server/index.html
Normal file
446
docs/en/tour/03-basic-server/index.html
Normal file
@@ -0,0 +1,446 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="active">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>Basic Server</h1>
|
||||
<p>In the previous chapter, you sent requests from a client to a test server. Now let's walk through how that server actually works.</p>
|
||||
<h2>Starting the Server</h2>
|
||||
<p>Once you've registered your routes, call <code>svr.listen()</code> to start the server.</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>The first argument is the host, and the second is the port. <code>"0.0.0.0"</code> listens on all network interfaces. Use <code>"127.0.0.1"</code> if you want to accept connections from your own machine only.</p>
|
||||
<p><code>listen()</code> is a blocking call. It won't return until the server stops. The server keeps running until you press <code>Ctrl+C</code> in your terminal or call <code>svr.stop()</code> from another thread.</p>
|
||||
<h2>Routing</h2>
|
||||
<p>Routing is the heart of any server. It's how you tell cpp-httplib: when a request comes in for this URL with this HTTP method, run this code.</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> registers a handler for GET requests. The first argument is the path, the second is the handler function. When a GET request arrives at <code>/hi</code>, your lambda runs.</p>
|
||||
<p>There's a method for each HTTP verb.</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>The handler signature is <code>(const httplib::Request &req, httplib::Response &res)</code>. You can use <code>auto</code> to keep it short.</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>The handler only runs when the path matches. Requests to unregistered paths automatically return 404.</p>
|
||||
<h2>The Request Object</h2>
|
||||
<p>The first parameter <code>req</code> gives you everything the client sent.</p>
|
||||
<h3>Body</h3>
|
||||
<p><code>req.body</code> holds the request body as a <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;">// Echo the body back to the client
|
||||
</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;">// Echo the body back to the client
|
||||
</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>Headers</h3>
|
||||
<p>Use <code>req.get_header_value()</code> to read a request header.</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>Query Parameters and Form Data</h3>
|
||||
<p><code>req.get_param_value()</code> retrieves a parameter by name. It works for both GET query parameters and POST form data.</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>A request to <code>/search?q=cpp-httplib</code> gives you <code>"cpp-httplib"</code> for <code>q</code>.</p>
|
||||
<p>To loop over all parameters, use <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>File Uploads</h3>
|
||||
<p>Files uploaded via multipart form data are available through <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> gives you the filename, and <code>f.content</code> gives you the file data.</p>
|
||||
<h2>Path Parameters</h2>
|
||||
<p>Sometimes you want to capture part of the URL as a variable -- for example, the <code>42</code> in <code>/users/42</code>. Use the <code>:param</code> syntax to do that.</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>A request to <code>/users/42</code> gives you <code>"42"</code> from <code>req.path_params.at("id")</code>. <code>/users/100</code> gives you <code>"100"</code>.</p>
|
||||
<p>You can capture multiple segments at once.</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>Regex Patterns</h3>
|
||||
<p>You can also write a regular expression directly in the path instead of <code>:param</code>. Capture group values are available via <code>req.matches</code>, which is a <code>std::smatch</code>.</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// Only accept numeric IDs
|
||||
</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;">// First capture group
|
||||
</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;">// Only accept numeric IDs
|
||||
</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;">// First capture group
|
||||
</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> matches, but <code>/files/abc</code> doesn't. This is handy when you want to constrain what values are accepted.</p>
|
||||
<h2>Building a Response</h2>
|
||||
<p>The second parameter <code>res</code> is how you send data back to the client.</p>
|
||||
<h3>Body and Content-Type</h3>
|
||||
<p><code>res.set_content()</code> sets the body and Content-Type. That's all you need for a 200 response.</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>Status Code</h3>
|
||||
<p>To return a different status code, assign to <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>Response Headers</h3>
|
||||
<p>Add response headers with <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>Walking Through the Test Server</h2>
|
||||
<p>Now let's use what we've learned to read through the test server from the previous chapter.</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>The simplest possible handler. We don't need any information from the request, so the <code>req</code> parameter is left unnamed. It just returns <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> pulls out the query parameter <code>q</code>. A request to <code>/search?q=cpp-httplib</code> returns <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>An echo server. Whatever body the client sends, <code>req.body</code> holds it, and we send it straight back.</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>Loops over the form data in <code>req.params</code> using structured bindings (<code>auto &[key, val]</code>) to unpack each key-value pair.</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>Receives a file uploaded via multipart form data. <code>req.form.get_file("file")</code> fetches the field named <code>"file"</code>, and we respond with the filename and size.</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> is the path parameter. <code>req.path_params.at("id")</code> retrieves its value. <code>/users/42</code> gives you <code>"42"</code>, <code>/users/alice</code> gives you <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>The regex <code>(\d+)</code> matches numeric IDs only. <code>/files/42</code> hits this handler, but <code>/files/abc</code> returns 404. <code>req.matches[1]</code> retrieves the first capture group.</p>
|
||||
<h2>Next Steps</h2>
|
||||
<p>You now have the full picture of how a server works. Routing, reading requests, building responses -- that's enough to build a real API server.</p>
|
||||
<p>Next, let's look at serving static files. We'll build a server that delivers HTML and CSS.</p>
|
||||
<p><strong>Next:</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/en/tour/04-static-file-server/index.html
Normal file
269
docs/en/tour/04-static-file-server/index.html
Normal file
@@ -0,0 +1,269 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="active">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/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 can serve static files too — HTML, CSS, images, you name it. No complicated configuration required. One call to <code>set_mount_point()</code> is all it takes.</p>
|
||||
<h2>The basics of set_mount_point</h2>
|
||||
<p>Let's jump right in. <code>set_mount_point()</code> maps a URL path to a local directory.</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>The first argument is the URL mount point. The second is the local directory path. In this example, requests to <code>/</code> are served from the <code>./html</code> directory.</p>
|
||||
<p>Let's try it out. First, create an <code>html</code> directory and add an <code>index.html</code> file.</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>Compile and start the server.</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>Open <code>http://localhost:8080</code> in your browser. You should see the contents of <code>html/index.html</code>. Visiting <code>http://localhost:8080/index.html</code> returns the same page.</p>
|
||||
<p>You can also access it with the client code from the previous chapter, or with <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 is displayed
|
||||
</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 is displayed
|
||||
</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>Multiple mount points</h2>
|
||||
<p>You can call <code>set_mount_point()</code> as many times as you like. Each URL path gets its own directory.</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>A request to <code>/assets/style.css</code> serves <code>./static/assets/style.css</code>. A request to <code>/docs/guide.html</code> serves <code>./documentation/guide.html</code>.</p>
|
||||
<h2>Combining with handlers</h2>
|
||||
<p>Static file serving and routing handlers — the kind you learned about in the previous chapter — work side by side.</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 endpoint
|
||||
</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;">// Static file serving
|
||||
</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 endpoint
|
||||
</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;">// Static file serving
|
||||
</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>Handlers take priority. The handler responds to <code>/api/hello</code>. For every other path, the server looks for a file in <code>./public</code>.</p>
|
||||
<h2>Adding response headers</h2>
|
||||
<p>Pass headers as the third argument to <code>set_mount_point()</code> and they get attached to every static file response. This is great for cache control.</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>With this in place, the browser caches served files for one hour.</p>
|
||||
<h2>A Dockerfile for your static file server</h2>
|
||||
<p>The cpp-httplib repository includes a <code>Dockerfile</code> built for static file serving. We also publish a pre-built image on Docker Hub, so you can get up and running with a single command.</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>Everything in your <code>./my-site</code> directory gets served on port 8080. The access log follows the same format as NGINX, so you can see exactly what's happening.</p>
|
||||
<h2>What's next</h2>
|
||||
<p>You can now serve static files. A web server that delivers HTML, CSS, and JavaScript — built with this little code.</p>
|
||||
<p>Next, let's encrypt your connections with HTTPS. We'll start by setting up a TLS library.</p>
|
||||
<p><strong>Next:</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/en/tour/05-tls-setup/index.html
Normal file
193
docs/en/tour/05-tls-setup/index.html
Normal file
@@ -0,0 +1,193 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="active">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>TLS Setup</h1>
|
||||
<p>So far we've been using plain HTTP, but in the real world, HTTPS is the norm. To use HTTPS with cpp-httplib, you need a TLS library.</p>
|
||||
<p>In this tour, we'll use OpenSSL. It's the most widely used option, and you'll find plenty of resources online.</p>
|
||||
<h2>Installing OpenSSL</h2>
|
||||
<p>Install it for your OS.</p>
|
||||
<table><thead><tr><th>OS</th><th>How to install</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>Compile Options</h2>
|
||||
<p>To enable TLS, define the <code>CPPHTTPLIB_OPENSSL_SUPPORT</code> macro when compiling. You'll need a few extra options compared to the previous chapters.</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>Let's look at what each option does.</p>
|
||||
<ul>
|
||||
<li><strong><code>-DCPPHTTPLIB_OPENSSL_SUPPORT</code></strong> — Defines the macro that enables TLS support</li>
|
||||
<li><strong><code>-lssl -lcrypto</code></strong> — Links the OpenSSL libraries</li>
|
||||
<li><strong><code>-I</code> / <code>-L</code></strong> (macOS only) — Points to the Homebrew OpenSSL paths</li>
|
||||
<li><strong><code>-framework CoreFoundation -framework Security</code></strong> (macOS only) — Needed to automatically load system certificates from the Keychain</li>
|
||||
</ul>
|
||||
<h2>Verifying the Setup</h2>
|
||||
<p>Let's make sure everything works. Here's a simple program that passes an HTTPS URL to <code>httplib::Client</code>.</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>Compile and run it. If you see <code>Status: 200</code>, your setup is complete.</p>
|
||||
<h2>Other TLS Backends</h2>
|
||||
<p>cpp-httplib also supports Mbed TLS and wolfSSL in addition to OpenSSL. You can switch between them just by changing the macro definition and linked libraries.</p>
|
||||
<table><thead><tr><th style="text-align: left">Backend</th><th style="text-align: left">Macro</th><th style="text-align: left">Libraries to link</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>This tour assumes OpenSSL, but the API is the same regardless of which backend you choose.</p>
|
||||
<h2>Next Step</h2>
|
||||
<p>You're all set with TLS. Next, let's send a request to an HTTPS site.</p>
|
||||
<p><strong>Next:</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/en/tour/06-https-client/index.html
Normal file
251
docs/en/tour/06-https-client/index.html
Normal file
@@ -0,0 +1,251 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="active">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>HTTPS Client</h1>
|
||||
<p>In the previous chapter, you set up OpenSSL. Now let's put it to use with an HTTPS client. You can use the same <code>httplib::Client</code> from Chapter 2. Just pass a URL with the <code>https://</code> scheme to the constructor.</p>
|
||||
<h2>GET Request</h2>
|
||||
<p>Let's try accessing a real HTTPS site.</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;">// First 100 chars of the 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;">// First 100 chars of the 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>In Chapter 2, you wrote <code>httplib::Client cli("http://localhost:8080")</code>. All you need to change is the scheme to <code>https://</code>. Every API you learned in Chapter 2 -- <code>Get()</code>, <code>Post()</code>, and so on -- works exactly the same way.</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>Specifying a Port</h2>
|
||||
<p>The default port for HTTPS is 443. If you need a different port, include it in the 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 Certificate Verification</h2>
|
||||
<p>When connecting over HTTPS, <code>httplib::Client</code> verifies the server certificate by default. It only connects to servers whose certificate was issued by a trusted CA (Certificate Authority).</p>
|
||||
<p>CA certificates are loaded automatically from the Keychain on macOS, the system CA certificate store on Linux, and the Windows certificate store on Windows. In most cases, no extra configuration is needed.</p>
|
||||
<h3>Specifying a CA Certificate File</h3>
|
||||
<p>On some environments, the system CA certificates may not be found. In that case, use <code>set_ca_cert_path()</code> to specify the path directly.</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>Disabling Certificate Verification</h3>
|
||||
<p>During development, you might want to connect to a server with a self-signed certificate. You can disable verification for that.</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>Never disable this in production. It opens you up to man-in-the-middle attacks.</p>
|
||||
<h2>Following Redirects</h2>
|
||||
<p>When accessing HTTPS sites, you'll often encounter redirects. For example, <code>http://</code> to <code>https://</code>, or a bare domain to <code>www</code>.</p>
|
||||
<p>By default, redirects are not followed. You can check the redirect target in the <code>Location</code> header.</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>Call <code>set_follow_location(true)</code> to automatically follow redirects and get the final response.</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 (the final response)
|
||||
</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 (the final response)
|
||||
</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>Next Steps</h2>
|
||||
<p>Now you know how to use the HTTPS client. Next, let's set up your own HTTPS server. We'll start with creating a self-signed certificate.</p>
|
||||
<p><strong>Next:</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/en/tour/07-https-server/index.html
Normal file
240
docs/en/tour/07-https-server/index.html
Normal file
@@ -0,0 +1,240 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="active">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>HTTPS Server</h1>
|
||||
<p>In the previous chapter, you used an HTTPS client. Now let's set up your own HTTPS server. Just swap <code>httplib::Server</code> from Chapter 3 with <code>httplib::SSLServer</code>.</p>
|
||||
<p>A TLS server needs a server certificate and a private key, though. Let's get those ready first.</p>
|
||||
<h2>Creating a Self-Signed Certificate</h2>
|
||||
<p>For development and testing, a self-signed certificate works just fine. You can generate one quickly with an OpenSSL command.</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>This creates two files:</p>
|
||||
<ul>
|
||||
<li><strong><code>cert.pem</code></strong> — Server certificate</li>
|
||||
<li><strong><code>key.pem</code></strong> — Private key</li>
|
||||
</ul>
|
||||
<h2>A Minimal HTTPS Server</h2>
|
||||
<p>Once you have your certificate, let's write the server.</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>Just pass the certificate and private key paths to the <code>httplib::SSLServer</code> constructor. The routing API is exactly the same as <code>httplib::Server</code> from Chapter 3.</p>
|
||||
<p>Compile and start it up.</p>
|
||||
<h2>Testing It Out</h2>
|
||||
<p>With the server running, try accessing it with <code>curl</code>. Since we're using a self-signed certificate, add the <code>-k</code> option to skip certificate verification.</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>If you open <code>https://localhost:8443</code> in a browser, you'll see a "This connection is not secure" warning. That's expected with a self-signed certificate. Just proceed past it.</p>
|
||||
<h2>Connecting from a Client</h2>
|
||||
<p>Let's connect using <code>httplib::Client</code> from the previous chapter. There are two ways to connect to a server with a self-signed certificate.</p>
|
||||
<h3>Option 1: Disable Certificate Verification</h3>
|
||||
<p>This is the quick and easy approach for development.</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>Option 2: Specify the Self-Signed Certificate as a CA Certificate</h3>
|
||||
<p>This is the safer approach. You tell the client to trust <code>cert.pem</code> as a CA certificate.</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>This way, only connections to the server with that specific certificate are allowed, preventing impersonation. Use this approach whenever possible, even in test environments.</p>
|
||||
<h2>Comparing Server and SSLServer</h2>
|
||||
<p>The <code>httplib::Server</code> API you learned in Chapter 3 works exactly the same with <code>httplib::SSLServer</code>. The only difference is the constructor.</p>
|
||||
<table><thead><tr><th></th><th><code>httplib::Server</code></th><th><code>httplib::SSLServer</code></th></tr></thead><tbody>
|
||||
<tr><td>Constructor</td><td>No arguments</td><td>Certificate and private key paths</td></tr>
|
||||
<tr><td>Protocol</td><td>HTTP</td><td>HTTPS</td></tr>
|
||||
<tr><td>Port (convention)</td><td>8080</td><td>8443</td></tr>
|
||||
<tr><td>Routing</td><td>Same</td><td>Same</td></tr>
|
||||
</tbody></table>
|
||||
<p>To switch an HTTP server to HTTPS, just change the constructor.</p>
|
||||
<h2>Next Steps</h2>
|
||||
<p>Your HTTPS server is up and running. You now have the basics of both HTTP/HTTPS clients and servers covered.</p>
|
||||
<p>Next, let's look at the WebSocket support that was recently added to cpp-httplib.</p>
|
||||
<p><strong>Next:</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/en/tour/08-websocket/index.html
Normal file
292
docs/en/tour/08-websocket/index.html
Normal file
@@ -0,0 +1,292 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="active">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/tour/09-whats-next/" class="">What's Next</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>WebSocket</h1>
|
||||
<p>cpp-httplib supports WebSocket as well. Unlike HTTP request/response, WebSocket lets the server and client exchange messages in both directions. It's great for chat apps and real-time notifications.</p>
|
||||
<p>Let's build an echo server and client right away.</p>
|
||||
<h2>Echo Server</h2>
|
||||
<p>Here's an echo server that sends back whatever message it receives.</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;">// Send back the received message as-is
|
||||
</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;">// Send back the received message as-is
|
||||
</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>You register a WebSocket handler with <code>svr.WebSocket()</code>. It works just like <code>svr.Get()</code> and <code>svr.Post()</code> from Chapter 3.</p>
|
||||
<p>Inside the handler, <code>ws.read(msg)</code> waits for a message. When the connection closes, <code>read()</code> returns <code>false</code>, so the loop exits. <code>ws.send(msg)</code> sends a message back.</p>
|
||||
<h2>Connecting from a Client</h2>
|
||||
<p>Let's connect to the server using <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;">// Send a message
|
||||
</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;">// Receive a response from the server
|
||||
</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;">// Send a message
|
||||
</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;">// Receive a response from the server
|
||||
</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>Pass a URL in <code>ws://host:port/path</code> format to the constructor. Call <code>connect()</code> to start the connection, then use <code>send()</code> and <code>read()</code> to exchange messages.</p>
|
||||
<h2>Text and Binary</h2>
|
||||
<p>WebSocket has two types of messages: text and binary. You can tell them apart by the return value of <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;">// Send as binary
|
||||
</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;">// Send as text
|
||||
</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;">// Send as binary
|
||||
</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;">// Send as text
|
||||
</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> — sends as a text message</li>
|
||||
<li><code>ws.send(const char *, size_t)</code> — sends as a binary message</li>
|
||||
</ul>
|
||||
<p>The client-side API is the same.</p>
|
||||
<h2>Accessing Request Information</h2>
|
||||
<p>You can read HTTP request information from the handshake through the first argument <code>req</code> in the handler. This is handy for checking authentication tokens.</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>Using WSS</h2>
|
||||
<p>WebSocket over HTTPS (WSS) is also supported. On the server side, just register a WebSocket handler on <code>httplib::SSLServer</code>.</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>On the client side, use the <code>wss://</code> scheme.</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>Next Steps</h2>
|
||||
<p>Now you know the basics of WebSocket. This wraps up the Tour.</p>
|
||||
<p>The next page gives you a summary of features we didn't cover in the Tour.</p>
|
||||
<p><strong>Next:</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/en/tour/09-whats-next/index.html
Normal file
424
docs/en/tour/09-whats-next/index.html
Normal file
@@ -0,0 +1,424 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/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>Great job finishing the Tour! You now have a solid grasp of the cpp-httplib basics. But there's a lot more to explore. Here's a quick overview of features we didn't cover in the Tour, organized by category.</p>
|
||||
<h2>Streaming API</h2>
|
||||
<p>When you're working with LLM streaming responses or downloading large files, you don't want to load the entire response into memory. Use <code>stream::Get()</code> to process data chunk by chunk.</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>You can also pass a <code>content_receiver</code> callback to <code>Get()</code>. This approach works with 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>On the server side, you have <code>set_content_provider()</code> and <code>set_chunked_content_provider()</code>. Use the former when you know the size, and the latter when you don't.</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// With known size (sets 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;">// Send 'length' bytes starting from 'offset'
|
||||
</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;">// Unknown size (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;">// Return false to finish
|
||||
</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;">// With known size (sets 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;">// Send 'length' bytes starting from 'offset'
|
||||
</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;">// Unknown size (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;">// Return false to finish
|
||||
</span><span style="color:#4f5b66;"> });
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>For uploading large files, <code>make_file_provider()</code> comes in handy. It streams the file instead of loading it all into memory.</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>We provide an SSE client as well. It supports automatic reconnection and resuming via <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;">// Blocking, with auto-reconnection
|
||||
</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;">// Blocking, with auto-reconnection
|
||||
</span></pre>
|
||||
</div>
|
||||
<p>You can also set separate handlers for each event type.</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;">// Only handles "update" events
|
||||
</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;">// Only handles "update" events
|
||||
</span><span style="color:#4f5b66;">});
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>Authentication</h2>
|
||||
<p>The client has helpers for Basic auth, Bearer Token auth, and Digest auth.</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>Compression</h2>
|
||||
<p>We support compression and decompression with gzip, Brotli, and Zstandard. Define the corresponding macro when you compile.</p>
|
||||
<table><thead><tr><th>Method</th><th>Macro</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;">// Compress request body
|
||||
</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;">// Decompress response body
|
||||
</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;">// Compress request body
|
||||
</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;">// Decompress response body
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>Proxy</h2>
|
||||
<p>You can connect through an HTTP proxy.</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>Timeouts</h2>
|
||||
<p>You can set connection, read, and write timeouts individually.</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 seconds
|
||||
</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 seconds
|
||||
</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 seconds
|
||||
</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 seconds
|
||||
</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 seconds
|
||||
</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 seconds
|
||||
</span></pre>
|
||||
</div>
|
||||
<h2>Keep-Alive</h2>
|
||||
<p>If you're making multiple requests to the same server, enable Keep-Alive. It reuses the TCP connection, which is much more efficient.</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>Server Middleware</h2>
|
||||
<p>You can hook into request processing before and after handlers run.</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;">// Runs before every request
|
||||
</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;">// Continue to normal routing
|
||||
</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;">// Runs after the response is sent
|
||||
</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;">// Runs before every request
|
||||
</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;">// Continue to normal routing
|
||||
</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;">// Runs after the response is sent
|
||||
</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>Use <code>req.user_data</code> to pass data from middleware to handlers. This is useful for sharing things like decoded auth tokens.</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>You can also customize error and exception handlers.</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>Logging</h2>
|
||||
<p>You can set a logger on both the server and the client.</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>In addition to TCP, we support Unix Domain Sockets. You can use them for inter-process communication on the same machine.</p>
|
||||
<div class="code-dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// Server
|
||||
</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;">// Server
|
||||
</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;">// Client
|
||||
</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;">// Client
|
||||
</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>Learn More</h2>
|
||||
<p>Want to dig deeper? Check out these resources.</p>
|
||||
<ul>
|
||||
<li>Cookbook — A collection of recipes for common use cases</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README.md">README</a> — Full API reference</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README-sse.md">README-sse</a> — How to use Server-Sent Events</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README-stream.md">README-stream</a> — How to use the Streaming API</li>
|
||||
<li><a href="https://github.com/yhirose/cpp-httplib/blob/master/README-websocket.md">README-websocket</a> — How to use the WebSocket server</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2025 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
105
docs/en/tour/index.html
Normal file
105
docs/en/tour/index.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/en/" 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="/en/">Home</a>
|
||||
<a href="/en/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">EN</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="/en/tour/" class="nav-section-title active">A Tour of cpp-httplib</a>
|
||||
|
||||
<ul class="nav-list">
|
||||
|
||||
<li><a href="/en/tour/01-getting-started/" class="">Getting Started</a></li>
|
||||
|
||||
<li><a href="/en/tour/02-basic-client/" class="">Basic Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/03-basic-server/" class="">Basic Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/04-static-file-server/" class="">Static File Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/05-tls-setup/" class="">TLS Setup</a></li>
|
||||
|
||||
<li><a href="/en/tour/06-https-client/" class="">HTTPS Client</a></li>
|
||||
|
||||
<li><a href="/en/tour/07-https-server/" class="">HTTPS Server</a></li>
|
||||
|
||||
<li><a href="/en/tour/08-websocket/" class="">WebSocket</a></li>
|
||||
|
||||
<li><a href="/en/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>This is a step-by-step tutorial that walks you through the basics of cpp-httplib. Each chapter builds on the previous one, so please read them in order starting from Chapter 1.</p>
|
||||
<ol>
|
||||
<li><a href="01-getting-started">Getting Started</a> — Get httplib.h and build a Hello World server</li>
|
||||
<li><a href="02-basic-client">Basic Client</a> — Send GET/POST requests and use path parameters</li>
|
||||
<li><a href="03-basic-server">Basic Server</a> — Routing, path parameters, and building responses</li>
|
||||
<li><a href="04-static-file-server">Static File Server</a> — Serve static files</li>
|
||||
<li><a href="05-tls-setup">TLS Setup</a> — Set up OpenSSL / mbedTLS</li>
|
||||
<li><a href="06-https-client">HTTPS Client</a> — Make requests to HTTPS sites</li>
|
||||
<li><a href="07-https-server">HTTPS Server</a> — Build an HTTPS server</li>
|
||||
<li><a href="08-websocket">WebSocket</a> — Learn the basics of WebSocket communication</li>
|
||||
<li><a href="09-whats-next">What's Next</a> — Explore more features</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