mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-04-14 12:48:31 +00:00
Remove docs-gen
This commit is contained in:
1992
docs-gen/Cargo.lock
generated
1992
docs-gen/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
||||
[package]
|
||||
name = "docs-gen"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
pulldown-cmark = "0.12"
|
||||
tera = "1"
|
||||
walkdir = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
serde_yaml = "0.9"
|
||||
toml = "0.8"
|
||||
syntect = "5"
|
||||
anyhow = "1"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
notify = "7"
|
||||
tiny_http = "0.12"
|
||||
tungstenite = "0.24"
|
||||
open = "5"
|
||||
tempfile = "3"
|
||||
socket2 = { version = "0.5", features = ["all"] }
|
||||
@@ -1,254 +0,0 @@
|
||||
# docs-gen
|
||||
|
||||
A static site generator for multi-language documentation. Markdown content, Tera templates, and syntax highlighting — all in a single binary.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Scaffold a new project
|
||||
docs-gen init my-docs
|
||||
|
||||
# 2. Start the local dev server with live-reload
|
||||
docs-gen serve my-docs --open
|
||||
|
||||
# 3. Build for production
|
||||
docs-gen build my-docs --out docs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
### `init [DIR]`
|
||||
|
||||
Creates a new project scaffold in `DIR` (default: `.`).
|
||||
|
||||
Generated files:
|
||||
|
||||
```
|
||||
config.toml
|
||||
pages/
|
||||
en/index.md
|
||||
ja/index.md
|
||||
templates/
|
||||
base.html
|
||||
page.html
|
||||
portal.html
|
||||
static/
|
||||
css/main.css
|
||||
js/main.js
|
||||
```
|
||||
|
||||
Existing files are never overwritten.
|
||||
|
||||
---
|
||||
|
||||
### `serve [SRC] [--port PORT] [--open]`
|
||||
|
||||
Builds the site into a temporary directory and serves it locally. Watches for changes and live-reloads the browser automatically.
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `SRC` | `.` | Source directory |
|
||||
| `--port` | `8080` | HTTP server port |
|
||||
| `--open` | — | Open browser on startup |
|
||||
|
||||
---
|
||||
|
||||
### `build [SRC] [--out OUT]`
|
||||
|
||||
Generates the static site from source.
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `SRC` | `.` | Source directory |
|
||||
| `--out` | `docs` | Output directory |
|
||||
|
||||
---
|
||||
|
||||
## Source Directory Structure
|
||||
|
||||
Only `config.toml` and `pages/` are required. `templates/` and `static/` are optional — when absent, built-in defaults are used automatically.
|
||||
|
||||
```
|
||||
my-docs/
|
||||
├── config.toml # Site configuration (required)
|
||||
├── pages/ # Markdown content (required)
|
||||
│ ├── en/
|
||||
│ │ ├── index.md # Portal page (homepage, no sidebar)
|
||||
│ │ └── guide/
|
||||
│ │ ├── index.md # Section index
|
||||
│ │ ├── 01-intro.md
|
||||
│ │ └── 02-usage.md
|
||||
│ └── ja/
|
||||
│ └── ...
|
||||
├── templates/ # Override built-in HTML templates (optional)
|
||||
│ ├── base.html
|
||||
│ ├── page.html
|
||||
│ └── portal.html
|
||||
└── static/ # Override built-in CSS/JS/assets (optional)
|
||||
├── css/main.css
|
||||
└── js/main.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## config.toml
|
||||
|
||||
```toml
|
||||
[site]
|
||||
title = "My Project"
|
||||
version = "1.0.0" # Optional. Shown in header.
|
||||
hostname = "https://example.github.io" # Optional. Combined with base_path for full URLs.
|
||||
base_path = "/my-project" # URL prefix. Use "" for local-only.
|
||||
|
||||
[[nav]]
|
||||
label = "Guide"
|
||||
path = "guide/" # Internal section path (resolved per language)
|
||||
icon_svg = '<svg ...>...</svg>' # Optional inline SVG icon
|
||||
|
||||
[[nav]]
|
||||
label = "GitHub"
|
||||
url = "https://github.com/your/repo" # External URL
|
||||
icon_svg = '<svg ...>...</svg>'
|
||||
|
||||
[i18n]
|
||||
langs = ["en", "ja"] # First entry is the default language
|
||||
|
||||
[highlight]
|
||||
dark_theme = "base16-eighties.dark" # Dark mode theme
|
||||
light_theme = "InspiredGitHub" # Light mode theme (optional)
|
||||
```
|
||||
|
||||
### `[site]`
|
||||
|
||||
| Key | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `title` | yes | Site title displayed in the header |
|
||||
| `version` | no | Version string displayed in the header |
|
||||
| `hostname` | no | Base hostname (e.g. `"https://user.github.io"`). Combined with `base_path` to form `site.base_url` in templates. |
|
||||
| `base_path` | no | URL path prefix. Use `"/repo-name"` for GitHub Pages, `""` for local development. |
|
||||
|
||||
### `[[nav]]` — Toolbar Buttons
|
||||
|
||||
Defines buttons in the site header. Each entry supports:
|
||||
|
||||
| Key | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `label` | yes | Button label text |
|
||||
| `path` | no | Internal section path relative to `<lang>/` (e.g. `"guide/"`). Resolved using the current language. |
|
||||
| `url` | no | Absolute external URL. Takes precedence over `path` if both are set. |
|
||||
| `icon_svg` | no | Inline SVG markup displayed as an icon |
|
||||
|
||||
### `[i18n]`
|
||||
|
||||
| Key | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `langs` | yes | List of language codes. At least one is required. The first entry is used as the default language. |
|
||||
|
||||
### `[highlight]`
|
||||
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `dark_theme` | `base16-ocean.dark` | Theme for dark mode |
|
||||
| `light_theme` | _(none)_ | Theme for light mode. When set, both dark and light code blocks are emitted and toggled via CSS. |
|
||||
|
||||
Available themes: `base16-ocean.dark`, `base16-ocean.light`, `base16-eighties.dark`, `base16-mocha.dark`, `InspiredGitHub`, `Solarized (dark)`, `Solarized (light)`.
|
||||
|
||||
---
|
||||
|
||||
## Writing Pages
|
||||
|
||||
### Frontmatter
|
||||
|
||||
Every `.md` file must begin with YAML frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Getting Started"
|
||||
order: 1
|
||||
---
|
||||
|
||||
Page content goes here...
|
||||
```
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| `title` | yes | Page title shown in the heading and browser tab |
|
||||
| `order` | no | Sort order within the section (default: `0`) |
|
||||
| `status` | no | Set to `"draft"` to display a DRAFT banner |
|
||||
|
||||
### URL Routing
|
||||
|
||||
Files are mapped to URLs as follows:
|
||||
|
||||
| File | URL |
|
||||
|------|-----|
|
||||
| `en/index.md` | `<base_path>/en/` |
|
||||
| `en/guide/index.md` | `<base_path>/en/guide/` |
|
||||
| `en/guide/01-intro.md` | `<base_path>/en/guide/01-intro/` |
|
||||
|
||||
The root `index.html` is generated automatically and redirects to the default language, respecting the user's `localStorage` language preference.
|
||||
|
||||
### Sidebar Navigation
|
||||
|
||||
Sidebar navigation is generated automatically:
|
||||
|
||||
- Each subdirectory under a language becomes a **section**
|
||||
- The section's `index.md` title is used as the section heading
|
||||
- Pages within a section are sorted by `order`, then by filename
|
||||
- `index.md` at the language root uses `portal.html` (no sidebar)
|
||||
- All other pages use `page.html` (with sidebar)
|
||||
|
||||
---
|
||||
|
||||
## Customizing Templates and Assets
|
||||
|
||||
When `templates/` or `static/` directories exist in the source, files there override the built-in defaults. Use `docs-gen init` to generate the defaults as a starting point.
|
||||
|
||||
Three templates are available:
|
||||
|
||||
| Template | Used for |
|
||||
|----------|----------|
|
||||
| `base.html` | Shared layout: `<head>`, header, footer, scripts |
|
||||
| `page.html` | Content pages with sidebar |
|
||||
| `portal.html` | Homepage (`index.md` at language root), no sidebar |
|
||||
|
||||
---
|
||||
|
||||
## Template Variables
|
||||
|
||||
Templates use [Tera](https://keats.github.io/tera/) syntax. Available variables:
|
||||
|
||||
### All templates
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `page.title` | string | Page title from frontmatter |
|
||||
| `page.url` | string | Page URL path |
|
||||
| `page.status` | string? | `"draft"` or null |
|
||||
| `content` | string | Rendered HTML (use `{{ content \| safe }}`) |
|
||||
| `lang` | string | Current language code |
|
||||
| `site.title` | string | Site title |
|
||||
| `site.version` | string? | Site version |
|
||||
| `site.base_url` | string | Full base URL (`hostname` + `base_path`) |
|
||||
| `site.base_path` | string | URL path prefix |
|
||||
| `site.langs` | list | All language codes |
|
||||
| `site.nav` | list | Toolbar button entries |
|
||||
| `site.nav[].label` | string | Button label |
|
||||
| `site.nav[].url` | string? | External URL (if set) |
|
||||
| `site.nav[].path` | string? | Internal section path (if set) |
|
||||
| `site.nav[].icon_svg` | string? | Inline SVG icon (if set) |
|
||||
|
||||
### `page.html` only
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `nav` | list | Sidebar sections |
|
||||
| `nav[].title` | string | Section title |
|
||||
| `nav[].url` | string | Section index URL |
|
||||
| `nav[].active` | bool | True if this section contains the current page |
|
||||
| `nav[].children` | list | Pages within this section |
|
||||
| `nav[].children[].title` | string | Page title |
|
||||
| `nav[].children[].url` | string | Page URL |
|
||||
| `nav[].children[].active` | bool | True if this is the current page |
|
||||
@@ -1,20 +0,0 @@
|
||||
[site]
|
||||
title = "My Docs"
|
||||
hostname = "https://example.github.io"
|
||||
base_path = "/my-project"
|
||||
|
||||
# [[nav]]
|
||||
# label = "Guide"
|
||||
# path = "guide/"
|
||||
#
|
||||
# [[nav]]
|
||||
# label = "GitHub"
|
||||
# url = "https://github.com/your/repo"
|
||||
# icon_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>'
|
||||
|
||||
[i18n]
|
||||
langs = ["en"]
|
||||
|
||||
[highlight]
|
||||
dark_theme = "base16-ocean.dark"
|
||||
light_theme = "InspiredGitHub"
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: Welcome
|
||||
order: 0
|
||||
---
|
||||
|
||||
## Welcome
|
||||
|
||||
This is the home page of your documentation site.
|
||||
|
||||
Edit this file at `pages/en/index.md` to get started.
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: ようこそ
|
||||
order: 0
|
||||
---
|
||||
|
||||
## ようこそ
|
||||
|
||||
ドキュメントサイトのトップページです。
|
||||
|
||||
`pages/ja/index.md` を編集して始めましょう。
|
||||
@@ -1,603 +0,0 @@
|
||||
:root {
|
||||
--bg: #333;
|
||||
--bg-secondary: #3c3c3c;
|
||||
--bg-code: #2a2a2a;
|
||||
--text: #ccc;
|
||||
--text-bright: white;
|
||||
--text-muted: #999;
|
||||
--text-code: #b0b0b0;
|
||||
--text-inline-code: plum;
|
||||
--border: #555;
|
||||
--border-code: #3a3a3a;
|
||||
--link: palegoldenrod;
|
||||
--heading: lightskyblue;
|
||||
--heading-link: #f0c090;
|
||||
--header-nav-link: pink;
|
||||
--emphasis: pink;
|
||||
--nav-section: #bbb;
|
||||
--nav-section-active: #ddd;
|
||||
--content-width: 900px;
|
||||
--sidebar-width: 280px;
|
||||
--header-height: 48px;
|
||||
--line-height: 1.6;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
line-height: var(--line-height);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: var(--header-height);
|
||||
background-color: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--border);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
color: var(--text);
|
||||
font-weight: bold;
|
||||
font-size: 1.1rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.header-title:hover {
|
||||
text-decoration: none;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.header-nav a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--header-nav-link);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.header-nav a svg {
|
||||
flex-shrink: 0;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.header-tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.lang-selector {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lang-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text);
|
||||
padding: 4px 6px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.lang-btn:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lang-popup {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
margin-top: 4px;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
list-style: none;
|
||||
min-width: 60px;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.lang-popup.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lang-popup li a {
|
||||
display: block;
|
||||
padding: 6px 12px;
|
||||
color: var(--text);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.lang-popup li a:hover {
|
||||
background: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
display: none;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text);
|
||||
font-size: 1.2rem;
|
||||
cursor: pointer;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
/* Draft banner */
|
||||
.draft-banner {
|
||||
position: fixed;
|
||||
top: var(--header-height);
|
||||
right: 0;
|
||||
background: #c44;
|
||||
color: white;
|
||||
padding: 4px 16px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.1em;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
.layout {
|
||||
margin-top: var(--header-height);
|
||||
display: grid;
|
||||
grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
|
||||
min-height: calc(100vh - var(--header-height));
|
||||
}
|
||||
|
||||
.layout.no-sidebar {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
width: var(--sidebar-width);
|
||||
flex-shrink: 0;
|
||||
padding: 24px 16px;
|
||||
border-right: 1px solid var(--bg-secondary);
|
||||
position: sticky;
|
||||
top: var(--header-height);
|
||||
height: calc(100vh - var(--header-height));
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.nav-section {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.nav-section-title {
|
||||
color: var(--nav-section);
|
||||
font-weight: bold;
|
||||
font-size: 1.0rem;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.nav-section-title.active {
|
||||
color: var(--nav-section-active);
|
||||
}
|
||||
|
||||
.nav-list {
|
||||
list-style: none;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.nav-list li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.nav-list li a {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.nav-list li a:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.nav-list li a.active {
|
||||
color: var(--emphasis);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Content */
|
||||
.content {
|
||||
min-width: 0;
|
||||
max-width: var(--content-width);
|
||||
padding: 32px 24px;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.content.portal {
|
||||
max-width: var(--content-width);
|
||||
padding: 48px 24px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.content article h1 {
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 24px;
|
||||
color: var(--heading);
|
||||
}
|
||||
|
||||
.content article h2 {
|
||||
font-size: 1.4rem;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 16px;
|
||||
color: var(--heading-link);
|
||||
}
|
||||
|
||||
.content article h3 {
|
||||
font-size: 1.1rem;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.content article p {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.content article ul,
|
||||
.content article ol {
|
||||
margin-bottom: 12px;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.content article li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.content article strong {
|
||||
color: var(--emphasis);
|
||||
}
|
||||
|
||||
.content article code {
|
||||
background: var(--bg-code);
|
||||
color: var(--text-inline-code);
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.content article pre {
|
||||
background: var(--bg-code);
|
||||
color: var(--text-code);
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 16px;
|
||||
border: 1px solid var(--border-code);
|
||||
}
|
||||
|
||||
.content article pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content article table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.content article th,
|
||||
.content article td {
|
||||
border: 1px solid var(--bg-secondary);
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content article th {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.content article blockquote {
|
||||
border-left: 3px solid var(--text-muted);
|
||||
padding-left: 16px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Code block theme switching: show dark by default, swap on light mode */
|
||||
.code-block-wrapper > [data-code-theme="light"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html[data-theme="light"] .code-block-wrapper > [data-code-theme="dark"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html[data-theme="light"] .code-block-wrapper > [data-code-theme="light"] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
padding: 12px 16px;
|
||||
text-align: center;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.8rem;
|
||||
border-top: 1px solid var(--bg-secondary);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.layout {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: calc(-1 * var(--sidebar-width));
|
||||
width: var(--sidebar-width);
|
||||
top: var(--header-height);
|
||||
height: calc(100vh - var(--header-height));
|
||||
background: var(--bg);
|
||||
z-index: 50;
|
||||
transition: left 0.2s ease;
|
||||
border-right: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.sidebar.open {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
:root {
|
||||
--header-height: 44px;
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
padding: 0 12px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.header-nav a {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.content article h1 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.content article h2 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Light mode */
|
||||
[data-theme="light"] {
|
||||
--bg: #f5f5f5;
|
||||
--bg-secondary: #e8e8e8;
|
||||
--bg-code: #eee;
|
||||
--text: #333;
|
||||
--text-bright: #000;
|
||||
--text-muted: #666;
|
||||
--text-code: #333;
|
||||
--text-inline-code: #8b5ca0;
|
||||
--border: #ccc;
|
||||
--border-code: #ddd;
|
||||
--link: #b8860b;
|
||||
--heading: #2a6496;
|
||||
--heading-link: #c06020;
|
||||
--header-nav-link: #c04060;
|
||||
--emphasis: #c04060;
|
||||
--nav-section: #666;
|
||||
--nav-section-active: #333;
|
||||
}
|
||||
|
||||
/* Theme toggle */
|
||||
.theme-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text);
|
||||
padding: 5px 6px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.theme-toggle:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Search button */
|
||||
.search-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text);
|
||||
padding: 5px 6px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.search-btn:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Search overlay & modal */
|
||||
.search-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 300;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding-top: 12vh;
|
||||
}
|
||||
|
||||
.search-overlay.open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.search-modal {
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
width: 90%;
|
||||
max-width: 560px;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.search-input-wrap svg {
|
||||
flex-shrink: 0;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
flex: 1;
|
||||
background: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: var(--text-bright);
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
#search-input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.search-esc {
|
||||
background: var(--bg);
|
||||
color: var(--text-muted);
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 0.7rem;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.search-results {
|
||||
list-style: none;
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.search-results:empty::after {
|
||||
content: "";
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search-results li {
|
||||
padding: 10px 16px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.search-results li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.search-results li:hover,
|
||||
.search-results li.active {
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
.search-results li .search-result-title {
|
||||
color: var(--text-bright);
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.search-results li .search-result-snippet {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.4;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.search-results li .search-result-snippet mark {
|
||||
background: rgba(255, 215, 0, 0.3);
|
||||
color: var(--text-bright);
|
||||
border-radius: 2px;
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
[data-theme="light"] .search-results li .search-result-snippet mark {
|
||||
background: rgba(255, 200, 0, 0.4);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.search-no-results {
|
||||
padding: 24px 16px;
|
||||
text-align: center;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,297 +0,0 @@
|
||||
// Language selector
|
||||
(function () {
|
||||
var btn = document.querySelector('.lang-btn');
|
||||
var popup = document.querySelector('.lang-popup');
|
||||
if (!btn || !popup) return;
|
||||
|
||||
btn.addEventListener('click', function (e) {
|
||||
e.stopPropagation();
|
||||
popup.classList.toggle('open');
|
||||
});
|
||||
|
||||
document.addEventListener('click', function () {
|
||||
popup.classList.remove('open');
|
||||
});
|
||||
|
||||
popup.addEventListener('click', function (e) {
|
||||
var link = e.target.closest('[data-lang]');
|
||||
if (!link) return;
|
||||
e.preventDefault();
|
||||
var lang = link.getAttribute('data-lang');
|
||||
localStorage.setItem('preferred-lang', lang);
|
||||
var basePath = document.documentElement.getAttribute('data-base-path') || '';
|
||||
var path = window.location.pathname;
|
||||
// Strip base path prefix, replace lang, then re-add base path
|
||||
var pathWithoutBase = path.slice(basePath.length);
|
||||
var newPath = basePath + pathWithoutBase.replace(/^\/[a-z]{2}\//, '/' + lang + '/');
|
||||
window.location.href = newPath;
|
||||
});
|
||||
})();
|
||||
|
||||
// Theme toggle
|
||||
(function () {
|
||||
var btn = document.querySelector('.theme-toggle');
|
||||
if (!btn) return;
|
||||
|
||||
// Feather Icons: sun (light mode) and moon (dark mode)
|
||||
var sunSVG = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>';
|
||||
var moonSVG = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>';
|
||||
|
||||
function getTheme() {
|
||||
var stored = localStorage.getItem('preferred-theme');
|
||||
if (stored) return stored;
|
||||
return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'light') {
|
||||
document.documentElement.setAttribute('data-theme', 'light');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
btn.innerHTML = theme === 'light' ? sunSVG : moonSVG;
|
||||
}
|
||||
|
||||
applyTheme(getTheme());
|
||||
|
||||
btn.addEventListener('click', function () {
|
||||
var current = getTheme();
|
||||
var next = current === 'dark' ? 'light' : 'dark';
|
||||
localStorage.setItem('preferred-theme', next);
|
||||
applyTheme(next);
|
||||
});
|
||||
})();
|
||||
|
||||
// Mobile sidebar toggle
|
||||
(function () {
|
||||
var toggle = document.querySelector('.sidebar-toggle');
|
||||
var sidebar = document.querySelector('.sidebar');
|
||||
if (!toggle || !sidebar) return;
|
||||
|
||||
toggle.addEventListener('click', function () {
|
||||
sidebar.classList.toggle('open');
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
if (!sidebar.contains(e.target) && e.target !== toggle) {
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
// Site search (⌘K / Ctrl+K)
|
||||
(function () {
|
||||
var overlay = document.getElementById('search-overlay');
|
||||
var input = document.getElementById('search-input');
|
||||
var resultsList = document.getElementById('search-results');
|
||||
if (!overlay || !input || !resultsList) return;
|
||||
|
||||
var searchBtn = document.querySelector('.search-btn');
|
||||
var pagesData = null; // cached pages-data.json
|
||||
var activeIndex = -1;
|
||||
|
||||
function getCurrentLang() {
|
||||
return document.documentElement.getAttribute('lang') || 'en';
|
||||
}
|
||||
|
||||
function getBasePath() {
|
||||
return document.documentElement.getAttribute('data-base-path') || '';
|
||||
}
|
||||
|
||||
function openSearch() {
|
||||
overlay.classList.add('open');
|
||||
input.value = '';
|
||||
resultsList.innerHTML = '';
|
||||
activeIndex = -1;
|
||||
input.focus();
|
||||
loadPagesData();
|
||||
}
|
||||
|
||||
function closeSearch() {
|
||||
overlay.classList.remove('open');
|
||||
input.value = '';
|
||||
resultsList.innerHTML = '';
|
||||
activeIndex = -1;
|
||||
}
|
||||
|
||||
function loadPagesData() {
|
||||
if (pagesData) return;
|
||||
var basePath = getBasePath();
|
||||
fetch(basePath + '/pages-data.json')
|
||||
.then(function (res) { return res.json(); })
|
||||
.then(function (data) { pagesData = data; })
|
||||
.catch(function () { pagesData = []; });
|
||||
}
|
||||
|
||||
function escapeRegExp(s) {
|
||||
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
function highlightText(text, query) {
|
||||
if (!query) return text;
|
||||
var escaped = escapeRegExp(query);
|
||||
var re = new RegExp('(' + escaped + ')', 'gi');
|
||||
return text.replace(re, '<mark>$1</mark>');
|
||||
}
|
||||
|
||||
function buildSnippet(body, query) {
|
||||
if (!query || !body) return '';
|
||||
var lower = body.toLowerCase();
|
||||
var idx = lower.indexOf(query.toLowerCase());
|
||||
var start, end, snippet;
|
||||
if (idx === -1) {
|
||||
snippet = body.substring(0, 120);
|
||||
} else {
|
||||
start = Math.max(0, idx - 40);
|
||||
end = Math.min(body.length, idx + query.length + 80);
|
||||
snippet = (start > 0 ? '...' : '') + body.substring(start, end) + (end < body.length ? '...' : '');
|
||||
}
|
||||
return highlightText(snippet, query);
|
||||
}
|
||||
|
||||
function search(query) {
|
||||
if (!pagesData || !query) {
|
||||
resultsList.innerHTML = '';
|
||||
activeIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
var lang = getCurrentLang();
|
||||
var q = query.toLowerCase();
|
||||
|
||||
// Score and filter
|
||||
var scored = [];
|
||||
for (var i = 0; i < pagesData.length; i++) {
|
||||
var page = pagesData[i];
|
||||
if (page.lang !== lang) continue;
|
||||
|
||||
var score = 0;
|
||||
var titleLower = page.title.toLowerCase();
|
||||
var bodyLower = (page.body || '').toLowerCase();
|
||||
|
||||
if (titleLower.indexOf(q) !== -1) {
|
||||
score += 10;
|
||||
// Bonus for exact title match
|
||||
if (titleLower === q) score += 5;
|
||||
}
|
||||
if (bodyLower.indexOf(q) !== -1) {
|
||||
score += 3;
|
||||
}
|
||||
if (page.section.toLowerCase().indexOf(q) !== -1) {
|
||||
score += 1;
|
||||
}
|
||||
|
||||
if (score > 0) {
|
||||
scored.push({ page: page, score: score });
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by score descending
|
||||
scored.sort(function (a, b) { return b.score - a.score; });
|
||||
|
||||
// Limit results
|
||||
var results = scored.slice(0, 20);
|
||||
|
||||
if (results.length === 0) {
|
||||
resultsList.innerHTML = '<li class="search-no-results">No results found.</li>';
|
||||
activeIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
for (var j = 0; j < results.length; j++) {
|
||||
var r = results[j];
|
||||
var snippet = buildSnippet(r.page.body, query);
|
||||
html += '<li data-url="' + r.page.url + '">'
|
||||
+ '<div class="search-result-title">' + highlightText(r.page.title, query) + '</div>'
|
||||
+ (snippet ? '<div class="search-result-snippet">' + snippet + '</div>' : '')
|
||||
+ '</li>';
|
||||
}
|
||||
resultsList.innerHTML = html;
|
||||
activeIndex = -1;
|
||||
}
|
||||
|
||||
function setActive(index) {
|
||||
var items = resultsList.querySelectorAll('li[data-url]');
|
||||
if (items.length === 0) return;
|
||||
// Remove previous active
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].classList.remove('active');
|
||||
}
|
||||
if (index < 0) index = items.length - 1;
|
||||
if (index >= items.length) index = 0;
|
||||
activeIndex = index;
|
||||
items[activeIndex].classList.add('active');
|
||||
items[activeIndex].scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
|
||||
function navigateToActive() {
|
||||
var items = resultsList.querySelectorAll('li[data-url]');
|
||||
if (activeIndex >= 0 && activeIndex < items.length) {
|
||||
var url = items[activeIndex].getAttribute('data-url');
|
||||
if (url) {
|
||||
closeSearch();
|
||||
window.location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Event: search button
|
||||
if (searchBtn) {
|
||||
searchBtn.addEventListener('click', function (e) {
|
||||
e.stopPropagation();
|
||||
openSearch();
|
||||
});
|
||||
}
|
||||
|
||||
// Use capture phase to intercept keys before browser default behavior
|
||||
// (e.g. ESC clearing input text in some browsers)
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
overlay.classList.contains('open') ? closeSearch() : openSearch();
|
||||
return;
|
||||
}
|
||||
if (!overlay.classList.contains('open')) return;
|
||||
if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
closeSearch();
|
||||
} else if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
setActive(activeIndex + 1);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
setActive(activeIndex - 1);
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
navigateToActive();
|
||||
}
|
||||
}, true); // capture phase
|
||||
|
||||
// Event: click overlay background to close
|
||||
overlay.addEventListener('click', function (e) {
|
||||
if (e.target === overlay) {
|
||||
closeSearch();
|
||||
}
|
||||
});
|
||||
|
||||
// Event: click result item
|
||||
resultsList.addEventListener('click', function (e) {
|
||||
var li = e.target.closest('li[data-url]');
|
||||
if (!li) return;
|
||||
var url = li.getAttribute('data-url');
|
||||
if (url) {
|
||||
closeSearch();
|
||||
window.location.href = url;
|
||||
}
|
||||
});
|
||||
|
||||
// Event: input for live search
|
||||
var debounceTimer = null;
|
||||
input.addEventListener('input', function () {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(function () {
|
||||
search(input.value.trim());
|
||||
}, 150);
|
||||
});
|
||||
})();
|
||||
@@ -1,88 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ lang }}" data-base-path="{{ site.base_path }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ page.title }} - {{ site.title }}</title>
|
||||
<link rel="icon" type="image/svg+xml" href="{{ site.base_path }}/favicon.svg">
|
||||
<link rel="stylesheet" href="{{ site.base_path }}/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="{{ site.base_path }}/{{ lang }}/" class="header-title">{{ site.title }}{% if site.version %} <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v{{ site.version }}</span>{% endif %}</a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="{{ site.base_path }}/{{ lang }}/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
{% for link in site.nav %}
|
||||
{% if link.url %}
|
||||
<a href="{{ link.url }}"{% if link.icon_svg %} aria-label="{{ link.label }}"{% endif %}>
|
||||
{% if link.icon_svg %}{{ link.icon_svg | safe }}{% endif %}
|
||||
{{ link.label }}
|
||||
</a>
|
||||
{% elif link.path %}
|
||||
<a href="{{ site.base_path }}/{{ lang }}/{{ link.path }}">
|
||||
{% if link.icon_svg %}{{ link.icon_svg | safe }}{% endif %}
|
||||
{{ link.label }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</nav>
|
||||
<div class="header-tools">
|
||||
<button class="search-btn" aria-label="Search (⌘K)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
{{ lang | upper }}
|
||||
</button>
|
||||
<ul class="lang-popup">
|
||||
{% for l in site.langs %}
|
||||
<li><a href="#" data-lang="{{ l }}">{{ l | upper }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% block sidebar_toggle %}{% endblock %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if page.status == "draft" %}
|
||||
<div class="draft-banner">DRAFT</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="layout {% block layout_class %}{% endblock %}">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
<div class="search-overlay" id="search-overlay">
|
||||
<div class="search-modal">
|
||||
<div class="search-input-wrap">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
<input type="text" id="search-input" placeholder="Search..." autocomplete="off" spellcheck="false">
|
||||
<kbd class="search-esc">ESC</kbd>
|
||||
</div>
|
||||
<ul class="search-results" id="search-results"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ site.base_path }}/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block layout_class %}has-sidebar{% endblock %}
|
||||
|
||||
{% block sidebar_toggle %}<button class="sidebar-toggle" aria-label="Menu">☰</button>{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
{% for section in nav %}
|
||||
<div class="nav-section">
|
||||
<a href="{{ section.url }}" class="nav-section-title {% if section.active %}active{% endif %}">{{ section.title }}</a>
|
||||
{% if section.children %}
|
||||
<ul class="nav-list">
|
||||
{% for item in section.children %}
|
||||
<li><a href="{{ item.url }}" class="{% if item.active %}active{% endif %}">{{ item.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<article>
|
||||
<h1>{{ page.title }}</h1>
|
||||
{{ content | safe }}
|
||||
</article>
|
||||
</main>
|
||||
{% endblock %}
|
||||
@@ -1,12 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block layout_class %}no-sidebar{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<main class="content portal">
|
||||
<article>
|
||||
<h1>{{ page.title }}</h1>
|
||||
{{ content | safe }}
|
||||
</article>
|
||||
</main>
|
||||
{% endblock %}
|
||||
@@ -1,468 +0,0 @@
|
||||
use crate::config::{NavLink, SiteConfig};
|
||||
use crate::defaults;
|
||||
use crate::markdown::{Frontmatter, MarkdownRenderer};
|
||||
use crate::utils::copy_dir_recursive;
|
||||
use anyhow::{Context, Result};
|
||||
use serde::Serialize;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tera::Tera;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct PageContext {
|
||||
title: String,
|
||||
url: String,
|
||||
status: Option<String>,
|
||||
}
|
||||
|
||||
/// Entry for pages-data.json used by client-side search.
|
||||
#[derive(Debug, Serialize)]
|
||||
struct PageDataEntry {
|
||||
title: String,
|
||||
url: String,
|
||||
lang: String,
|
||||
section: String,
|
||||
/// Plain-text body with HTML tags stripped (truncated to ~500 chars).
|
||||
body: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
struct NavItem {
|
||||
title: String,
|
||||
url: String,
|
||||
children: Vec<NavItem>,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct SiteContext {
|
||||
title: String,
|
||||
version: Option<String>,
|
||||
base_url: String,
|
||||
base_path: String,
|
||||
langs: Vec<String>,
|
||||
nav: Vec<NavLink>,
|
||||
}
|
||||
|
||||
struct Page {
|
||||
frontmatter: Frontmatter,
|
||||
html_content: String,
|
||||
url: String,
|
||||
out_path: PathBuf,
|
||||
rel_path: String,
|
||||
section: String,
|
||||
}
|
||||
|
||||
pub fn build(src: &Path, out: &Path) -> Result<()> {
|
||||
let config = SiteConfig::load(src)?;
|
||||
let renderer = MarkdownRenderer::new(
|
||||
config.highlight_dark_theme(),
|
||||
config.highlight_light_theme(),
|
||||
);
|
||||
|
||||
// Build Tera: start with embedded defaults, then override with user templates
|
||||
let tera = build_tera(src)?;
|
||||
|
||||
// Clean output directory
|
||||
if out.exists() {
|
||||
fs::remove_dir_all(out).context("Failed to clean output directory")?;
|
||||
}
|
||||
fs::create_dir_all(out)?;
|
||||
|
||||
// Copy static files: embedded defaults first, then user overrides on top
|
||||
copy_default_static(out)?;
|
||||
let static_dir = src.join("static");
|
||||
if static_dir.exists() {
|
||||
copy_dir_recursive(&static_dir, out)?;
|
||||
}
|
||||
|
||||
// Collect page data entries for pages-data.json across all languages
|
||||
let mut page_data_entries: Vec<PageDataEntry> = Vec::new();
|
||||
|
||||
// Build each language
|
||||
for lang in &config.i18n.langs {
|
||||
let pages_dir = src.join("pages").join(lang);
|
||||
if !pages_dir.exists() {
|
||||
eprintln!("Warning: pages directory not found for lang '{}', skipping", lang);
|
||||
continue;
|
||||
}
|
||||
|
||||
let pages = collect_pages(&pages_dir, lang, out, &renderer, &config.site.base_path)?;
|
||||
let nav = build_nav(&pages);
|
||||
|
||||
for page in &pages {
|
||||
// Collect search data for pages-data.json
|
||||
let plain_body = strip_html_tags(&remove_light_theme_blocks(&page.html_content));
|
||||
let truncated_body: String = plain_body.chars().take(500).collect();
|
||||
page_data_entries.push(PageDataEntry {
|
||||
title: page.frontmatter.title.clone(),
|
||||
url: page.url.clone(),
|
||||
lang: lang.clone(),
|
||||
section: page.section.clone(),
|
||||
body: truncated_body,
|
||||
});
|
||||
|
||||
let template_name = if page.section.is_empty() {
|
||||
"portal.html"
|
||||
} else {
|
||||
"page.html"
|
||||
};
|
||||
|
||||
// Filter nav to only the current section
|
||||
let section_nav: Vec<&NavItem> = nav
|
||||
.iter()
|
||||
.filter(|item| {
|
||||
let item_section = extract_section(&item.url, &config.site.base_path);
|
||||
item_section == page.section
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut ctx = tera::Context::new();
|
||||
ctx.insert("page", &PageContext {
|
||||
title: page.frontmatter.title.clone(),
|
||||
url: page.url.clone(),
|
||||
status: page.frontmatter.status.clone(),
|
||||
});
|
||||
ctx.insert("content", &page.html_content);
|
||||
ctx.insert("lang", lang);
|
||||
ctx.insert("site", &SiteContext {
|
||||
title: config.site.title.clone(),
|
||||
version: config.site.version.clone(),
|
||||
base_url: config.site.base_url(),
|
||||
base_path: config.site.base_path.clone(),
|
||||
langs: config.i18n.langs.clone(),
|
||||
nav: config.nav.clone(),
|
||||
});
|
||||
|
||||
// Set active state and pass nav
|
||||
let mut nav_with_active: Vec<NavItem> = section_nav
|
||||
.into_iter()
|
||||
.cloned()
|
||||
.map(|mut item| {
|
||||
set_active(&mut item, &page.url);
|
||||
item
|
||||
})
|
||||
.collect();
|
||||
|
||||
// If we're on a section index page, expand its children
|
||||
if let Some(item) = nav_with_active.first_mut() {
|
||||
if item.url == page.url {
|
||||
item.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.insert("nav", &nav_with_active);
|
||||
|
||||
let html = tera
|
||||
.render(template_name, &ctx)
|
||||
.with_context(|| format!("Failed to render template for {}", page.url))?;
|
||||
|
||||
if let Some(parent) = page.out_path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
fs::write(&page.out_path, html)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate pages-data.json for client-side search
|
||||
let pages_json = serde_json::to_string(&page_data_entries)
|
||||
.context("Failed to serialize pages-data.json")?;
|
||||
fs::write(out.join("pages-data.json"), pages_json)?;
|
||||
|
||||
// Generate root redirect
|
||||
generate_root_redirect(out, &config)?;
|
||||
|
||||
println!(
|
||||
"Site generated: {} languages, output at {}",
|
||||
config.i18n.langs.len(),
|
||||
out.display()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_pages(
|
||||
pages_dir: &Path,
|
||||
lang: &str,
|
||||
out: &Path,
|
||||
renderer: &MarkdownRenderer,
|
||||
base_path: &str,
|
||||
) -> Result<Vec<Page>> {
|
||||
let mut pages = Vec::new();
|
||||
|
||||
for entry in WalkDir::new(pages_dir)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| {
|
||||
e.path().extension().map_or(false, |ext| ext == "md")
|
||||
})
|
||||
{
|
||||
let path = entry.path();
|
||||
let content = fs::read_to_string(path)
|
||||
.with_context(|| format!("Failed to read {}", path.display()))?;
|
||||
|
||||
let (frontmatter, body) = MarkdownRenderer::parse_frontmatter(&content)
|
||||
.with_context(|| format!("Failed to parse frontmatter in {}", path.display()))?;
|
||||
|
||||
let html_content = renderer.render(body);
|
||||
|
||||
let rel = path.strip_prefix(pages_dir)?;
|
||||
let rel_str = rel.to_string_lossy().to_string();
|
||||
|
||||
// Compute URL and output path
|
||||
let (url, out_path) = if rel.file_name().map_or(false, |f| f == "index.md") {
|
||||
// index.md -> <base_path>/<lang>/dir/
|
||||
let parent = rel.parent().unwrap_or(Path::new(""));
|
||||
if parent.as_os_str().is_empty() {
|
||||
// Root index.md
|
||||
(
|
||||
format!("{}/{}/", base_path, lang),
|
||||
out.join(lang).join("index.html"),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
format!("{}/{}/{}/", base_path, lang, parent.display()),
|
||||
out.join(lang).join(parent).join("index.html"),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// foo.md -> <base_path>/<lang>/foo/
|
||||
let stem = rel.with_extension("");
|
||||
(
|
||||
format!("{}/{}/{}/", base_path, lang, stem.display()),
|
||||
out.join(lang).join(&stem).join("index.html"),
|
||||
)
|
||||
};
|
||||
|
||||
let section = extract_section(&url, base_path);
|
||||
|
||||
pages.push(Page {
|
||||
frontmatter,
|
||||
html_content,
|
||||
url,
|
||||
out_path,
|
||||
rel_path: rel_str,
|
||||
section,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(pages)
|
||||
}
|
||||
|
||||
fn extract_section(url: &str, base_path: &str) -> String {
|
||||
// Strip base_path prefix before parsing
|
||||
let stripped = url.strip_prefix(base_path).unwrap_or(url);
|
||||
// URL format: /<lang>/ or /<lang>/section/...
|
||||
let parts: Vec<&str> = stripped.trim_matches('/').split('/').collect();
|
||||
if parts.len() >= 2 {
|
||||
parts[1].to_string()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn build_nav(pages: &[Page]) -> Vec<NavItem> {
|
||||
// Group pages by section (top-level directory)
|
||||
let mut sections: std::collections::BTreeMap<String, Vec<&Page>> =
|
||||
std::collections::BTreeMap::new();
|
||||
|
||||
for page in pages {
|
||||
if page.section.is_empty() {
|
||||
continue; // Skip root index (portal)
|
||||
}
|
||||
sections
|
||||
.entry(page.section.clone())
|
||||
.or_default()
|
||||
.push(page);
|
||||
}
|
||||
|
||||
let mut nav = Vec::new();
|
||||
|
||||
for (section, mut section_pages) in sections {
|
||||
// Sort by order, then by filename
|
||||
section_pages.sort_by(|a, b| {
|
||||
a.frontmatter
|
||||
.order
|
||||
.cmp(&b.frontmatter.order)
|
||||
.then_with(|| a.rel_path.cmp(&b.rel_path))
|
||||
});
|
||||
|
||||
// Find the section index page
|
||||
let index_page = section_pages
|
||||
.iter()
|
||||
.find(|p| p.rel_path.ends_with("index.md") && p.section == section);
|
||||
|
||||
let section_title = index_page
|
||||
.map(|p| p.frontmatter.title.clone())
|
||||
.unwrap_or_else(|| section.clone());
|
||||
let section_url = index_page
|
||||
.map(|p| p.url.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
let children: Vec<NavItem> = section_pages
|
||||
.iter()
|
||||
.filter(|p| !p.rel_path.ends_with("index.md") || p.section != section)
|
||||
.map(|p| NavItem {
|
||||
title: p.frontmatter.title.clone(),
|
||||
url: p.url.clone(),
|
||||
children: Vec::new(),
|
||||
active: false,
|
||||
})
|
||||
.collect();
|
||||
|
||||
nav.push(NavItem {
|
||||
title: section_title,
|
||||
url: section_url,
|
||||
children,
|
||||
active: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Sort nav sections by order of their index pages
|
||||
nav
|
||||
}
|
||||
|
||||
fn set_active(item: &mut NavItem, current_url: &str) {
|
||||
if item.url == current_url {
|
||||
item.active = true;
|
||||
}
|
||||
for child in &mut item.children {
|
||||
set_active(child, current_url);
|
||||
if child.active {
|
||||
item.active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_root_redirect(out: &Path, config: &SiteConfig) -> Result<()> {
|
||||
let base_path = &config.site.base_path;
|
||||
let html = format!(
|
||||
r#"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
(function() {{
|
||||
var lang = localStorage.getItem('preferred-lang') || '{default_lang}';
|
||||
window.location.replace('{base_path}/' + lang + '/');
|
||||
}})();
|
||||
</script>
|
||||
<meta http-equiv="refresh" content="0;url={base_path}/{default_lang}/">
|
||||
<title>Redirecting...</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to <a href="{base_path}/{default_lang}/">{base_path}/{default_lang}/</a>...</p>
|
||||
</body>
|
||||
</html>"#,
|
||||
default_lang = config.i18n.default_lang(),
|
||||
base_path = base_path,
|
||||
);
|
||||
|
||||
fs::write(out.join("index.html"), html)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build Tera with embedded default templates, then override with any files
|
||||
/// found in `<src>/templates/`.
|
||||
fn build_tera(src: &Path) -> Result<Tera> {
|
||||
let mut tera = Tera::default();
|
||||
|
||||
// Register embedded defaults
|
||||
for (name, source) in defaults::default_templates() {
|
||||
tera.add_raw_template(name, source)
|
||||
.with_context(|| format!("Failed to add default template '{}'", name))?;
|
||||
}
|
||||
|
||||
// Override with user-provided templates (if any)
|
||||
let templates_dir = src.join("templates");
|
||||
if templates_dir.exists() {
|
||||
for entry in WalkDir::new(&templates_dir)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.path().extension().map_or(false, |ext| ext == "html"))
|
||||
{
|
||||
let path = entry.path();
|
||||
let rel = path.strip_prefix(&templates_dir)?;
|
||||
let name = rel.to_string_lossy().replace('\\', "/");
|
||||
let source = fs::read_to_string(path)
|
||||
.with_context(|| format!("Failed to read template {}", path.display()))?;
|
||||
tera.add_raw_template(&name, &source)
|
||||
.with_context(|| format!("Failed to register template '{}'", name))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(tera)
|
||||
}
|
||||
|
||||
/// Write embedded default static files (css/js) to the output directory.
|
||||
fn copy_default_static(out: &Path) -> Result<()> {
|
||||
for (rel_path, content) in defaults::default_static_files() {
|
||||
let target = out.join(rel_path);
|
||||
if let Some(parent) = target.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
// Only write if not already present (user file takes precedence via
|
||||
// the subsequent copy_dir_recursive call, but write defaults first)
|
||||
fs::write(&target, content)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Strip HTML tags from a string and collapse whitespace into a single space,
|
||||
/// producing a plain-text representation suitable for search indexing.
|
||||
fn strip_html_tags(html: &str) -> String {
|
||||
let mut result = String::with_capacity(html.len());
|
||||
let mut in_tag = false;
|
||||
|
||||
for ch in html.chars() {
|
||||
match ch {
|
||||
'<' => in_tag = true,
|
||||
'>' => {
|
||||
in_tag = false;
|
||||
// Insert a space to avoid words being glued across tags
|
||||
result.push(' ');
|
||||
}
|
||||
_ if !in_tag => result.push(ch),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Collapse whitespace
|
||||
let collapsed: String = result.split_whitespace().collect::<Vec<_>>().join(" ");
|
||||
collapsed
|
||||
}
|
||||
|
||||
/// Remove `<div data-code-theme="light">...</div>` blocks so that
|
||||
/// dual-theme code snippets are only indexed once.
|
||||
fn remove_light_theme_blocks(html: &str) -> String {
|
||||
const MARKER: &str = "<div data-code-theme=\"light\"";
|
||||
let mut result = String::with_capacity(html.len());
|
||||
let mut remaining = html;
|
||||
|
||||
while let Some(start) = remaining.find(MARKER) {
|
||||
result.push_str(&remaining[..start]);
|
||||
remaining = &remaining[start..];
|
||||
|
||||
let mut depth: usize = 0;
|
||||
let mut i = 0;
|
||||
while i < remaining.len() {
|
||||
if remaining[i..].starts_with("<div") {
|
||||
depth += 1;
|
||||
i += 4;
|
||||
} else if remaining[i..].starts_with("</div>") {
|
||||
depth -= 1;
|
||||
i += 6;
|
||||
if depth == 0 {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i += remaining[i..].chars().next().map_or(1, |c| c.len_utf8());
|
||||
}
|
||||
}
|
||||
remaining = &remaining[i..];
|
||||
}
|
||||
|
||||
result.push_str(remaining);
|
||||
result
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct SiteConfig {
|
||||
pub site: Site,
|
||||
pub i18n: I18n,
|
||||
pub highlight: Option<Highlight>,
|
||||
#[serde(default)]
|
||||
pub nav: Vec<NavLink>,
|
||||
}
|
||||
|
||||
/// A navigation link entry defined in config.toml under [[nav]].
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct NavLink {
|
||||
pub label: String,
|
||||
/// Absolute or external URL (e.g. GitHub link).
|
||||
pub url: Option<String>,
|
||||
/// Path relative to /<base_path>/<lang>/ (e.g. "tour/").
|
||||
pub path: Option<String>,
|
||||
/// Optional inline SVG string to display as an icon.
|
||||
pub icon_svg: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Site {
|
||||
pub title: String,
|
||||
pub version: Option<String>,
|
||||
/// Optional hostname (e.g. "https://example.github.io"). Combined with
|
||||
/// base_path to form the full base URL.
|
||||
pub hostname: Option<String>,
|
||||
#[serde(default)]
|
||||
pub base_path: String,
|
||||
}
|
||||
|
||||
impl Site {
|
||||
/// Returns the full base URL derived from hostname + base_path.
|
||||
/// Falls back to base_path alone if hostname is not set.
|
||||
pub fn base_url(&self) -> String {
|
||||
match &self.hostname {
|
||||
Some(h) => format!("{}{}", h.trim_end_matches('/'), self.base_path),
|
||||
None => self.base_path.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct I18n {
|
||||
pub langs: Vec<String>,
|
||||
}
|
||||
|
||||
impl I18n {
|
||||
/// Returns the default language, which is the first entry in langs.
|
||||
pub fn default_lang(&self) -> &str {
|
||||
self.langs.first().map(|s| s.as_str()).unwrap_or("en")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Highlight {
|
||||
pub dark_theme: Option<String>,
|
||||
pub light_theme: Option<String>,
|
||||
}
|
||||
|
||||
impl SiteConfig {
|
||||
pub fn load(src_dir: &Path) -> Result<Self> {
|
||||
let path = src_dir.join("config.toml");
|
||||
let content =
|
||||
std::fs::read_to_string(&path).with_context(|| format!("Failed to read {}", path.display()))?;
|
||||
let mut config: SiteConfig =
|
||||
toml::from_str(&content).with_context(|| format!("Failed to parse {}", path.display()))?;
|
||||
|
||||
// Validate required fields
|
||||
if config.i18n.langs.is_empty() {
|
||||
anyhow::bail!("[i18n] langs must not be empty. Please specify at least one language.");
|
||||
}
|
||||
|
||||
// Normalize base_path: strip trailing slash (but keep empty for root)
|
||||
let bp = config.site.base_path.trim_end_matches('/').to_string();
|
||||
config.site.base_path = bp;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub fn highlight_dark_theme(&self) -> &str {
|
||||
self.highlight
|
||||
.as_ref()
|
||||
.and_then(|h| h.dark_theme.as_deref())
|
||||
.unwrap_or("base16-ocean.dark")
|
||||
}
|
||||
|
||||
pub fn highlight_light_theme(&self) -> Option<&str> {
|
||||
self.highlight
|
||||
.as_ref()
|
||||
.and_then(|h| h.light_theme.as_deref())
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// Default embedded theme files. Users can override any of these by placing
|
||||
// a file with the same name under their <SRC>/templates/ or <SRC>/static/.
|
||||
|
||||
pub const TEMPLATE_BASE: &str = include_str!("../defaults/templates/base.html");
|
||||
pub const TEMPLATE_PAGE: &str = include_str!("../defaults/templates/page.html");
|
||||
pub const TEMPLATE_PORTAL: &str = include_str!("../defaults/templates/portal.html");
|
||||
|
||||
pub const STATIC_CSS_MAIN: &str = include_str!("../defaults/static/css/main.css");
|
||||
pub const STATIC_JS_MAIN: &str = include_str!("../defaults/static/js/main.js");
|
||||
pub const STATIC_FAVICON_SVG: &str = include_str!("../defaults/static/favicon.svg");
|
||||
|
||||
// Init command templates
|
||||
pub const INIT_CONFIG_TOML: &str = include_str!("../defaults/config.toml");
|
||||
pub const INIT_PAGE_EN_INDEX: &str = include_str!("../defaults/pages/en/index.md");
|
||||
pub const INIT_PAGE_JA_INDEX: &str = include_str!("../defaults/pages/ja/index.md");
|
||||
|
||||
/// Returns all default templates as (name, source) pairs for Tera registration.
|
||||
pub fn default_templates() -> Vec<(&'static str, &'static str)> {
|
||||
vec![
|
||||
("base.html", TEMPLATE_BASE),
|
||||
("page.html", TEMPLATE_PAGE),
|
||||
("portal.html", TEMPLATE_PORTAL),
|
||||
]
|
||||
}
|
||||
|
||||
/// Returns all default static files as (relative_path, content) pairs.
|
||||
pub fn default_static_files() -> Vec<(&'static str, &'static str)> {
|
||||
vec![
|
||||
("css/main.css", STATIC_CSS_MAIN),
|
||||
("js/main.js", STATIC_JS_MAIN),
|
||||
("favicon.svg", STATIC_FAVICON_SVG),
|
||||
]
|
||||
}
|
||||
|
||||
/// Returns all init scaffold files as (relative_path, content) pairs.
|
||||
pub fn init_files() -> Vec<(&'static str, &'static str)> {
|
||||
vec![
|
||||
("config.toml", INIT_CONFIG_TOML),
|
||||
("templates/base.html", TEMPLATE_BASE),
|
||||
("templates/page.html", TEMPLATE_PAGE),
|
||||
("templates/portal.html", TEMPLATE_PORTAL),
|
||||
("static/css/main.css", STATIC_CSS_MAIN),
|
||||
("static/js/main.js", STATIC_JS_MAIN),
|
||||
("pages/en/index.md", INIT_PAGE_EN_INDEX),
|
||||
("pages/ja/index.md", INIT_PAGE_JA_INDEX),
|
||||
]
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
mod builder;
|
||||
mod config;
|
||||
mod defaults;
|
||||
mod markdown;
|
||||
mod serve;
|
||||
mod utils;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand, CommandFactory};
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about = "A simple static site generator")]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Option<Command>,
|
||||
|
||||
/// Source directory containing config.toml (used when no subcommand given)
|
||||
#[arg(default_value = ".")]
|
||||
src: PathBuf,
|
||||
|
||||
/// Output directory (used when no subcommand given)
|
||||
#[arg(long, default_value = "docs")]
|
||||
out: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
/// Build the documentation site
|
||||
Build {
|
||||
/// Source directory containing config.toml
|
||||
#[arg(default_value = ".")]
|
||||
src: PathBuf,
|
||||
|
||||
/// Output directory
|
||||
#[arg(long, default_value = "docs")]
|
||||
out: PathBuf,
|
||||
},
|
||||
/// Initialize a new docs project with default scaffold files
|
||||
Init {
|
||||
/// Target directory to initialize (default: current directory)
|
||||
#[arg(default_value = ".")]
|
||||
src: PathBuf,
|
||||
},
|
||||
/// Start a local development server with live-reload
|
||||
Serve {
|
||||
/// Source directory containing config.toml
|
||||
#[arg(default_value = ".")]
|
||||
src: PathBuf,
|
||||
|
||||
/// Port number for the HTTP server
|
||||
#[arg(long, default_value = "8080")]
|
||||
port: u16,
|
||||
|
||||
/// Open browser automatically
|
||||
#[arg(long)]
|
||||
open: bool,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
match cli.command {
|
||||
Some(Command::Build { src, out }) => builder::build(&src, &out),
|
||||
Some(Command::Init { src }) => cmd_init(&src),
|
||||
Some(Command::Serve { src, port, open }) => serve::serve(&src, port, open),
|
||||
None => {
|
||||
Cli::command().print_help()?;
|
||||
println!();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_init(target: &Path) -> Result<()> {
|
||||
let mut skipped = 0usize;
|
||||
let mut created = 0usize;
|
||||
|
||||
for (rel_path, content) in defaults::init_files() {
|
||||
let dest = target.join(rel_path);
|
||||
if dest.exists() {
|
||||
eprintln!("Skipping (already exists): {}", dest.display());
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
if let Some(parent) = dest.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
fs::write(&dest, content)?;
|
||||
println!("Created: {}", dest.display());
|
||||
created += 1;
|
||||
}
|
||||
|
||||
println!("\nInit complete: {} file(s) created, {} skipped.", created, skipped);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
use anyhow::{Context, Result};
|
||||
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag, TagEnd};
|
||||
use serde::Deserialize;
|
||||
use syntect::highlighting::ThemeSet;
|
||||
use syntect::html::highlighted_html_for_string;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Frontmatter {
|
||||
pub title: String,
|
||||
#[serde(default)]
|
||||
pub order: i32,
|
||||
pub status: Option<String>,
|
||||
}
|
||||
|
||||
pub struct MarkdownRenderer {
|
||||
syntax_set: SyntaxSet,
|
||||
theme_set: ThemeSet,
|
||||
dark_theme: String,
|
||||
light_theme: Option<String>,
|
||||
}
|
||||
|
||||
impl MarkdownRenderer {
|
||||
pub fn new(dark_theme: &str, light_theme: Option<&str>) -> Self {
|
||||
Self {
|
||||
syntax_set: SyntaxSet::load_defaults_newlines(),
|
||||
theme_set: ThemeSet::load_defaults(),
|
||||
dark_theme: dark_theme.to_string(),
|
||||
light_theme: light_theme.map(|s| s.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_frontmatter(content: &str) -> Result<(Frontmatter, &str)> {
|
||||
let content = content.trim_start();
|
||||
if !content.starts_with("---") {
|
||||
anyhow::bail!("Missing frontmatter delimiter");
|
||||
}
|
||||
let after_first = &content[3..];
|
||||
let end = after_first
|
||||
.find("\n---")
|
||||
.context("Missing closing frontmatter delimiter")?;
|
||||
let yaml = &after_first[..end];
|
||||
let body = &after_first[end + 4..];
|
||||
let fm: Frontmatter =
|
||||
serde_yaml::from_str(yaml).context("Failed to parse frontmatter YAML")?;
|
||||
Ok((fm, body))
|
||||
}
|
||||
|
||||
pub fn render(&self, markdown: &str) -> String {
|
||||
let options = Options::ENABLE_TABLES
|
||||
| Options::ENABLE_STRIKETHROUGH
|
||||
| Options::ENABLE_TASKLISTS;
|
||||
|
||||
let parser = Parser::new_ext(markdown, options);
|
||||
|
||||
let mut in_code_block = false;
|
||||
let mut code_lang = String::new();
|
||||
let mut code_buf = String::new();
|
||||
let mut events: Vec<Event> = Vec::new();
|
||||
|
||||
for event in parser {
|
||||
match event {
|
||||
Event::Start(Tag::CodeBlock(kind)) => {
|
||||
in_code_block = true;
|
||||
code_buf.clear();
|
||||
code_lang = match kind {
|
||||
CodeBlockKind::Fenced(lang) => lang.to_string(),
|
||||
CodeBlockKind::Indented => String::new(),
|
||||
};
|
||||
}
|
||||
Event::End(TagEnd::CodeBlock) => {
|
||||
in_code_block = false;
|
||||
let html = self.highlight_code(&code_buf, &code_lang);
|
||||
events.push(Event::Html(html.into()));
|
||||
}
|
||||
Event::Text(text) if in_code_block => {
|
||||
code_buf.push_str(&text);
|
||||
}
|
||||
other => events.push(other),
|
||||
}
|
||||
}
|
||||
|
||||
let mut html_output = String::new();
|
||||
pulldown_cmark::html::push_html(&mut html_output, events.into_iter());
|
||||
html_output
|
||||
}
|
||||
|
||||
fn highlight_code(&self, code: &str, lang: &str) -> String {
|
||||
let syntax = if lang.is_empty() {
|
||||
self.syntax_set.find_syntax_plain_text()
|
||||
} else {
|
||||
self.syntax_set
|
||||
.find_syntax_by_token(lang)
|
||||
.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
|
||||
};
|
||||
|
||||
let dark_html = self.highlight_with_theme(code, syntax, &self.dark_theme);
|
||||
|
||||
match &self.light_theme {
|
||||
Some(light) => {
|
||||
let light_html = self.highlight_with_theme(code, syntax, light);
|
||||
format!(
|
||||
concat!(
|
||||
"<div class=\"code-block-wrapper\">",
|
||||
"<div data-code-theme=\"dark\">{}</div>",
|
||||
"<div data-code-theme=\"light\">{}</div>",
|
||||
"</div>",
|
||||
),
|
||||
dark_html, light_html
|
||||
)
|
||||
}
|
||||
None => dark_html,
|
||||
}
|
||||
}
|
||||
|
||||
fn highlight_with_theme(
|
||||
&self,
|
||||
code: &str,
|
||||
syntax: &syntect::parsing::SyntaxReference,
|
||||
theme_name: &str,
|
||||
) -> String {
|
||||
let theme = self
|
||||
.theme_set
|
||||
.themes
|
||||
.get(theme_name)
|
||||
.unwrap_or_else(|| {
|
||||
self.theme_set
|
||||
.themes
|
||||
.values()
|
||||
.next()
|
||||
.expect("No themes available")
|
||||
});
|
||||
|
||||
match highlighted_html_for_string(code, &self.syntax_set, syntax, theme) {
|
||||
Ok(html) => html,
|
||||
Err(_) => format!("<pre><code>{}</code></pre>", escape_html(code)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn escape_html(s: &str) -> String {
|
||||
s.replace('&', "&")
|
||||
.replace('<', "<")
|
||||
.replace('>', ">")
|
||||
}
|
||||
@@ -1,340 +0,0 @@
|
||||
use crate::builder;
|
||||
use crate::config::SiteConfig;
|
||||
use crate::utils::copy_dir_recursive;
|
||||
use anyhow::{Context, Result};
|
||||
use notify::{Event, RecursiveMode, Watcher};
|
||||
use socket2::{Domain, Protocol, Socket, Type};
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::path::Path;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
/// Live-reload WebSocket script injected into every HTML page during serve.
|
||||
const LIVE_RELOAD_SCRIPT: &str = r#"<script>
|
||||
(function() {
|
||||
var ws = new WebSocket('ws://' + location.hostname + ':{{WS_PORT}}');
|
||||
ws.onmessage = function(e) { if (e.data === 'reload') location.reload(); };
|
||||
ws.onclose = function() {
|
||||
setTimeout(function() { location.reload(); }, 2000);
|
||||
};
|
||||
})();
|
||||
</script>"#;
|
||||
|
||||
/// Run the serve command: build, start HTTP + WebSocket servers, watch for changes.
|
||||
pub fn serve(src: &Path, port: u16, open_browser: bool) -> Result<()> {
|
||||
let config = SiteConfig::load(src)?;
|
||||
let base_path = config.site.base_path.clone();
|
||||
let ws_port = port + 1;
|
||||
|
||||
// Create temp directory for serving
|
||||
let tmp_dir = tempfile::tempdir().context("Failed to create temp directory")?;
|
||||
let serve_root = tmp_dir.path().to_path_buf();
|
||||
|
||||
println!("Serving from temp directory: {}", serve_root.display());
|
||||
|
||||
// Initial build
|
||||
build_and_copy(src, &serve_root, &base_path, ws_port)?;
|
||||
|
||||
// Track connected WebSocket clients
|
||||
let clients: Arc<Mutex<Vec<TcpStream>>> = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
// Create HTTP and WebSocket listeners upfront with SO_REUSEADDR
|
||||
// so that rapid restarts (after Ctrl+C) don't hit "address in use".
|
||||
let http_listener = create_reuse_listener(port)
|
||||
.with_context(|| format!("Failed to bind HTTP server to port {}", port))?;
|
||||
let ws_listener = create_reuse_listener(ws_port)
|
||||
.with_context(|| format!("Failed to bind WebSocket server to port {}", ws_port))?;
|
||||
|
||||
// Start WebSocket server for live-reload notifications
|
||||
let ws_clients = clients.clone();
|
||||
thread::spawn(move || {
|
||||
if let Err(e) = run_ws_server(ws_listener, ws_clients) {
|
||||
eprintln!("WebSocket server error: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
// Start HTTP server
|
||||
let http_root = serve_root.clone();
|
||||
thread::spawn(move || {
|
||||
if let Err(e) = run_http_server(http_listener, &http_root) {
|
||||
eprintln!("HTTP server error: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
let url = if base_path.is_empty() {
|
||||
format!("http://localhost:{}/", port)
|
||||
} else {
|
||||
format!("http://localhost:{}{}/", port, base_path)
|
||||
};
|
||||
|
||||
println!("\n Local: {}", url);
|
||||
println!(" Press Ctrl+C to stop.\n");
|
||||
|
||||
if open_browser {
|
||||
let _ = open::that(&url);
|
||||
}
|
||||
|
||||
// File watcher
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
let mut watcher = notify::recommended_watcher(move |res: Result<Event, notify::Error>| {
|
||||
if let Ok(event) = res {
|
||||
if event.kind.is_modify() || event.kind.is_create() || event.kind.is_remove() {
|
||||
let _ = tx.send(());
|
||||
}
|
||||
}
|
||||
})?;
|
||||
|
||||
let src_abs = fs::canonicalize(src)?;
|
||||
watcher.watch(&src_abs, RecursiveMode::Recursive)?;
|
||||
|
||||
println!("Watching for changes in {}...", src_abs.display());
|
||||
|
||||
// Debounce: wait for changes, then rebuild
|
||||
loop {
|
||||
// Block until a change notification arrives
|
||||
if rx.recv().is_err() {
|
||||
break;
|
||||
}
|
||||
// Drain any additional events within a short debounce window
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
while rx.try_recv().is_ok() {}
|
||||
|
||||
println!("Change detected, rebuilding...");
|
||||
match build_and_copy(src, &serve_root, &base_path, ws_port) {
|
||||
Ok(()) => {
|
||||
println!("Rebuild complete. Notifying browser...");
|
||||
notify_clients(&clients);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Rebuild failed: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build site into a temp build dir, then copy to serve_root/<base_path>/
|
||||
/// with live-reload script injected.
|
||||
fn build_and_copy(src: &Path, serve_root: &Path, base_path: &str, ws_port: u16) -> Result<()> {
|
||||
// Build into a temporary output directory
|
||||
let build_tmp = tempfile::tempdir().context("Failed to create build temp dir")?;
|
||||
let build_out = build_tmp.path();
|
||||
|
||||
builder::build(src, build_out)?;
|
||||
|
||||
// Determine the target directory under serve_root
|
||||
let target = if base_path.is_empty() {
|
||||
serve_root.to_path_buf()
|
||||
} else {
|
||||
let bp = base_path.trim_start_matches('/');
|
||||
serve_root.join(bp)
|
||||
};
|
||||
|
||||
// Clean target and copy
|
||||
if target.exists() {
|
||||
fs::remove_dir_all(&target).ok();
|
||||
}
|
||||
copy_dir_recursive(build_out, &target)?;
|
||||
|
||||
// Inject live-reload script into all HTML files
|
||||
inject_live_reload(&target, ws_port)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Inject live-reload WebSocket script into all HTML files under dir.
|
||||
fn inject_live_reload(dir: &Path, ws_port: u16) -> Result<()> {
|
||||
let script = LIVE_RELOAD_SCRIPT.replace("{{WS_PORT}}", &ws_port.to_string());
|
||||
|
||||
for entry in WalkDir::new(dir)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| {
|
||||
e.path()
|
||||
.extension()
|
||||
.map_or(false, |ext| ext == "html")
|
||||
})
|
||||
{
|
||||
let path = entry.path();
|
||||
let content = fs::read_to_string(path)?;
|
||||
if let Some(pos) = content.rfind("</body>") {
|
||||
let injected = format!("{}{}{}", &content[..pos], script, &content[pos..]);
|
||||
fs::write(path, injected)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Simple HTTP static file server using tiny_http.
|
||||
fn run_http_server(listener: TcpListener, root: &Path) -> Result<()> {
|
||||
let server = tiny_http::Server::from_listener(listener, None)
|
||||
.map_err(|e| anyhow::anyhow!("HTTP server: {}", e))?;
|
||||
|
||||
for request in server.incoming_requests() {
|
||||
let url_path = percent_decode(request.url());
|
||||
let rel = url_path.trim_start_matches('/');
|
||||
|
||||
let file_path = if rel.is_empty() {
|
||||
root.join("index.html")
|
||||
} else {
|
||||
let candidate = root.join(rel);
|
||||
if candidate.is_dir() {
|
||||
candidate.join("index.html")
|
||||
} else {
|
||||
candidate
|
||||
}
|
||||
};
|
||||
|
||||
if file_path.exists() && file_path.is_file() {
|
||||
let content = fs::read(&file_path).unwrap_or_default();
|
||||
let mime = guess_mime(&file_path);
|
||||
let response = tiny_http::Response::from_data(content)
|
||||
.with_header(
|
||||
tiny_http::Header::from_bytes(&b"Content-Type"[..], mime.as_bytes()).unwrap(),
|
||||
);
|
||||
let _ = request.respond(response);
|
||||
} else {
|
||||
let response = tiny_http::Response::from_string("404 Not Found")
|
||||
.with_status_code(404);
|
||||
let _ = request.respond(response);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// WebSocket server that accepts connections and stores them for later notification.
|
||||
fn run_ws_server(listener: TcpListener, clients: Arc<Mutex<Vec<TcpStream>>>) -> Result<()> {
|
||||
|
||||
for stream in listener.incoming().flatten() {
|
||||
let clients = clients.clone();
|
||||
thread::spawn(move || {
|
||||
if let Ok(ws) = tungstenite::accept(stream.try_clone().unwrap()) {
|
||||
// Store the underlying TCP stream for later notification
|
||||
if let Ok(mut list) = clients.lock() {
|
||||
list.push(stream);
|
||||
}
|
||||
// Keep the WebSocket connection alive - read until closed
|
||||
let mut ws = ws;
|
||||
loop {
|
||||
match ws.read() {
|
||||
Ok(msg) => {
|
||||
if msg.is_close() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send "reload" to all connected WebSocket clients.
|
||||
fn notify_clients(clients: &Arc<Mutex<Vec<TcpStream>>>) {
|
||||
if let Ok(mut list) = clients.lock() {
|
||||
let mut alive = Vec::new();
|
||||
for stream in list.drain(..) {
|
||||
if stream.try_clone().is_ok() {
|
||||
// Re-wrap as WebSocket and send reload message
|
||||
// Since we can't easily re-wrap existing TCP streams,
|
||||
// we'll use a simpler approach: raw WebSocket frame
|
||||
if send_ws_text_frame(&stream, "reload").is_ok() {
|
||||
alive.push(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
*list = alive;
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a WebSocket text frame directly on a TCP stream.
|
||||
fn send_ws_text_frame(mut stream: &TcpStream, msg: &str) -> Result<()> {
|
||||
let payload = msg.as_bytes();
|
||||
let len = payload.len();
|
||||
|
||||
// WebSocket text frame: opcode 0x81
|
||||
let mut frame = Vec::new();
|
||||
frame.push(0x81);
|
||||
if len < 126 {
|
||||
frame.push(len as u8);
|
||||
} else if len < 65536 {
|
||||
frame.push(126);
|
||||
frame.push((len >> 8) as u8);
|
||||
frame.push((len & 0xFF) as u8);
|
||||
}
|
||||
frame.extend_from_slice(payload);
|
||||
|
||||
stream.write_all(&frame)?;
|
||||
stream.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn guess_mime(path: &Path) -> String {
|
||||
match path.extension().and_then(|e| e.to_str()) {
|
||||
Some("html") => "text/html; charset=utf-8".to_string(),
|
||||
Some("css") => "text/css; charset=utf-8".to_string(),
|
||||
Some("js") => "application/javascript; charset=utf-8".to_string(),
|
||||
Some("json") => "application/json; charset=utf-8".to_string(),
|
||||
Some("svg") => "image/svg+xml".to_string(),
|
||||
Some("png") => "image/png".to_string(),
|
||||
Some("jpg") | Some("jpeg") => "image/jpeg".to_string(),
|
||||
Some("gif") => "image/gif".to_string(),
|
||||
Some("ico") => "image/x-icon".to_string(),
|
||||
Some("wasm") => "application/wasm".to_string(),
|
||||
Some("woff") => "font/woff".to_string(),
|
||||
Some("woff2") => "font/woff2".to_string(),
|
||||
Some("ttf") => "font/ttf".to_string(),
|
||||
_ => "application/octet-stream".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn percent_decode(input: &str) -> String {
|
||||
let mut result = String::with_capacity(input.len());
|
||||
let mut chars = input.bytes();
|
||||
while let Some(b) = chars.next() {
|
||||
if b == b'%' {
|
||||
let hi = chars.next().and_then(|c| hex_val(c));
|
||||
let lo = chars.next().and_then(|c| hex_val(c));
|
||||
if let (Some(h), Some(l)) = (hi, lo) {
|
||||
result.push((h << 4 | l) as char);
|
||||
}
|
||||
} else {
|
||||
result.push(b as char);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn hex_val(b: u8) -> Option<u8> {
|
||||
match b {
|
||||
b'0'..=b'9' => Some(b - b'0'),
|
||||
b'a'..=b'f' => Some(b - b'a' + 10),
|
||||
b'A'..=b'F' => Some(b - b'A' + 10),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a TCP listener with SO_REUSEADDR (and SO_REUSEPORT on Unix) set,
|
||||
/// so that rapid restarts after Ctrl+C don't fail with "address in use".
|
||||
fn create_reuse_listener(port: u16) -> Result<TcpListener> {
|
||||
let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP))?;
|
||||
socket.set_reuse_address(true)?;
|
||||
#[cfg(unix)]
|
||||
socket.set_reuse_port(true)?;
|
||||
let addr: std::net::SocketAddr = format!("0.0.0.0:{}", port).parse()?;
|
||||
socket.bind(&addr.into())?;
|
||||
socket.listen(128)?;
|
||||
Ok(socket.into())
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub fn copy_dir_recursive(src: &Path, dst: &Path) -> Result<()> {
|
||||
for entry in WalkDir::new(src).into_iter().filter_map(|e| e.ok()) {
|
||||
let path = entry.path();
|
||||
let rel = path.strip_prefix(src)?;
|
||||
let target = dst.join(rel);
|
||||
|
||||
if path.is_dir() {
|
||||
fs::create_dir_all(&target)?;
|
||||
} else {
|
||||
if let Some(parent) = target.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
fs::copy(path, &target)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,8 +1,13 @@
|
||||
[system]
|
||||
theme = "default"
|
||||
langs = ["en", "ja"]
|
||||
|
||||
[site]
|
||||
title = "cpp-httplib"
|
||||
version = "0.36.0"
|
||||
hostname = "https://yhirose.github.io"
|
||||
base_path = "/cpp-httplib"
|
||||
footer_message = "© 2026 Yuji Hirose. All rights reserved."
|
||||
|
||||
[[nav]]
|
||||
label = "Tour"
|
||||
@@ -13,10 +18,3 @@ icon_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewB
|
||||
label = "GitHub"
|
||||
url = "https://github.com/yhirose/cpp-httplib"
|
||||
icon_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>'
|
||||
|
||||
[i18n]
|
||||
langs = ["en", "ja"]
|
||||
|
||||
[highlight]
|
||||
dark_theme = "base16-eighties.dark"
|
||||
light_theme = "InspiredGitHub"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
--link: palegoldenrod;
|
||||
--heading: lightskyblue;
|
||||
--heading-link: #f0c090;
|
||||
--header-nav-link: pink;
|
||||
--header-nav-link: #ddd;
|
||||
--emphasis: pink;
|
||||
--nav-section: #bbb;
|
||||
--nav-section-active: #ddd;
|
||||
@@ -357,7 +357,7 @@ html[data-theme="light"] .code-block-wrapper > [data-code-theme="light"] {
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
padding: 12px 16px;
|
||||
padding: 8px 16px;
|
||||
text-align: center;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.8rem;
|
||||
@@ -433,7 +433,7 @@ html[data-theme="light"] .code-block-wrapper > [data-code-theme="light"] {
|
||||
--link: #b8860b;
|
||||
--heading: #2a6496;
|
||||
--heading-link: #c06020;
|
||||
--header-nav-link: #c04060;
|
||||
--header-nav-link: #282828;
|
||||
--emphasis: #c04060;
|
||||
--nav-section: #666;
|
||||
--nav-section-active: #333;
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -89,7 +91,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -88,7 +90,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,8 +107,8 @@
|
||||
<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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -LO</span><span style="color:#c0c5ce;"> https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -LO https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h
|
||||
@@ -121,18 +123,18 @@
|
||||
</tbody></table>
|
||||
<h2>Hello World Server</h2>
|
||||
<p>Save the following code as <code>server.cpp</code>.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request&, httplib::Response& res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, World!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -151,17 +153,17 @@
|
||||
<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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;"># macOS
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Linux
|
||||
</span><span style="color:#65737e;"># `-pthread`: cpp-httplib uses threads internally
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -pthread -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#65737e;"># `/EHsc`: Enable C++ exception handling
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#c0c5ce;"> /EHsc /std:c++17 server.cpp
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;"># macOS
|
||||
@@ -177,12 +179,12 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>Once it compiles, run it.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;"># macOS / Linux
|
||||
</span><span style="color:#8fa1b3;">./server
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Windows
|
||||
</span><span style="color:#8fa1b3;">server.exe
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;"># macOS / Linux
|
||||
@@ -194,9 +196,9 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/
|
||||
</span><span style="color:#65737e;"># Hello, World!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/
|
||||
@@ -214,7 +216,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,53 +107,53 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#c0c5ce;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::string result;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">for </span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#c0c5ce;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#c0c5ce;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#c0c5ce;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#c0c5ce;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#c0c5ce;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#c0c5ce;">[</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">];
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -204,19 +206,19 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -235,9 +237,9 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/hi
|
||||
</span><span style="color:#65737e;"># Hello!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/hi
|
||||
@@ -246,18 +248,18 @@
|
||||
</div></div>
|
||||
<h2>Checking the Response</h2>
|
||||
<p>A response contains header information in addition to the status code and body.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Status code
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Body
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello!
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Headers
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Content-Type</span><span style="color:#c0c5ce;">") << std::endl; </span><span style="color:#65737e;">// text/plain
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">);
|
||||
@@ -276,11 +278,11 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", httplib::Params{{"</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">cpp-httplib</span><span style="color:#c0c5ce;">"}});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Query: cpp-httplib
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/search"</span><span style="color:#323232;">, httplib::Params{{</span><span style="color:#183691;">"q"</span><span style="color:#323232;">, </span><span style="color:#183691;">"cpp-httplib"</span><span style="color:#323232;">}});
|
||||
@@ -290,9 +292,9 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p><code>httplib::Params</code> automatically URL-encodes special characters for you.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">http://localhost:8080/search?q=cpp-httplib</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#65737e;"># Query: cpp-httplib
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl </span><span style="color:#183691;">"http://localhost:8080/search?q=cpp-httplib"
|
||||
@@ -301,11 +303,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/42</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// User ID: 42
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/users/42"</span><span style="color:#323232;">);
|
||||
@@ -313,9 +315,9 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->body </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// User ID: 42
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/users/42
|
||||
</span><span style="color:#65737e;"># User ID: 42
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/users/42
|
||||
@@ -323,11 +325,11 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/files/42</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// File ID: 42
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/files/42"</span><span style="color:#323232;">);
|
||||
@@ -335,9 +337,9 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->body </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// File ID: 42
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/files/42
|
||||
</span><span style="color:#65737e;"># File ID: 42
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/files/42
|
||||
@@ -347,18 +349,18 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", httplib::Headers{
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">Authorization</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Bearer my-token</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, httplib::Headers{
|
||||
</span><span style="color:#323232;"> {</span><span style="color:#183691;">"Authorization"</span><span style="color:#323232;">, </span><span style="color:#183691;">"Bearer my-token"</span><span style="color:#323232;">}
|
||||
</span><span style="color:#323232;">});
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -H </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">Authorization: Bearer my-token</span><span style="color:#c0c5ce;">" http://localhost:8080/hi
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -H </span><span style="color:#183691;">"Authorization: Bearer my-token"</span><span style="color:#323232;"> http://localhost:8080/hi
|
||||
@@ -366,12 +368,12 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Hello, Server!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello, Server!
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Post(</span><span style="color:#183691;">"/post"</span><span style="color:#323232;">, </span><span style="color:#183691;">"Hello, Server!"</span><span style="color:#323232;">, </span><span style="color:#183691;">"text/plain"</span><span style="color:#323232;">);
|
||||
@@ -382,9 +384,9 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -X</span><span style="color:#c0c5ce;"> POST</span><span style="color:#bf616a;"> -H </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">Content-Type: text/plain</span><span style="color:#c0c5ce;">"</span><span style="color:#bf616a;"> -d </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">Hello, Server!</span><span style="color:#c0c5ce;">" http://localhost:8080/post
|
||||
</span><span style="color:#65737e;"># Hello, Server!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -X POST -H </span><span style="color:#183691;">"Content-Type: text/plain"</span><span style="color:#323232;"> -d </span><span style="color:#183691;">"Hello, Server!"</span><span style="color:#323232;"> http://localhost:8080/post
|
||||
@@ -393,16 +395,16 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", httplib::Params{
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">name</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Alice</span><span style="color:#c0c5ce;">"},
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">age</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">30</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// age = 30
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// name = Alice
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Post(</span><span style="color:#183691;">"/submit"</span><span style="color:#323232;">, httplib::Params{
|
||||
@@ -417,8 +419,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>This sends the data in <code>application/x-www-form-urlencoded</code> format.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -X</span><span style="color:#c0c5ce;"> POST</span><span style="color:#bf616a;"> -d </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">name=Alice&age=30</span><span style="color:#c0c5ce;">" http://localhost:8080/submit
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -X POST -d </span><span style="color:#183691;">"name=Alice&age=30"</span><span style="color:#323232;"> http://localhost:8080/submit
|
||||
@@ -426,13 +428,13 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", httplib::UploadFormDataItems{
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Hello, File!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">hello.txt</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// hello.txt (12 bytes)
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Post(</span><span style="color:#183691;">"/upload"</span><span style="color:#323232;">, httplib::UploadFormDataItems{
|
||||
@@ -444,8 +446,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>Each element in <code>UploadFormDataItems</code> has four fields: <code>{name, content, filename, content_type}</code>.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -F </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">file=Hello, File!;filename=hello.txt;type=text/plain</span><span style="color:#c0c5ce;">" http://localhost:8080/upload
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -F </span><span style="color:#183691;">"file=Hello, File!;filename=hello.txt;type=text/plain"</span><span style="color:#323232;"> http://localhost:8080/upload
|
||||
@@ -453,24 +455,24 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:9999</span><span style="color:#c0c5ce;">"); </span><span style="color:#65737e;">// Non-existent port
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(!res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Connection error
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#c0c5ce;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#c0c5ce;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#c0c5ce;">()) << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Error: Connection
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// If we reach here, we have a response
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;">!= </span><span style="color:#d08770;">200</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">HTTP Error: </span><span style="color:#c0c5ce;">" << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:9999"</span><span style="color:#323232;">); </span><span style="font-style:italic;color:#969896;">// Non-existent port
|
||||
@@ -507,7 +509,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,8 +107,8 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.listen(</span><span style="color:#183691;">"0.0.0.0"</span><span style="color:#323232;">, </span><span style="color:#0086b3;">8080</span><span style="color:#323232;">);
|
||||
@@ -116,12 +118,12 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &req, httplib::Response &res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Server svr;
|
||||
@@ -133,11 +135,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// GET
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// POST
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Put</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// PUT
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Delete</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// DELETE
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/path"</span><span style="color:#323232;">, handler); </span><span style="font-style:italic;color:#969896;">// GET
|
||||
@@ -147,10 +149,10 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -163,11 +165,11 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Echo the body back to the client
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/post"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -178,11 +180,11 @@
|
||||
</div></div>
|
||||
<h3>Headers</h3>
|
||||
<p>Use <code>req.get_header_value()</code> to read a request header.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/check</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> auth = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Authorization</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Auth: </span><span style="color:#c0c5ce;">" + auth, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/check"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -193,11 +195,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#c0c5ce;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/search"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -208,14 +210,14 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::string result;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">for </span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#c0c5ce;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/submit"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -229,12 +231,12 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#c0c5ce;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#c0c5ce;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/upload"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -247,11 +249,11 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#c0c5ce;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/users/:id"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -262,12 +264,12 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:user_id/posts/:post_id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> user_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">user_id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> post_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">post_id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User: </span><span style="color:#c0c5ce;">" + user_id + "</span><span style="color:#a3be8c;">, Post: </span><span style="color:#c0c5ce;">" + post_id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/users/:user_id/posts/:post_id"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -279,12 +281,12 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// Only accept numeric IDs
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#c0c5ce;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#c0c5ce;">[</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">]; </span><span style="color:#65737e;">// First capture group
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// Only accept numeric IDs
|
||||
@@ -299,10 +301,10 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -312,11 +314,11 @@
|
||||
</div></div>
|
||||
<h3>Status Code</h3>
|
||||
<p>To return a different status code, assign to <code>res.status</code>.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/not-found</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;">= </span><span style="color:#d08770;">404</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Not found</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/not-found"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -327,11 +329,11 @@
|
||||
</div></div>
|
||||
<h3>Response Headers</h3>
|
||||
<p>Add response headers with <code>res.set_header()</code>.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/with-header</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">X-Custom</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">my-value</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/with-header"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -343,10 +345,10 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -356,11 +358,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#c0c5ce;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/search"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -371,10 +373,10 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/post"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -384,14 +386,14 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::string result;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">for </span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#c0c5ce;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/submit"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -405,12 +407,12 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#c0c5ce;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#c0c5ce;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/upload"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -422,11 +424,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#c0c5ce;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/users/:id"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -437,11 +439,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#c0c5ce;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#c0c5ce;">[</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">];
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="font-weight:bold;color:#a71d5d;">R</span><span style="color:#183691;">"(/files/(\d+))"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -462,7 +464,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,18 +107,18 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./html</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -134,21 +136,21 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">mkdir</span><span style="color:#d3d0c8;"> html
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">mkdir</span><span style="color:#c0c5ce;"> html
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">mkdir html
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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;">>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;"><!</span><span style="color:#bf616a;">DOCTYPE</span><span style="color:#c0c5ce;"> html>
|
||||
</span><span style="color:#c0c5ce;"><</span><span style="color:#bf616a;">html</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"><</span><span style="color:#bf616a;">head</span><span style="color:#c0c5ce;">><</span><span style="color:#bf616a;">title</span><span style="color:#c0c5ce;">>My Page</</span><span style="color:#bf616a;">title</span><span style="color:#c0c5ce;">></</span><span style="color:#bf616a;">head</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"><</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"> <</span><span style="color:#bf616a;">h1</span><span style="color:#c0c5ce;">>Hello from cpp-httplib!</</span><span style="color:#bf616a;">h1</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"> <</span><span style="color:#bf616a;">p</span><span style="color:#c0c5ce;">>This is a static file.</</span><span style="color:#bf616a;">p</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"></</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"></</span><span style="color:#bf616a;">html</span><span style="color:#c0c5ce;">>
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;"><!</span><span style="color:#63a35c;">DOCTYPE</span><span style="color:#323232;"> html>
|
||||
@@ -162,9 +164,9 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>Compile and start the server.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">g++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp</span><span style="color:#bf616a;"> -pthread
|
||||
</span><span style="color:#8fa1b3;">./server
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">g++ -std</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;">c++17 -o server server.cpp -pthread
|
||||
@@ -173,12 +175,12 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// HTML is displayed
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -187,8 +189,8 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->body </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// HTML is displayed
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080
|
||||
@@ -196,10 +198,10 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/assets</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./static/assets</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/docs</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./documentation</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_mount_point(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">, </span><span style="color:#183691;">"./public"</span><span style="color:#323232;">);
|
||||
@@ -210,18 +212,18 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// API endpoint
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/api/hello</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">{"message":"Hello!"}</span><span style="color:#c0c5ce;">)", "</span><span style="color:#a3be8c;">application/json</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// Static file serving
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Server svr;
|
||||
@@ -240,10 +242,10 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#c0c5ce;">", {
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">Cache-Control</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">max-age=3600</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_mount_point(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">, </span><span style="color:#183691;">"./public"</span><span style="color:#323232;">, {
|
||||
@@ -254,14 +256,14 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">"
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">> docker run</span><span style="color:#bf616a;"> -p</span><span style="color:#c0c5ce;"> 8080:80</span><span style="color:#bf616a;"> -v</span><span style="color:#c0c5ce;"> ./my-site:/html yhirose4dockerhub/cpp-httplib-server
|
||||
</span><span style="color:#8fa1b3;">Serving</span><span style="color:#c0c5ce;"> HTTP on 0.0.0.0:80
|
||||
</span><span style="color:#8fa1b3;">Mount</span><span style="color:#c0c5ce;"> point: / -> ./html
|
||||
</span><span style="color:#8fa1b3;">Press</span><span style="color:#c0c5ce;"> Ctrl+C to shutdown gracefully...
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#c0c5ce;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#c0c5ce;">22/Feb/2026:12:00:00 +0000</span><span style="color:#b48ead;">] </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">GET / HTTP/1.1</span><span style="color:#c0c5ce;">" 200 256 "</span><span style="color:#a3be8c;">-</span><span style="color:#c0c5ce;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#c0c5ce;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#c0c5ce;">22/Feb/2026:12:00:00 +0000</span><span style="color:#b48ead;">] </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">GET /style.css HTTP/1.1</span><span style="color:#c0c5ce;">" 200 1024 "</span><span style="color:#a3be8c;">-</span><span style="color:#c0c5ce;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#c0c5ce;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#c0c5ce;">22/Feb/2026:12:00:01 +0000</span><span style="color:#b48ead;">] </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">GET /favicon.ico HTTP/1.1</span><span style="color:#c0c5ce;">" 404 152 "</span><span style="color:#a3be8c;">-</span><span style="color:#c0c5ce;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#c0c5ce;">"
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">></span><span style="color:#323232;"> docker run -p 8080:80 -v ./my-site:/html yhirose4dockerhub/cpp-httplib-server
|
||||
@@ -285,7 +287,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -113,22 +115,22 @@
|
||||
</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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;"># macOS (Homebrew)
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -I</span><span style="color:#c0c5ce;">$</span><span style="color:#bf616a;">(</span><span style="color:#8fa1b3;">brew</span><span style="color:#bf616a;"> --prefix openssl)</span><span style="color:#c0c5ce;">/include \
|
||||
</span><span style="color:#bf616a;"> -L</span><span style="color:#c0c5ce;">$</span><span style="color:#bf616a;">(</span><span style="color:#8fa1b3;">brew</span><span style="color:#bf616a;"> --prefix openssl)</span><span style="color:#c0c5ce;">/lib \
|
||||
</span><span style="color:#bf616a;"> -lssl -lcrypto </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -framework</span><span style="color:#c0c5ce;"> CoreFoundation</span><span style="color:#bf616a;"> -framework</span><span style="color:#c0c5ce;"> Security \
|
||||
</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Linux
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -pthread -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -lssl -lcrypto </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#c0c5ce;"> /EHsc /std:c++17 /DCPPHTTPLIB_OPENSSL_SUPPORT server.cpp libssl.lib libcrypto.lib
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;"># macOS (Homebrew)
|
||||
@@ -157,21 +159,21 @@
|
||||
</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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://www.google.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Status: </span><span style="color:#c0c5ce;">" << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;"> } </span><span style="color:#b48ead;">else </span><span style="color:#c0c5ce;">{
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#c0c5ce;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#c0c5ce;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#c0c5ce;">()) << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -209,7 +211,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,22 +107,22 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">substr</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">100</span><span style="color:#c0c5ce;">) << std::endl; </span><span style="color:#65737e;">// First 100 chars of the HTML
|
||||
</span><span style="color:#c0c5ce;"> } </span><span style="color:#b48ead;">else </span><span style="color:#c0c5ce;">{
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#c0c5ce;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#c0c5ce;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#c0c5ce;">()) << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -141,8 +143,8 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> https://nghttp2.org/
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl https://nghttp2.org/
|
||||
@@ -150,8 +152,8 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://localhost:8443"</span><span style="color:#323232;">);
|
||||
@@ -162,11 +164,11 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_ca_cert_path</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/etc/ssl/certs/ca-certificates.crt</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://nghttp2.org"</span><span style="color:#323232;">);
|
||||
@@ -174,8 +176,8 @@
|
||||
</span><span style="color:#323232;">
|
||||
</span><span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">);
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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/
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> --cacert</span><span style="color:#c0c5ce;"> /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl --cacert /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/
|
||||
@@ -183,11 +185,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">enable_server_certificate_verification</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">false</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://localhost:8443"</span><span style="color:#323232;">);
|
||||
@@ -195,8 +197,8 @@
|
||||
</span><span style="color:#323232;">
|
||||
</span><span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">);
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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/
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -k</span><span style="color:#c0c5ce;"> https://localhost:8443/
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -k https://localhost:8443/
|
||||
@@ -206,14 +208,14 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/httpbin/redirect/3</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 302
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Location</span><span style="color:#c0c5ce;">") << std::endl;
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://nghttp2.org"</span><span style="color:#323232;">);
|
||||
@@ -224,22 +226,22 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->get_header_value(</span><span style="color:#183691;">"Location"</span><span style="color:#323232;">) </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl;
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>Call <code>set_follow_location(true)</code> to automatically follow redirects and get the final response.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_follow_location</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/httpbin/redirect/3</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200 (the final response)
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://nghttp2.org"</span><span style="color:#323232;">);
|
||||
@@ -250,8 +252,8 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->status </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// 200 (the final response)
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -L</span><span style="color:#c0c5ce;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -L https://nghttp2.org/httpbin/redirect/3
|
||||
@@ -267,7 +269,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -106,8 +108,8 @@
|
||||
<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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">openssl</span><span style="color:#c0c5ce;"> req</span><span style="color:#bf616a;"> -x509 -noenc -keyout</span><span style="color:#c0c5ce;"> key.pem</span><span style="color:#bf616a;"> -out</span><span style="color:#c0c5ce;"> cert.pem</span><span style="color:#bf616a;"> -subj</span><span style="color:#c0c5ce;"> /CN=localhost
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">openssl req -x509 -noenc -keyout key.pem -out cert.pem -subj /CN=localhost
|
||||
@@ -120,21 +122,21 @@
|
||||
</ul>
|
||||
<h2>A Minimal HTTPS Server</h2>
|
||||
<p>Once you have your certificate, let's write the server.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::SSLServer </span><span style="color:#8fa1b3;">svr</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">key.pem</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, HTTPS!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on https://localhost:8443</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8443</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -157,9 +159,9 @@
|
||||
<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-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -k</span><span style="color:#c0c5ce;"> https://localhost:8443/
|
||||
</span><span style="color:#65737e;"># Hello, HTTPS!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -k https://localhost:8443/
|
||||
@@ -171,20 +173,20 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> cli.</span><span style="color:#8fa1b3;">enable_server_certificate_verification</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">false</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello, HTTPS!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -204,20 +206,20 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> cli.</span><span style="color:#8fa1b3;">set_ca_cert_path</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello, HTTPS!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -256,7 +258,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -106,23 +108,23 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg); </span><span style="color:#65737e;">// Send back the received message as-is
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -147,29 +149,29 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::ws::WebSocketClient </span><span style="color:#8fa1b3;">client</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">ws://localhost:8080/ws</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(!client.</span><span style="color:#8fa1b3;">connect</span><span style="color:#c0c5ce;">()) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Connection failed</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Send a message
|
||||
</span><span style="color:#c0c5ce;"> client.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, WebSocket!</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Receive a response from the server
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(client.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << msg << std::endl; </span><span style="color:#65737e;">// Hello, WebSocket!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> client.</span><span style="color:#8fa1b3;">close</span><span style="color:#c0c5ce;">();
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -199,18 +201,18 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> httplib::ws::ReadResult ret;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">((ret = ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg))) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(ret == httplib::ws::Binary) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg.</span><span style="color:#8fa1b3;">data</span><span style="color:#c0c5ce;">(), msg.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()); </span><span style="color:#65737e;">// Send as binary
|
||||
</span><span style="color:#c0c5ce;"> } </span><span style="color:#b48ead;">else </span><span style="color:#c0c5ce;">{
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg); </span><span style="color:#65737e;">// Send as text
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.WebSocket(</span><span style="color:#183691;">"/ws"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;"> httplib::Request </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">, httplib::ws::WebSocket </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">ws) {
|
||||
@@ -233,19 +235,19 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &req, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> token = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Authorization</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(token.</span><span style="color:#8fa1b3;">empty</span><span style="color:#c0c5ce;">()) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">close</span><span style="color:#c0c5ce;">(httplib::ws::CloseStatus::PolicyViolation, "</span><span style="color:#a3be8c;">unauthorized</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg);
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.WebSocket(</span><span style="color:#183691;">"/ws"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;"> httplib::Request </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">req, httplib::ws::WebSocket </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">ws) {
|
||||
@@ -264,17 +266,17 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::SSLServer </span><span style="color:#8fa1b3;">svr</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">key.pem</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg);
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8443</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::SSLServer </span><span style="font-weight:bold;color:#795da3;">svr</span><span style="color:#323232;">(</span><span style="color:#183691;">"cert.pem"</span><span style="color:#323232;">, </span><span style="color:#183691;">"key.pem"</span><span style="color:#323232;">);
|
||||
@@ -290,8 +292,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>On the client side, use the <code>wss://</code> scheme.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::ws::WebSocketClient </span><span style="color:#8fa1b3;">client</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">wss://localhost:8443/ws</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::ws::WebSocketClient </span><span style="font-weight:bold;color:#795da3;">client</span><span style="color:#323232;">(</span><span style="color:#183691;">"wss://localhost:8443/ws"</span><span style="color:#323232;">);
|
||||
@@ -308,7 +310,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,16 +107,16 @@
|
||||
<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-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:11434</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> result = </span><span style="color:#8fa1b3;">httplib::stream::Get</span><span style="color:#c0c5ce;">(cli, "</span><span style="color:#a3be8c;">/api/generate</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(result) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(result.</span><span style="color:#8fa1b3;">next</span><span style="color:#c0c5ce;">()) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout.</span><span style="color:#8fa1b3;">write</span><span style="color:#c0c5ce;">(result.</span><span style="color:#8fa1b3;">data</span><span style="color:#c0c5ce;">(), result.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">());
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:11434"</span><span style="color:#323232;">);
|
||||
@@ -129,13 +131,13 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/stream</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const char </span><span style="color:#c0c5ce;">*data, size_t len) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout.</span><span style="color:#8fa1b3;">write</span><span style="color:#c0c5ce;">(data, len);
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -147,25 +149,25 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// With known size (sets Content-Length)
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/file</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> size = </span><span style="color:#8fa1b3;">get_file_size</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">large.bin</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content_provider</span><span style="color:#c0c5ce;">(size, "</span><span style="color:#a3be8c;">application/octet-stream</span><span style="color:#c0c5ce;">",
|
||||
</span><span style="color:#c0c5ce;"> [](size_t offset, size_t length, httplib::DataSink &sink) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Send 'length' bytes starting from 'offset'
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// Unknown size (Chunked Transfer Encoding)
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/stream</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_chunked_content_provider</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">",
|
||||
</span><span style="color:#c0c5ce;"> [](size_t offset, httplib::DataSink &sink) {
|
||||
</span><span style="color:#c0c5ce;"> sink.</span><span style="color:#8fa1b3;">write</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">chunk</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">6</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">; </span><span style="color:#65737e;">// Return false to finish
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// With known size (sets Content-Length)
|
||||
@@ -189,12 +191,12 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", {}, {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#8fa1b3;">httplib::make_file_provider</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">/path/to/large-file.zip</span><span style="color:#c0c5ce;">")
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -206,15 +208,15 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">httplib::sse::SSEClient </span><span style="color:#8fa1b3;">sse</span><span style="color:#c0c5ce;">(</span><span style="color:#bf616a;">cli</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">/events</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">sse.</span><span style="color:#8fa1b3;">on_message</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << msg.</span><span style="color:#bf616a;">event </span><span style="color:#c0c5ce;"><< "</span><span style="color:#a3be8c;">: </span><span style="color:#c0c5ce;">" << msg.</span><span style="color:#bf616a;">data </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">sse.</span><span style="color:#8fa1b3;">start</span><span style="color:#c0c5ce;">(); </span><span style="color:#65737e;">// Blocking, with auto-reconnection
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -228,10 +230,10 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>You can also set separate handlers for each event type.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">sse.</span><span style="color:#8fa1b3;">on_event</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">update</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Only handles "update" events
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">sse.on_event(</span><span style="color:#183691;">"update"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;"> httplib::sse::SSEMessage </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">msg) {
|
||||
@@ -241,10 +243,10 @@
|
||||
</div></div>
|
||||
<h2>Authentication</h2>
|
||||
<p>The client has helpers for Basic auth, Bearer Token auth, and Digest auth.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://api.example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_basic_auth</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">user</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">password</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_bearer_token_auth</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">my-token</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://api.example.com"</span><span style="color:#323232;">);
|
||||
@@ -259,10 +261,10 @@
|
||||
<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-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_compress</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// Compress request body
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_decompress</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// Decompress response body
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -272,10 +274,10 @@
|
||||
</div></div>
|
||||
<h2>Proxy</h2>
|
||||
<p>You can connect through an HTTP proxy.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_proxy</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">proxy.example.com</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_proxy_basic_auth</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">user</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">password</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -285,11 +287,11 @@
|
||||
</div></div>
|
||||
<h2>Timeouts</h2>
|
||||
<p>You can set connection, read, and write timeouts individually.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_connection_timeout</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">5</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// 5 seconds
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_read_timeout</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">10</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// 10 seconds
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_write_timeout</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">10</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// 10 seconds
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -300,9 +302,9 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_keep_alive</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -311,16 +313,16 @@
|
||||
</div></div>
|
||||
<h2>Server Middleware</h2>
|
||||
<p>You can hook into request processing before and after handlers run.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_pre_routing_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Runs before every request
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return</span><span style="color:#c0c5ce;"> httplib::Server::HandlerResponse::Unhandled; </span><span style="color:#65737e;">// Continue to normal routing
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_post_routing_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Runs after the response is sent
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">X-Server</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">cpp-httplib</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_pre_routing_handler([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -335,16 +337,16 @@
|
||||
</span></pre>
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_pre_routing_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> req.</span><span style="color:#bf616a;">user_data</span><span style="color:#c0c5ce;">["</span><span style="color:#a3be8c;">auth_user</span><span style="color:#c0c5ce;">"] = </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">alice</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return</span><span style="color:#c0c5ce;"> httplib::Server::HandlerResponse::Unhandled;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/me</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> user = std::</span><span style="color:#8fa1b3;">any_cast</span><span style="color:#c0c5ce;"><std::string>(req.</span><span style="color:#bf616a;">user_data</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">auth_user</span><span style="color:#c0c5ce;">"));
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, </span><span style="color:#c0c5ce;">" + user, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_pre_routing_handler([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -359,15 +361,15 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>You can also customize error and exception handlers.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_error_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Custom Error Page</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/html</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_exception_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res, std::exception_ptr ep) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;">= </span><span style="color:#d08770;">500</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Internal Server Error</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_error_handler([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -382,10 +384,10 @@
|
||||
</div></div>
|
||||
<h2>Logging</h2>
|
||||
<p>You can set a logger on both the server and the client.</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_logger</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << req.</span><span style="color:#bf616a;">method </span><span style="color:#c0c5ce;"><< " " << req.</span><span style="color:#bf616a;">path </span><span style="color:#c0c5ce;"><< " " << res.</span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_logger([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">res) {
|
||||
@@ -395,11 +397,11 @@
|
||||
</div></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-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// Server
|
||||
</span><span style="color:#c0c5ce;">httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_address_family</span><span style="color:#c0c5ce;">(AF_UNIX);
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/tmp/httplib.sock</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// Server
|
||||
@@ -407,13 +409,13 @@
|
||||
</span><span style="color:#323232;">svr.set_address_family(AF_UNIX);
|
||||
</span><span style="color:#323232;">svr.listen(</span><span style="color:#183691;">"/tmp/httplib.sock"</span><span style="color:#323232;">, </span><span style="color:#0086b3;">0</span><span style="color:#323232;">);
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// Client
|
||||
</span><span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_address_family</span><span style="color:#c0c5ce;">(AF_UNIX);
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_hostname_addr_map</span><span style="color:#c0c5ce;">({{"</span><span style="color:#a3be8c;">localhost</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">/tmp/httplib.sock</span><span style="color:#c0c5ce;">"}});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// Client
|
||||
@@ -440,7 +442,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/en/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<a href="/cpp-httplib/en/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<a href="/cpp-httplib/en/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -121,7 +123,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -89,7 +91,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -88,7 +90,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,8 +107,8 @@
|
||||
<p>cpp-httplibを始めるのに必要なのは、<code>httplib.h</code>とC++コンパイラーだけです。ファイルをダウンロードして、Hello Worldサーバーを動かすところまでやってみましょう。</p>
|
||||
<h2>httplib.h の入手</h2>
|
||||
<p>GitHubから直接ダウンロードできます。常に最新版を使ってください。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -LO</span><span style="color:#c0c5ce;"> https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -LO https://github.com/yhirose/cpp-httplib/raw/refs/tags/latest/httplib.h
|
||||
@@ -121,18 +123,18 @@
|
||||
</tbody></table>
|
||||
<h2>Hello World サーバー</h2>
|
||||
<p>次のコードを <code>server.cpp</code> として保存しましょう。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request&, httplib::Response& res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, World!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -151,17 +153,17 @@
|
||||
<p>たった数行で、HTTPリクエストに応答するサーバーが書けます。</p>
|
||||
<h2>コンパイルと実行</h2>
|
||||
<p>このチュートリアルのサンプルコードは、コードを簡潔に書けるC++17で書いています。cpp-httplib自体はC++11でもコンパイルできます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;"># macOS
|
||||
</span><span style="color:#6699cc;">clang++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -o</span><span style="color:#d3d0c8;"> server server.cpp
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Linux
|
||||
</span><span style="color:#747369;"># `-pthread`: cpp-httplibは内部でスレッドを使用
|
||||
</span><span style="color:#6699cc;">clang++</span><span style="color:#f2777a;"> -std</span><span style="color:#d3d0c8;">=c++17</span><span style="color:#f2777a;"> -pthread -o</span><span style="color:#d3d0c8;"> server server.cpp
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#747369;"># `/EHsc`: C++例外処理を有効化
|
||||
</span><span style="color:#6699cc;">cl</span><span style="color:#d3d0c8;"> /EHsc /std:c++17 server.cpp
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;"># macOS
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Linux
|
||||
</span><span style="color:#65737e;"># `-pthread`: cpp-httplibは内部でスレッドを使用
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -pthread -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#65737e;"># `/EHsc`: C++例外処理を有効化
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#c0c5ce;"> /EHsc /std:c++17 server.cpp
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;"># macOS
|
||||
@@ -177,12 +179,12 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>コンパイルできたら実行します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;"># macOS / Linux
|
||||
</span><span style="color:#8fa1b3;">./server
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Windows
|
||||
</span><span style="color:#8fa1b3;">server.exe
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;"># macOS / Linux
|
||||
@@ -194,9 +196,9 @@
|
||||
</div></div>
|
||||
<p>ブラウザで <code>http://localhost:8080</code> を開いてください。"Hello, World!" と表示されれば成功です。</p>
|
||||
<p><code>curl</code> でも確認できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/
|
||||
</span><span style="color:#65737e;"># Hello, World!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/
|
||||
@@ -214,7 +216,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,53 +107,53 @@
|
||||
<p>cpp-httplibはサーバーだけでなく、HTTPクライアント機能も備えています。<code>httplib::Client</code> を使って、GETやPOSTリクエストを送ってみましょう。</p>
|
||||
<h2>テスト用サーバーの準備</h2>
|
||||
<p>クライアントの動作を確認するために、リクエストを受け付けるサーバーを用意します。次のコードを保存し、前章と同じ手順でコンパイル・実行してください。サーバーの詳しい解説は次章で行います。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#c0c5ce;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::string result;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">for </span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#c0c5ce;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#c0c5ce;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#c0c5ce;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#c0c5ce;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#c0c5ce;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#c0c5ce;">[</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">];
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -204,19 +206,19 @@
|
||||
</div></div>
|
||||
<h2>GETリクエスト</h2>
|
||||
<p>サーバーが起動したら、別のターミナルを開いて試してみましょう。まず、最もシンプルなGETリクエストです。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -235,9 +237,9 @@
|
||||
</div></div>
|
||||
<p><code>httplib::Client</code> のコンストラクターにサーバーのアドレスを渡し、<code>Get()</code> でリクエストを送ります。戻り値の <code>res</code> からステータスコードやボディを取得できます。</p>
|
||||
<p>対応する <code>curl</code> コマンドはこうなります。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/hi
|
||||
</span><span style="color:#65737e;"># Hello!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/hi
|
||||
@@ -246,18 +248,18 @@
|
||||
</div></div>
|
||||
<h2>レスポンスの確認</h2>
|
||||
<p>レスポンスには、ステータスコードとボディ以外にもヘッダー情報が含まれています。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// ステータスコード
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// ボディ
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// Hello!
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// ヘッダー
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#6699cc;">get_header_value</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Content-Type</span><span style="color:#d3d0c8;">") << std::endl; </span><span style="color:#747369;">// text/plain
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// ステータスコード
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// ボディ
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello!
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// ヘッダー
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Content-Type</span><span style="color:#c0c5ce;">") << std::endl; </span><span style="color:#65737e;">// text/plain
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">);
|
||||
@@ -276,11 +278,11 @@
|
||||
<p><code>res->body</code> は <code>std::string</code> なので、JSON レスポンスをパースしたい場合は <a href="https://github.com/nlohmann/json">nlohmann/json</a> などの JSON ライブラリにそのまま渡せます。</p>
|
||||
<h2>クエリパラメーター</h2>
|
||||
<p>GETリクエストにクエリパラメーターを付けるには、URLに直接書くか、<code>httplib::Params</code> を使います。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", httplib::Params{{"</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">cpp-httplib</span><span style="color:#c0c5ce;">"}});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Query: cpp-httplib
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/search"</span><span style="color:#323232;">, httplib::Params{{</span><span style="color:#183691;">"q"</span><span style="color:#323232;">, </span><span style="color:#183691;">"cpp-httplib"</span><span style="color:#323232;">}});
|
||||
@@ -290,9 +292,9 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p><code>httplib::Params</code> を使うと、特殊文字のURLエンコードを自動で行ってくれます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">http://localhost:8080/search?q=cpp-httplib</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#65737e;"># Query: cpp-httplib
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl </span><span style="color:#183691;">"http://localhost:8080/search?q=cpp-httplib"
|
||||
@@ -301,11 +303,11 @@
|
||||
</div></div>
|
||||
<h2>パスパラメーター</h2>
|
||||
<p>URLのパスに値を直接埋め込む場合も、クライアント側は特別なAPIは不要です。パスをそのまま <code>Get()</code> に渡すだけです。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/42</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// User ID: 42
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/users/42"</span><span style="color:#323232;">);
|
||||
@@ -313,9 +315,9 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->body </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// User ID: 42
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/users/42
|
||||
</span><span style="color:#65737e;"># User ID: 42
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/users/42
|
||||
@@ -323,11 +325,11 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>テスト用サーバーには、正規表現でIDを数字のみに絞った <code>/files/(\d+)</code> もあります。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/files/42</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// File ID: 42
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/files/42"</span><span style="color:#323232;">);
|
||||
@@ -335,9 +337,9 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->body </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// File ID: 42
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080/files/42
|
||||
</span><span style="color:#65737e;"># File ID: 42
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080/files/42
|
||||
@@ -347,18 +349,18 @@
|
||||
<p><code>/files/abc</code> のように数字以外を渡すと404が返ります。仕組みは次章で解説します。</p>
|
||||
<h2>リクエストヘッダー</h2>
|
||||
<p>カスタムHTTPヘッダーを付けるには、<code>httplib::Headers</code> を渡します。<code>Get()</code> や <code>Post()</code> のどちらでも使えます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", httplib::Headers{
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">Authorization</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Bearer my-token</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, httplib::Headers{
|
||||
</span><span style="color:#323232;"> {</span><span style="color:#183691;">"Authorization"</span><span style="color:#323232;">, </span><span style="color:#183691;">"Bearer my-token"</span><span style="color:#323232;">}
|
||||
</span><span style="color:#323232;">});
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -H </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">Authorization: Bearer my-token</span><span style="color:#c0c5ce;">" http://localhost:8080/hi
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -H </span><span style="color:#183691;">"Authorization: Bearer my-token"</span><span style="color:#323232;"> http://localhost:8080/hi
|
||||
@@ -366,12 +368,12 @@
|
||||
</div></div>
|
||||
<h2>POSTリクエスト</h2>
|
||||
<p>テキストデータをPOSTしてみましょう。<code>Post()</code> の第2引数にボディ、第3引数にContent-Typeを指定します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Hello, Server!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello, Server!
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Post(</span><span style="color:#183691;">"/post"</span><span style="color:#323232;">, </span><span style="color:#183691;">"Hello, Server!"</span><span style="color:#323232;">, </span><span style="color:#183691;">"text/plain"</span><span style="color:#323232;">);
|
||||
@@ -382,9 +384,9 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>テスト用サーバーの <code>/post</code> はボディをそのまま返すので、送った文字列がそのまま返ってきます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -X</span><span style="color:#c0c5ce;"> POST</span><span style="color:#bf616a;"> -H </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">Content-Type: text/plain</span><span style="color:#c0c5ce;">"</span><span style="color:#bf616a;"> -d </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">Hello, Server!</span><span style="color:#c0c5ce;">" http://localhost:8080/post
|
||||
</span><span style="color:#65737e;"># Hello, Server!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -X POST -H </span><span style="color:#183691;">"Content-Type: text/plain"</span><span style="color:#323232;"> -d </span><span style="color:#183691;">"Hello, Server!"</span><span style="color:#323232;"> http://localhost:8080/post
|
||||
@@ -393,16 +395,16 @@
|
||||
</div></div>
|
||||
<h2>フォームデータの送信</h2>
|
||||
<p>HTMLフォームのように、キーと値のペアを送ることもできます。<code>httplib::Params</code> を使います。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", httplib::Params{
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">name</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Alice</span><span style="color:#c0c5ce;">"},
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">age</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">30</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// age = 30
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// name = Alice
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Post(</span><span style="color:#183691;">"/submit"</span><span style="color:#323232;">, httplib::Params{
|
||||
@@ -417,8 +419,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>これは <code>application/x-www-form-urlencoded</code> 形式で送信されます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -X</span><span style="color:#c0c5ce;"> POST</span><span style="color:#bf616a;"> -d </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">name=Alice&age=30</span><span style="color:#c0c5ce;">" http://localhost:8080/submit
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -X POST -d </span><span style="color:#183691;">"name=Alice&age=30"</span><span style="color:#323232;"> http://localhost:8080/submit
|
||||
@@ -426,13 +428,13 @@
|
||||
</div></div>
|
||||
<h2>ファイルのPOST</h2>
|
||||
<p>ファイルをアップロードするには、<code>httplib::UploadFormDataItems</code> を使ってマルチパートフォームデータとして送信します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", httplib::UploadFormDataItems{
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">Hello, File!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">hello.txt</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// hello.txt (12 bytes)
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Post(</span><span style="color:#183691;">"/upload"</span><span style="color:#323232;">, httplib::UploadFormDataItems{
|
||||
@@ -444,8 +446,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p><code>UploadFormDataItems</code> の各要素は <code>{name, content, filename, content_type}</code> の4つのフィールドで構成されます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -F </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">file=Hello, File!;filename=hello.txt;type=text/plain</span><span style="color:#c0c5ce;">" http://localhost:8080/upload
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -F </span><span style="color:#183691;">"file=Hello, File!;filename=hello.txt;type=text/plain"</span><span style="color:#323232;"> http://localhost:8080/upload
|
||||
@@ -453,24 +455,24 @@
|
||||
</div></div>
|
||||
<h2>エラーハンドリング</h2>
|
||||
<p>ネットワーク通信では、サーバーに接続できない場合があります。<code>res</code> が有効かどうかを必ず確認しましょう。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:9999</span><span style="color:#d3d0c8;">"); </span><span style="color:#747369;">// 存在しないポート
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(!res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// 接続エラー
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Error: </span><span style="color:#d3d0c8;">" << </span><span style="color:#6699cc;">httplib::to_string</span><span style="color:#d3d0c8;">(res.</span><span style="color:#6699cc;">error</span><span style="color:#d3d0c8;">()) << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// Error: Connection
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// ここに到達すればレスポンスを受信できている
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;">!= </span><span style="color:#f99157;">200</span><span style="color:#d3d0c8;">) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">HTTP Error: </span><span style="color:#d3d0c8;">" << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl;
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:9999</span><span style="color:#c0c5ce;">"); </span><span style="color:#65737e;">// 存在しないポート
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(!res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// 接続エラー
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#c0c5ce;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#c0c5ce;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#c0c5ce;">()) << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// Error: Connection
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// ここに到達すればレスポンスを受信できている
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;">!= </span><span style="color:#d08770;">200</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">HTTP Error: </span><span style="color:#c0c5ce;">" << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:9999"</span><span style="color:#323232;">); </span><span style="font-style:italic;color:#969896;">// 存在しないポート
|
||||
@@ -507,7 +509,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,8 +107,8 @@
|
||||
<p>前章ではクライアントからリクエストを送りました。そのとき、テスト用サーバーを用意しましたね。この章では、あのサーバーの仕組みをひとつずつ紐解いていきます。</p>
|
||||
<h2>サーバーの起動</h2>
|
||||
<p>ルーティングを登録したら、最後に <code>svr.listen()</code> を呼んでサーバーを起動します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.listen(</span><span style="color:#183691;">"0.0.0.0"</span><span style="color:#323232;">, </span><span style="color:#0086b3;">8080</span><span style="color:#323232;">);
|
||||
@@ -116,12 +118,12 @@
|
||||
<p><code>listen()</code> はブロッキング呼び出しです。サーバーが停止するまで、この行から先には進みません。ターミナルで <code>Ctrl+C</code> を押すか、別スレッドから <code>svr.stop()</code> を呼ぶまでサーバーは動き続けます。</p>
|
||||
<h2>ルーティング</h2>
|
||||
<p>サーバーの核になるのは「ルーティング」です。どのURLに、どのHTTPメソッドでアクセスされたら、何をするか。それを登録する仕組みです。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &req, httplib::Response &res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Server svr;
|
||||
@@ -133,11 +135,11 @@
|
||||
</div></div>
|
||||
<p><code>svr.Get()</code> は、GETリクエストに対するハンドラーを登録します。第1引数がパス、第2引数がハンドラー関数です。<code>/hi</code> にGETリクエストが来たら、このラムダが呼ばれます。</p>
|
||||
<p>HTTPメソッドごとにメソッドが用意されています。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// GET
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// POST
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Put</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// PUT
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Delete</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/path</span><span style="color:#c0c5ce;">", handler); </span><span style="color:#65737e;">// DELETE
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/path"</span><span style="color:#323232;">, handler); </span><span style="font-style:italic;color:#969896;">// GET
|
||||
@@ -147,10 +149,10 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>ハンドラーのシグネチャは <code>(const httplib::Request &req, httplib::Response &res)</code> です。<code>auto</code> を使って短く書くこともできます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -163,11 +165,11 @@
|
||||
<p>ハンドラーの第1引数 <code>req</code> から、クライアントが送ってきた情報を読み取れます。</p>
|
||||
<h3>ボディ</h3>
|
||||
<p><code>req.body</code> でリクエストボディを取得できます。型は <code>std::string</code> です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// クライアントが送ったボディをそのまま返す
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(req.</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">, "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// クライアントが送ったボディをそのまま返す
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/post"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -178,11 +180,11 @@
|
||||
</div></div>
|
||||
<h3>ヘッダー</h3>
|
||||
<p><code>req.get_header_value()</code> でリクエストヘッダーの値を取得できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/check</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> auth = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Authorization</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Auth: </span><span style="color:#c0c5ce;">" + auth, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/check"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -193,11 +195,11 @@
|
||||
</div></div>
|
||||
<h3>クエリパラメーターとフォームデータ</h3>
|
||||
<p><code>req.get_param_value()</code> でパラメーターを取得できます。GETのクエリパラメーターと、POSTのフォームデータの両方に使えます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#c0c5ce;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/search"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -208,14 +210,14 @@
|
||||
</div></div>
|
||||
<p><code>/search?q=cpp-httplib</code> にアクセスすると、<code>q</code> の値は <code>"cpp-httplib"</code> になります。</p>
|
||||
<p>すべてのパラメーターをループで処理したいときは、<code>req.params</code> を使います。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::string result;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">for </span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#c0c5ce;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/submit"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -229,12 +231,12 @@
|
||||
</div></div>
|
||||
<h3>ファイルアップロード</h3>
|
||||
<p>マルチパートフォームでアップロードされたファイルは、<code>req.form.get_file()</code> で取得します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#c0c5ce;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#c0c5ce;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/upload"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -247,11 +249,11 @@
|
||||
<p><code>f.filename</code> でファイル名、<code>f.content</code> でファイルの中身にアクセスできます。</p>
|
||||
<h2>パスパラメーター</h2>
|
||||
<p>URLの一部を変数として受け取りたいことがあります。たとえば <code>/users/42</code> の <code>42</code> を取得したい場合です。<code>:param</code> 記法を使うと、URLの一部をキャプチャできます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#c0c5ce;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/users/:id"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -262,12 +264,12 @@
|
||||
</div></div>
|
||||
<p><code>/users/42</code> にアクセスすると、<code>req.path_params.at("id")</code> は <code>"42"</code> を返します。<code>/users/100</code> なら <code>"100"</code> です。</p>
|
||||
<p>複数のパスパラメーターも使えます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:user_id/posts/:post_id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> user_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">user_id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> post_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">post_id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User: </span><span style="color:#c0c5ce;">" + user_id + "</span><span style="color:#a3be8c;">, Post: </span><span style="color:#c0c5ce;">" + post_id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/users/:user_id/posts/:post_id"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -279,12 +281,12 @@
|
||||
</div></div>
|
||||
<h3>正規表現パターン</h3>
|
||||
<p><code>:param</code> の代わりに正規表現をパスに書くこともできます。キャプチャグループの値は <code>req.matches</code> で取得します。型は <code>std::smatch</code> です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// 数字のみのIDを受け付ける
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">"(</span><span style="color:#99cc99;">/files/(\d+)</span><span style="color:#d3d0c8;">)", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">matches</span><span style="color:#d3d0c8;">[</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">]; </span><span style="color:#747369;">// 最初のキャプチャグループ
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">File ID: </span><span style="color:#d3d0c8;">" + </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">(id), "</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// 数字のみのIDを受け付ける
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#c0c5ce;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#c0c5ce;">[</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">]; </span><span style="color:#65737e;">// 最初のキャプチャグループ
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// 数字のみのIDを受け付ける
|
||||
@@ -299,10 +301,10 @@
|
||||
<p>ハンドラーの第2引数 <code>res</code> を使って、クライアントに返すレスポンスを組み立てます。</p>
|
||||
<h3>ボディとContent-Type</h3>
|
||||
<p><code>res.set_content()</code> でボディとContent-Typeを設定します。これだけでステータスコード200のレスポンスが返ります。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -312,11 +314,11 @@
|
||||
</div></div>
|
||||
<h3>ステータスコード</h3>
|
||||
<p>ステータスコードを変えたいときは、<code>res.status</code> に代入します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/not-found</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;">= </span><span style="color:#d08770;">404</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Not found</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/not-found"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -327,11 +329,11 @@
|
||||
</div></div>
|
||||
<h3>レスポンスヘッダー</h3>
|
||||
<p><code>res.set_header()</code> でレスポンスヘッダーを追加できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/with-header</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">X-Custom</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">my-value</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/with-header"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -343,10 +345,10 @@
|
||||
<h2>前章のサーバーを読み解く</h2>
|
||||
<p>ここまでの知識を使って、前章で用意したテスト用サーバーを改めて見てみましょう。</p>
|
||||
<h3>GET /hi</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/hi</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/hi"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -356,11 +358,11 @@
|
||||
</div></div>
|
||||
<p>最もシンプルなハンドラーです。リクエストの情報は使わないので、<code>req</code> の変数名を省略しています。<code>"Hello!"</code> というテキストをそのまま返します。</p>
|
||||
<h3>GET /search</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/search</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">q</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Query: </span><span style="color:#c0c5ce;">" + q, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/search"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -371,10 +373,10 @@
|
||||
</div></div>
|
||||
<p><code>req.get_param_value("q")</code> でクエリパラメーター <code>q</code> の値を取り出します。<code>/search?q=cpp-httplib</code> なら、レスポンスは <code>"Query: cpp-httplib"</code> になります。</p>
|
||||
<h3>POST /post</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/post</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/post"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -384,14 +386,14 @@
|
||||
</div></div>
|
||||
<p>クライアントが送ったリクエストボディを、そのままレスポンスとして返すエコーサーバーです。<code>req.body</code> にボディが丸ごと入っています。</p>
|
||||
<h3>POST /submit</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/submit</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::string result;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">for </span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#c0c5ce;">) {
|
||||
</span><span style="color:#c0c5ce;"> result += key + "</span><span style="color:#a3be8c;"> = </span><span style="color:#c0c5ce;">" + val + "</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(result, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/submit"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -405,12 +407,12 @@
|
||||
</div></div>
|
||||
<p>フォームデータとして送られたキーと値のペアを、<code>req.params</code> でループ処理しています。構造化束縛 <code>auto &[key, val]</code> を使って、各ペアを取り出しています。</p>
|
||||
<h3>POST /upload</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#c0c5ce;">+ "</span><span style="color:#a3be8c;"> (</span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#c0c5ce;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()) + "</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#c0c5ce;">";
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(content, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Post(</span><span style="color:#183691;">"/upload"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -422,11 +424,11 @@
|
||||
</div></div>
|
||||
<p>マルチパートフォームで送られたファイルを受け取ります。<code>req.form.get_file("file")</code> で <code>"file"</code> という名前のフィールドを取得し、<code>f.filename</code> と <code>f.content.size()</code> でファイル名とサイズを返しています。</p>
|
||||
<h3>GET /users/:id</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">id</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">User ID: </span><span style="color:#c0c5ce;">" + id, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="color:#183691;">"/users/:id"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -437,11 +439,11 @@
|
||||
</div></div>
|
||||
<p><code>:id</code> の部分がパスパラメーターです。<code>req.path_params.at("id")</code> で値を取り出しています。<code>/users/42</code> なら <code>"42"</code>、<code>/users/alice</code> なら <code>"alice"</code> が得られます。</p>
|
||||
<h3>GET /files/(\d+)</h3>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#c0c5ce;">)", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#c0c5ce;">[</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">];
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">File ID: </span><span style="color:#c0c5ce;">" + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">(id), "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.Get(</span><span style="font-weight:bold;color:#a71d5d;">R</span><span style="color:#183691;">"(/files/(\d+))"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -462,7 +464,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,18 +107,18 @@
|
||||
<p>cpp-httplibは、HTMLやCSS、画像ファイルなどの静的ファイルも配信できます。面倒な設定は要りません。<code>set_mount_point()</code> を1行呼ぶだけです。</p>
|
||||
<h2>set_mount_point の基本</h2>
|
||||
<p>さっそくやってみましょう。<code>set_mount_point()</code> は、URLのパスとローカルディレクトリを紐づけます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./html</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -134,21 +136,21 @@
|
||||
</div></div>
|
||||
<p>第1引数がURLのマウントポイント、第2引数がローカルのディレクトリパスです。この例だと、<code>/</code> へのリクエストを <code>./html</code> ディレクトリから配信します。</p>
|
||||
<p>試してみましょう。まず <code>html</code> ディレクトリを作って、<code>index.html</code> を置きます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">mkdir</span><span style="color:#d3d0c8;"> html
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">mkdir</span><span style="color:#c0c5ce;"> html
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">mkdir html
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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;">>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;"><!</span><span style="color:#bf616a;">DOCTYPE</span><span style="color:#c0c5ce;"> html>
|
||||
</span><span style="color:#c0c5ce;"><</span><span style="color:#bf616a;">html</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"><</span><span style="color:#bf616a;">head</span><span style="color:#c0c5ce;">><</span><span style="color:#bf616a;">title</span><span style="color:#c0c5ce;">>My Page</</span><span style="color:#bf616a;">title</span><span style="color:#c0c5ce;">></</span><span style="color:#bf616a;">head</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"><</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"> <</span><span style="color:#bf616a;">h1</span><span style="color:#c0c5ce;">>Hello from cpp-httplib!</</span><span style="color:#bf616a;">h1</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"> <</span><span style="color:#bf616a;">p</span><span style="color:#c0c5ce;">>This is a static file.</</span><span style="color:#bf616a;">p</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"></</span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;"></</span><span style="color:#bf616a;">html</span><span style="color:#c0c5ce;">>
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;"><!</span><span style="color:#63a35c;">DOCTYPE</span><span style="color:#323232;"> html>
|
||||
@@ -162,9 +164,9 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>コンパイルして起動します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">g++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp</span><span style="color:#bf616a;"> -pthread
|
||||
</span><span style="color:#8fa1b3;">./server
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">g++ -std</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;">c++17 -o server server.cpp -pthread
|
||||
@@ -173,12 +175,12 @@
|
||||
</div></div>
|
||||
<p>ブラウザで <code>http://localhost:8080</code> を開いてみてください。<code>html/index.html</code> の内容が表示されるはずです。<code>http://localhost:8080/index.html</code> でも同じページが返ります。</p>
|
||||
<p>もちろん、前章のクライアントコードや <code>curl</code> でもアクセスできますよ。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost:8080</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// HTMLが表示される
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// HTMLが表示される
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -187,8 +189,8 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->body </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// HTMLが表示される
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> http://localhost:8080
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> http://localhost:8080
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl http://localhost:8080
|
||||
@@ -196,10 +198,10 @@
|
||||
</div></div>
|
||||
<h2>複数のマウントポイント</h2>
|
||||
<p><code>set_mount_point()</code> は何回でも呼べます。URLのパスごとに、別々のディレクトリを割り当てられます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/assets</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./static/assets</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/docs</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./documentation</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_mount_point(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">, </span><span style="color:#183691;">"./public"</span><span style="color:#323232;">);
|
||||
@@ -210,18 +212,18 @@
|
||||
<p><code>/assets/style.css</code> なら <code>./static/assets/style.css</code> を、<code>/docs/guide.html</code> なら <code>./documentation/guide.html</code> を配信します。</p>
|
||||
<h2>ハンドラーとの組み合わせ</h2>
|
||||
<p>静的ファイルの配信と、前章で学んだルーティングハンドラーは共存できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// APIエンドポイント
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/api/hello</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">"(</span><span style="color:#99cc99;">{"message":"Hello!"}</span><span style="color:#d3d0c8;">)", "</span><span style="color:#99cc99;">application/json</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// 静的ファイル配信
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_mount_point</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">./public</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// APIエンドポイント
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/api/hello</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">(</span><span style="color:#b48ead;">R</span><span style="color:#c0c5ce;">"(</span><span style="color:#a3be8c;">{"message":"Hello!"}</span><span style="color:#c0c5ce;">)", "</span><span style="color:#a3be8c;">application/json</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// 静的ファイル配信
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Server svr;
|
||||
@@ -240,10 +242,10 @@
|
||||
<p>ハンドラーが先に評価されます。<code>/api/hello</code> にはハンドラーが応答し、それ以外のパスは <code>./public</code> ディレクトリからファイルを探します。</p>
|
||||
<h2>レスポンスヘッダーの追加</h2>
|
||||
<p><code>set_mount_point()</code> の第3引数にヘッダーを渡すと、静的ファイルのレスポンスにカスタムヘッダーを付けられます。キャッシュ制御に便利です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_mount_point</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">./public</span><span style="color:#c0c5ce;">", {
|
||||
</span><span style="color:#c0c5ce;"> {"</span><span style="color:#a3be8c;">Cache-Control</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">max-age=3600</span><span style="color:#c0c5ce;">"}
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_mount_point(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">, </span><span style="color:#183691;">"./public"</span><span style="color:#323232;">, {
|
||||
@@ -254,14 +256,14 @@
|
||||
<p>こうすると、ブラウザは配信されたファイルを1時間キャッシュします。</p>
|
||||
<h2>静的ファイルサーバー用のDockerファイル</h2>
|
||||
<p>cpp-httplibのリポジトリには、静的ファイルサーバー用の <code>Dockerfile</code> が含まれています。Docker Hubにビルド済みイメージも公開しているので、1コマンドで起動できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">"
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">> docker run</span><span style="color:#bf616a;"> -p</span><span style="color:#c0c5ce;"> 8080:80</span><span style="color:#bf616a;"> -v</span><span style="color:#c0c5ce;"> ./my-site:/html yhirose4dockerhub/cpp-httplib-server
|
||||
</span><span style="color:#8fa1b3;">Serving</span><span style="color:#c0c5ce;"> HTTP on 0.0.0.0:80
|
||||
</span><span style="color:#8fa1b3;">Mount</span><span style="color:#c0c5ce;"> point: / -> ./html
|
||||
</span><span style="color:#8fa1b3;">Press</span><span style="color:#c0c5ce;"> Ctrl+C to shutdown gracefully...
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#c0c5ce;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#c0c5ce;">22/Feb/2026:12:00:00 +0000</span><span style="color:#b48ead;">] </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">GET / HTTP/1.1</span><span style="color:#c0c5ce;">" 200 256 "</span><span style="color:#a3be8c;">-</span><span style="color:#c0c5ce;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#c0c5ce;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#c0c5ce;">22/Feb/2026:12:00:00 +0000</span><span style="color:#b48ead;">] </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">GET /style.css HTTP/1.1</span><span style="color:#c0c5ce;">" 200 1024 "</span><span style="color:#a3be8c;">-</span><span style="color:#c0c5ce;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#8fa1b3;">192.168.65.1</span><span style="color:#c0c5ce;"> - - </span><span style="color:#b48ead;">[</span><span style="color:#c0c5ce;">22/Feb/2026:12:00:01 +0000</span><span style="color:#b48ead;">] </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">GET /favicon.ico HTTP/1.1</span><span style="color:#c0c5ce;">" 404 152 "</span><span style="color:#a3be8c;">-</span><span style="color:#c0c5ce;">" "</span><span style="color:#a3be8c;">Mozilla/5.0 ...</span><span style="color:#c0c5ce;">"
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">></span><span style="color:#323232;"> docker run -p 8080:80 -v ./my-site:/html yhirose4dockerhub/cpp-httplib-server
|
||||
@@ -285,7 +287,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -113,22 +115,22 @@
|
||||
</tbody></table>
|
||||
<h2>コンパイルオプション</h2>
|
||||
<p>TLS機能を有効にするには、<code>CPPHTTPLIB_OPENSSL_SUPPORT</code> マクロを定義してコンパイルします。前章までのコンパイルコマンドに、いくつかオプションが増えます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;"># macOS (Homebrew)
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -I</span><span style="color:#c0c5ce;">$</span><span style="color:#bf616a;">(</span><span style="color:#8fa1b3;">brew</span><span style="color:#bf616a;"> --prefix openssl)</span><span style="color:#c0c5ce;">/include \
|
||||
</span><span style="color:#bf616a;"> -L</span><span style="color:#c0c5ce;">$</span><span style="color:#bf616a;">(</span><span style="color:#8fa1b3;">brew</span><span style="color:#bf616a;"> --prefix openssl)</span><span style="color:#c0c5ce;">/lib \
|
||||
</span><span style="color:#bf616a;"> -lssl -lcrypto </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -framework</span><span style="color:#c0c5ce;"> CoreFoundation</span><span style="color:#bf616a;"> -framework</span><span style="color:#c0c5ce;"> Security \
|
||||
</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Linux
|
||||
</span><span style="color:#8fa1b3;">clang++</span><span style="color:#bf616a;"> -std</span><span style="color:#c0c5ce;">=c++17</span><span style="color:#bf616a;"> -pthread -DCPPHTTPLIB_OPENSSL_SUPPORT </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -lssl -lcrypto </span><span style="color:#c0c5ce;">\
|
||||
</span><span style="color:#bf616a;"> -o</span><span style="color:#c0c5ce;"> server server.cpp
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;"># Windows (Developer Command Prompt)
|
||||
</span><span style="color:#8fa1b3;">cl</span><span style="color:#c0c5ce;"> /EHsc /std:c++17 /DCPPHTTPLIB_OPENSSL_SUPPORT server.cpp libssl.lib libcrypto.lib
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;"># macOS (Homebrew)
|
||||
@@ -157,21 +159,21 @@
|
||||
</ul>
|
||||
<h2>動作確認</h2>
|
||||
<p>ちゃんと動くか確認してみましょう。<code>httplib::Client</code> にHTTPSのURLを渡してアクセスするだけのプログラムです。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://www.google.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Status: </span><span style="color:#c0c5ce;">" << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;"> } </span><span style="color:#b48ead;">else </span><span style="color:#c0c5ce;">{
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#c0c5ce;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#c0c5ce;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#c0c5ce;">()) << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -209,7 +211,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,22 +107,22 @@
|
||||
<p>前章でOpenSSLのセットアップが済んだので、さっそくHTTPSクライアントを使ってみましょう。2章で使った <code>httplib::Client</code> がそのまま使えます。コンストラクタに <code>https://</code> 付きのURLを渡すだけです。</p>
|
||||
<h2>GETリクエスト</h2>
|
||||
<p>実在するHTTPSサイトにアクセスしてみましょう。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#define </span><span style="color:#d3d0c8;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://nghttp2.org</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">substr</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">100</span><span style="color:#d3d0c8;">) << std::endl; </span><span style="color:#747369;">// HTMLの先頭部分
|
||||
</span><span style="color:#d3d0c8;"> } </span><span style="color:#cc99cc;">else </span><span style="color:#d3d0c8;">{
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Error: </span><span style="color:#d3d0c8;">" << </span><span style="color:#6699cc;">httplib::to_string</span><span style="color:#d3d0c8;">(res.</span><span style="color:#6699cc;">error</span><span style="color:#d3d0c8;">()) << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">substr</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">100</span><span style="color:#c0c5ce;">) << std::endl; </span><span style="color:#65737e;">// HTMLの先頭部分
|
||||
</span><span style="color:#c0c5ce;"> } </span><span style="color:#b48ead;">else </span><span style="color:#c0c5ce;">{
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Error: </span><span style="color:#c0c5ce;">" << </span><span style="color:#8fa1b3;">httplib::to_string</span><span style="color:#c0c5ce;">(res.</span><span style="color:#8fa1b3;">error</span><span style="color:#c0c5ce;">()) << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -141,8 +143,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>2章では <code>httplib::Client cli("http://localhost:8080")</code> と書きましたよね。スキームを <code>https://</code> に変えるだけです。<code>Get()</code> や <code>Post()</code> など、2章で学んだAPIはすべてそのまま使えます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> https://nghttp2.org/
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl https://nghttp2.org/
|
||||
@@ -150,8 +152,8 @@
|
||||
</div></div>
|
||||
<h2>ポートの指定</h2>
|
||||
<p>HTTPSのデフォルトポートは443です。別のポートを使いたい場合は、URLにポートを含めます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://localhost:8443"</span><span style="color:#323232;">);
|
||||
@@ -162,11 +164,11 @@
|
||||
<p>CA証明書は、macOSならKeychain、LinuxならシステムのCA証明書ストア、WindowsならWindowsの証明書ストアから自動で読み込みます。ほとんどの場合、追加の設定は要りません。</p>
|
||||
<h3>CA証明書ファイルの指定</h3>
|
||||
<p>環境によってはシステムのCA証明書が見つからないこともあります。そのときは <code>set_ca_cert_path()</code> でパスを直接指定してください。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_ca_cert_path</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/etc/ssl/certs/ca-certificates.crt</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://nghttp2.org"</span><span style="color:#323232;">);
|
||||
@@ -174,8 +176,8 @@
|
||||
</span><span style="color:#323232;">
|
||||
</span><span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">);
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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/
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> --cacert</span><span style="color:#c0c5ce;"> /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl --cacert /etc/ssl/certs/ca-certificates.crt https://nghttp2.org/
|
||||
@@ -183,11 +185,11 @@
|
||||
</div></div>
|
||||
<h3>証明書検証の無効化</h3>
|
||||
<p>開発中、自己署名証明書のサーバーに接続したいときは、検証を無効にできます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">enable_server_certificate_verification</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">false</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://localhost:8443"</span><span style="color:#323232;">);
|
||||
@@ -195,8 +197,8 @@
|
||||
</span><span style="color:#323232;">
|
||||
</span><span style="font-weight:bold;color:#a71d5d;">auto</span><span style="color:#323232;"> res </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> cli.Get(</span><span style="color:#183691;">"/"</span><span style="color:#323232;">);
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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/
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -k</span><span style="color:#c0c5ce;"> https://localhost:8443/
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -k https://localhost:8443/
|
||||
@@ -206,14 +208,14 @@
|
||||
<h2>リダイレクトの追跡</h2>
|
||||
<p>HTTPSサイトへのアクセスでは、リダイレクトに遭遇することがよくあります。たとえば <code>http://</code> から <code>https://</code> へ、あるいは <code>www</code> なしから <code>www</code> ありへ転送されるケースです。</p>
|
||||
<p>デフォルトではリダイレクトを追跡しません。リダイレクト先は <code>Location</code> ヘッダーで確認できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/httpbin/redirect/3</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 302
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Location</span><span style="color:#c0c5ce;">") << std::endl;
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://nghttp2.org"</span><span style="color:#323232;">);
|
||||
@@ -224,22 +226,22 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->get_header_value(</span><span style="color:#183691;">"Location"</span><span style="color:#323232;">) </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl;
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#6699cc;">curl</span><span style="color:#d3d0c8;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#c0c5ce;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p><code>set_follow_location(true)</code> を設定すると、リダイレクトを自動で追跡して、最終的なレスポンスを返してくれます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://nghttp2.org</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_follow_location</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/httpbin/redirect/3</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(res) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << res-></span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;"><< std::endl; </span><span style="color:#747369;">// 200(最終的なレスポンス)
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://nghttp2.org</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_follow_location</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/httpbin/redirect/3</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// 200(最終的なレスポンス)
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://nghttp2.org"</span><span style="color:#323232;">);
|
||||
@@ -250,8 +252,8 @@
|
||||
</span><span style="color:#323232;"> std::cout </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> res->status </span><span style="font-weight:bold;color:#a71d5d;"><<</span><span style="color:#323232;"> std::endl; </span><span style="font-style:italic;color:#969896;">// 200(最終的なレスポンス)
|
||||
</span><span style="color:#323232;">}
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="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
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -L</span><span style="color:#c0c5ce;"> https://nghttp2.org/httpbin/redirect/3
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -L https://nghttp2.org/httpbin/redirect/3
|
||||
@@ -267,7 +269,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -106,8 +108,8 @@
|
||||
<p>ただし、TLSサーバーにはサーバー証明書と秘密鍵が必要です。まずはそこから準備しましょう。</p>
|
||||
<h2>自己署名証明書の作成</h2>
|
||||
<p>開発やテスト用なら、自己署名証明書(いわゆるオレオレ証明書)で十分です。OpenSSLのコマンドでサクッと作れます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">openssl</span><span style="color:#c0c5ce;"> req</span><span style="color:#bf616a;"> -x509 -noenc -keyout</span><span style="color:#c0c5ce;"> key.pem</span><span style="color:#bf616a;"> -out</span><span style="color:#c0c5ce;"> cert.pem</span><span style="color:#bf616a;"> -subj</span><span style="color:#c0c5ce;"> /CN=localhost
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">openssl req -x509 -noenc -keyout key.pem -out cert.pem -subj /CN=localhost
|
||||
@@ -120,21 +122,21 @@
|
||||
</ul>
|
||||
<h2>最小のHTTPSサーバー</h2>
|
||||
<p>証明書ができたら、さっそくサーバーを書いてみましょう。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::SSLServer </span><span style="color:#8fa1b3;">svr</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">key.pem</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, HTTPS!</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on https://localhost:8443</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8443</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -157,9 +159,9 @@
|
||||
<p>コンパイルして起動しましょう。</p>
|
||||
<h2>動作確認</h2>
|
||||
<p>サーバーが起動したら、<code>curl</code> でアクセスしてみましょう。自己署名証明書なので、<code>-k</code> オプションで証明書検証をスキップします。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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!
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#8fa1b3;">curl</span><span style="color:#bf616a;"> -k</span><span style="color:#c0c5ce;"> https://localhost:8443/
|
||||
</span><span style="color:#65737e;"># Hello, HTTPS!
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">curl -k https://localhost:8443/
|
||||
@@ -171,20 +173,20 @@
|
||||
<p>前章の <code>httplib::Client</code> で接続してみましょう。自己署名証明書のサーバーに接続するには、2つの方法があります。</p>
|
||||
<h3>方法1: 証明書検証を無効にする</h3>
|
||||
<p>開発時の手軽な方法です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> cli.</span><span style="color:#8fa1b3;">enable_server_certificate_verification</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">false</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello, HTTPS!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -204,20 +206,20 @@
|
||||
</div></div>
|
||||
<h3>方法2: 自己署名証明書をCA証明書として指定する</h3>
|
||||
<p>こちらのほうが安全です。<code>cert.pem</code> をCA証明書として信頼するよう指定します。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#define </span><span style="color:#c0c5ce;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://localhost:8443</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> cli.</span><span style="color:#8fa1b3;">set_ca_cert_path</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << res-></span><span style="color:#bf616a;">body </span><span style="color:#c0c5ce;"><< std::endl; </span><span style="color:#65737e;">// Hello, HTTPS!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#define </span><span style="color:#323232;">CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -256,7 +258,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -106,23 +108,23 @@
|
||||
<p>さっそく、エコーサーバーとクライアントを作ってみましょう。</p>
|
||||
<h2>エコーサーバー</h2>
|
||||
<p>受け取ったメッセージをそのまま返すエコーサーバーです。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">WebSocket</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/ws</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">(ws.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg)) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg); </span><span style="color:#747369;">// 受け取ったメッセージをそのまま返す
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Listening on port 8080...</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg); </span><span style="color:#65737e;">// 受け取ったメッセージをそのまま返す
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Listening on port 8080...</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -147,29 +149,29 @@
|
||||
<p>ハンドラーの中では、<code>ws.read(msg)</code> でメッセージを待ちます。接続が閉じられると <code>read()</code> が <code>false</code> を返すので、ループを抜けます。<code>ws.send(msg)</code> でメッセージを送り返します。</p>
|
||||
<h2>クライアントからの接続</h2>
|
||||
<p><code>httplib::ws::WebSocketClient</code> を使ってサーバーに接続してみましょう。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;">"</span><span style="color:#99cc99;">httplib.h</span><span style="color:#d3d0c8;">"
|
||||
</span><span style="color:#cc99cc;">#include </span><span style="color:#d3d0c8;"><</span><span style="color:#99cc99;">iostream</span><span style="color:#d3d0c8;">>
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">int </span><span style="color:#6699cc;">main</span><span style="color:#d3d0c8;">() {
|
||||
</span><span style="color:#d3d0c8;"> httplib::ws::WebSocketClient </span><span style="color:#6699cc;">client</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">ws://localhost:8080/ws</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(!client.</span><span style="color:#6699cc;">connect</span><span style="color:#d3d0c8;">()) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << "</span><span style="color:#99cc99;">Connection failed</span><span style="color:#d3d0c8;">" << std::endl;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// メッセージを送信
|
||||
</span><span style="color:#d3d0c8;"> client.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">Hello, WebSocket!</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// サーバーからの応答を受信
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(client.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg)) {
|
||||
</span><span style="color:#d3d0c8;"> std::cout << msg << std::endl; </span><span style="color:#747369;">// Hello, WebSocket!
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;"> client.</span><span style="color:#6699cc;">close</span><span style="color:#d3d0c8;">();
|
||||
</span><span style="color:#d3d0c8;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;">"</span><span style="color:#a3be8c;">httplib.h</span><span style="color:#c0c5ce;">"
|
||||
</span><span style="color:#b48ead;">#include </span><span style="color:#c0c5ce;"><</span><span style="color:#a3be8c;">iostream</span><span style="color:#c0c5ce;">>
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">int </span><span style="color:#8fa1b3;">main</span><span style="color:#c0c5ce;">() {
|
||||
</span><span style="color:#c0c5ce;"> httplib::ws::WebSocketClient </span><span style="color:#8fa1b3;">client</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">ws://localhost:8080/ws</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(!client.</span><span style="color:#8fa1b3;">connect</span><span style="color:#c0c5ce;">()) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << "</span><span style="color:#a3be8c;">Connection failed</span><span style="color:#c0c5ce;">" << std::endl;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// メッセージを送信
|
||||
</span><span style="color:#c0c5ce;"> client.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, WebSocket!</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// サーバーからの応答を受信
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(client.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << msg << std::endl; </span><span style="color:#65737e;">// Hello, WebSocket!
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> client.</span><span style="color:#8fa1b3;">close</span><span style="color:#c0c5ce;">();
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-weight:bold;color:#a71d5d;">#include </span><span style="color:#183691;">"httplib.h"
|
||||
@@ -199,18 +201,18 @@
|
||||
<p>コンストラクタには <code>ws://host:port/path</code> 形式のURLを渡します。<code>connect()</code> で接続を開始し、<code>send()</code> と <code>read()</code> でメッセージをやり取りします。</p>
|
||||
<h2>テキストとバイナリ</h2>
|
||||
<p>WebSocketにはテキストとバイナリの2種類のメッセージがあります。<code>read()</code> の戻り値で区別できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">WebSocket</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/ws</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#d3d0c8;"> std::string msg;
|
||||
</span><span style="color:#d3d0c8;"> httplib::ws::ReadResult ret;
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">while </span><span style="color:#d3d0c8;">((ret = ws.</span><span style="color:#6699cc;">read</span><span style="color:#d3d0c8;">(msg))) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">if </span><span style="color:#d3d0c8;">(ret == httplib::ws::Binary) {
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg.</span><span style="color:#6699cc;">data</span><span style="color:#d3d0c8;">(), msg.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()); </span><span style="color:#747369;">// バイナリとして送信
|
||||
</span><span style="color:#d3d0c8;"> } </span><span style="color:#cc99cc;">else </span><span style="color:#d3d0c8;">{
|
||||
</span><span style="color:#d3d0c8;"> ws.</span><span style="color:#6699cc;">send</span><span style="color:#d3d0c8;">(msg); </span><span style="color:#747369;">// テキストとして送信
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;"> }
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> httplib::ws::ReadResult ret;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">((ret = ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg))) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(ret == httplib::ws::Binary) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg.</span><span style="color:#8fa1b3;">data</span><span style="color:#c0c5ce;">(), msg.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">()); </span><span style="color:#65737e;">// バイナリとして送信
|
||||
</span><span style="color:#c0c5ce;"> } </span><span style="color:#b48ead;">else </span><span style="color:#c0c5ce;">{
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg); </span><span style="color:#65737e;">// テキストとして送信
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.WebSocket(</span><span style="color:#183691;">"/ws"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;"> httplib::Request </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">, httplib::ws::WebSocket </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">ws) {
|
||||
@@ -233,19 +235,19 @@
|
||||
<p>クライアント側も同じAPIです。</p>
|
||||
<h2>リクエスト情報へのアクセス</h2>
|
||||
<p>ハンドラーの第1引数 <code>req</code> から、ハンドシェイク時のHTTPリクエスト情報を読み取れます。認証トークンの確認などに便利です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &req, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> token = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Authorization</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(token.</span><span style="color:#8fa1b3;">empty</span><span style="color:#c0c5ce;">()) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">close</span><span style="color:#c0c5ce;">(httplib::ws::CloseStatus::PolicyViolation, "</span><span style="color:#a3be8c;">unauthorized</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg);
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.WebSocket(</span><span style="color:#183691;">"/ws"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;"> httplib::Request </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">req, httplib::ws::WebSocket </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">ws) {
|
||||
@@ -264,17 +266,17 @@
|
||||
</div></div>
|
||||
<h2>WSSで使う</h2>
|
||||
<p>HTTPS上のWebSocket(WSS)にも対応しています。サーバー側は <code>httplib::SSLServer</code> にWebSocketハンドラーを登録するだけです。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::SSLServer </span><span style="color:#8fa1b3;">svr</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">cert.pem</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">key.pem</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">WebSocket</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/ws</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::Request &, httplib::ws::WebSocket &ws) {
|
||||
</span><span style="color:#c0c5ce;"> std::string msg;
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(ws.</span><span style="color:#8fa1b3;">read</span><span style="color:#c0c5ce;">(msg)) {
|
||||
</span><span style="color:#c0c5ce;"> ws.</span><span style="color:#8fa1b3;">send</span><span style="color:#c0c5ce;">(msg);
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8443</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::SSLServer </span><span style="font-weight:bold;color:#795da3;">svr</span><span style="color:#323232;">(</span><span style="color:#183691;">"cert.pem"</span><span style="color:#323232;">, </span><span style="color:#183691;">"key.pem"</span><span style="color:#323232;">);
|
||||
@@ -290,8 +292,8 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>クライアント側は <code>wss://</code> スキームを使います。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::ws::WebSocketClient </span><span style="color:#8fa1b3;">client</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">wss://localhost:8443/ws</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::ws::WebSocketClient </span><span style="font-weight:bold;color:#795da3;">client</span><span style="color:#323232;">(</span><span style="color:#183691;">"wss://localhost:8443/ws"</span><span style="color:#323232;">);
|
||||
@@ -308,7 +310,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -105,16 +107,16 @@
|
||||
<p>Tourお疲れさまでした! cpp-httplibの基本はひと通り押さえましたね。でも、まだまだ便利な機能があります。Tourで取り上げなかった機能をカテゴリー別に紹介します。</p>
|
||||
<h2>Streaming API</h2>
|
||||
<p>LLMのストリーミング応答や大きなファイルのダウンロードでは、レスポンス全体をメモリに載せたくないですよね。<code>stream::Get()</code> を使えば、データをチャンクごとに処理できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">}
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:11434</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> result = </span><span style="color:#8fa1b3;">httplib::stream::Get</span><span style="color:#c0c5ce;">(cli, "</span><span style="color:#a3be8c;">/api/generate</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">if </span><span style="color:#c0c5ce;">(result) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">while </span><span style="color:#c0c5ce;">(result.</span><span style="color:#8fa1b3;">next</span><span style="color:#c0c5ce;">()) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout.</span><span style="color:#8fa1b3;">write</span><span style="color:#c0c5ce;">(result.</span><span style="color:#8fa1b3;">data</span><span style="color:#c0c5ce;">(), result.</span><span style="color:#8fa1b3;">size</span><span style="color:#c0c5ce;">());
|
||||
</span><span style="color:#c0c5ce;"> }
|
||||
</span><span style="color:#c0c5ce;">}
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:11434"</span><span style="color:#323232;">);
|
||||
@@ -129,13 +131,13 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p><code>Get()</code> に <code>content_receiver</code> コールバックを渡す方法もあります。こちらはKeep-Aliveと併用できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/stream</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const char </span><span style="color:#c0c5ce;">*data, size_t len) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout.</span><span style="color:#8fa1b3;">write</span><span style="color:#c0c5ce;">(data, len);
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -147,25 +149,25 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>サーバー側には <code>set_content_provider()</code> と <code>set_chunked_content_provider()</code> があります。サイズがわかっているなら前者、不明なら後者を使ってください。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// サイズ指定あり(Content-Length が設定される)
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/file</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> size = </span><span style="color:#6699cc;">get_file_size</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">large.bin</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content_provider</span><span style="color:#d3d0c8;">(size, "</span><span style="color:#99cc99;">application/octet-stream</span><span style="color:#d3d0c8;">",
|
||||
</span><span style="color:#d3d0c8;"> [](size_t offset, size_t length, httplib::DataSink &sink) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// offset から length バイト分を送る
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">;
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#747369;">// サイズ不明(Chunked Transfer Encoding)
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/stream</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_chunked_content_provider</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">",
|
||||
</span><span style="color:#d3d0c8;"> [](size_t offset, httplib::DataSink &sink) {
|
||||
</span><span style="color:#d3d0c8;"> sink.</span><span style="color:#6699cc;">write</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">chunk</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">6</span><span style="color:#d3d0c8;">);
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return </span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">; </span><span style="color:#747369;">// falseを返すと終了
|
||||
</span><span style="color:#d3d0c8;"> });
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// サイズ指定あり(Content-Length が設定される)
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/file</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> size = </span><span style="color:#8fa1b3;">get_file_size</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">large.bin</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content_provider</span><span style="color:#c0c5ce;">(size, "</span><span style="color:#a3be8c;">application/octet-stream</span><span style="color:#c0c5ce;">",
|
||||
</span><span style="color:#c0c5ce;"> [](size_t offset, size_t length, httplib::DataSink &sink) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// offset から length バイト分を送る
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#65737e;">// サイズ不明(Chunked Transfer Encoding)
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/stream</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_chunked_content_provider</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">",
|
||||
</span><span style="color:#c0c5ce;"> [](size_t offset, httplib::DataSink &sink) {
|
||||
</span><span style="color:#c0c5ce;"> sink.</span><span style="color:#8fa1b3;">write</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">chunk</span><span style="color:#96b5b4;">\n</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">6</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">; </span><span style="color:#65737e;">// falseを返すと終了
|
||||
</span><span style="color:#c0c5ce;"> });
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// サイズ指定あり(Content-Length が設定される)
|
||||
@@ -189,12 +191,12 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>大きなファイルのアップロードには <code>make_file_provider()</code> が便利です。ファイルを全部メモリに読み込まず、ストリーミングで送れます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Post</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/upload</span><span style="color:#c0c5ce;">", {}, {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#8fa1b3;">httplib::make_file_provider</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">file</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">/path/to/large-file.zip</span><span style="color:#c0c5ce;">")
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -206,15 +208,15 @@
|
||||
</div></div>
|
||||
<h2>Server-Sent Events (SSE)</h2>
|
||||
<p>SSEクライアントも用意しています。自動再接続や <code>Last-Event-ID</code> による再開にも対応しています。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">// ブロッキング、自動再接続あり
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost:8080</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">httplib::sse::SSEClient </span><span style="color:#8fa1b3;">sse</span><span style="color:#c0c5ce;">(</span><span style="color:#bf616a;">cli</span><span style="color:#c0c5ce;">, "</span><span style="color:#a3be8c;">/events</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">sse.</span><span style="color:#8fa1b3;">on_message</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << msg.</span><span style="color:#bf616a;">event </span><span style="color:#c0c5ce;"><< "</span><span style="color:#a3be8c;">: </span><span style="color:#c0c5ce;">" << msg.</span><span style="color:#bf616a;">data </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">sse.</span><span style="color:#8fa1b3;">start</span><span style="color:#c0c5ce;">(); </span><span style="color:#65737e;">// ブロッキング、自動再接続あり
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"http://localhost:8080"</span><span style="color:#323232;">);
|
||||
@@ -228,10 +230,10 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>イベントタイプごとにハンドラーを分けることもできますよ。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">sse.</span><span style="color:#6699cc;">on_event</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">update</span><span style="color:#d3d0c8;">", [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// "update" イベントだけ処理
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">sse.</span><span style="color:#8fa1b3;">on_event</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">update</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const</span><span style="color:#c0c5ce;"> httplib::sse::SSEMessage &msg) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// "update" イベントだけ処理
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">sse.on_event(</span><span style="color:#183691;">"update"</span><span style="color:#323232;">, [](</span><span style="font-weight:bold;color:#a71d5d;">const</span><span style="color:#323232;"> httplib::sse::SSEMessage </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">msg) {
|
||||
@@ -241,10 +243,10 @@
|
||||
</div></div>
|
||||
<h2>認証</h2>
|
||||
<p>クライアントにはBasic認証、Bearer Token認証、Digest認証のヘルパーを用意しています。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://api.example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_basic_auth</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">user</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">password</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_bearer_token_auth</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">my-token</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://api.example.com"</span><span style="color:#323232;">);
|
||||
@@ -259,10 +261,10 @@
|
||||
<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-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_compress</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// リクエストボディを圧縮
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_decompress</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">true</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// レスポンスボディを展開
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_compress</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// リクエストボディを圧縮
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_decompress</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// レスポンスボディを展開
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -272,10 +274,10 @@
|
||||
</div></div>
|
||||
<h2>プロキシ</h2>
|
||||
<p>HTTPプロキシ経由で接続できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">");
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_proxy</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">proxy.example.com</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">8080</span><span style="color:#c0c5ce;">);
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_proxy_basic_auth</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">user</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">password</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -285,11 +287,11 @@
|
||||
</div></div>
|
||||
<h2>タイムアウト</h2>
|
||||
<p>接続・読み取り・書き込みのタイムアウトを個別に設定できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">https://example.com</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_connection_timeout</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">5</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// 5秒
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_read_timeout</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">10</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// 10秒
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_write_timeout</span><span style="color:#d3d0c8;">(</span><span style="color:#f99157;">10</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">); </span><span style="color:#747369;">// 10秒
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_connection_timeout</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">5</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// 5秒
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_read_timeout</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">10</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// 10秒
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_write_timeout</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">10</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">); </span><span style="color:#65737e;">// 10秒
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -300,9 +302,9 @@
|
||||
</div></div>
|
||||
<h2>Keep-Alive</h2>
|
||||
<p>同じサーバーに何度もリクエストするなら、Keep-Aliveを有効にしましょう。TCP接続を再利用するので効率的です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">https://example.com</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_keep_alive</span><span style="color:#c0c5ce;">(</span><span style="color:#d08770;">true</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">httplib::Client </span><span style="font-weight:bold;color:#795da3;">cli</span><span style="color:#323232;">(</span><span style="color:#183691;">"https://example.com"</span><span style="color:#323232;">);
|
||||
@@ -311,16 +313,16 @@
|
||||
</div></div>
|
||||
<h2>サーバーのミドルウェア</h2>
|
||||
<p>リクエスト処理の前後にフックを挟めます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_pre_routing_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// すべてのリクエストの前に実行される
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">return</span><span style="color:#d3d0c8;"> httplib::Server::HandlerResponse::Unhandled; </span><span style="color:#747369;">// 通常のルーティングに進む
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_post_routing_handler</span><span style="color:#d3d0c8;">([](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&res) {
|
||||
</span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// レスポンスが返された後に実行される
|
||||
</span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_header</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">X-Server</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">cpp-httplib</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_pre_routing_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// すべてのリクエストの前に実行される
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return</span><span style="color:#c0c5ce;"> httplib::Server::HandlerResponse::Unhandled; </span><span style="color:#65737e;">// 通常のルーティングに進む
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_post_routing_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#65737e;">// レスポンスが返された後に実行される
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">X-Server</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">cpp-httplib</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_pre_routing_handler([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -335,16 +337,16 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p><code>req.user_data</code> を使うと、ミドルウェアからハンドラーにデータを渡せます。認証トークンのデコード結果を共有するときに便利です。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_pre_routing_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> req.</span><span style="color:#bf616a;">user_data</span><span style="color:#c0c5ce;">["</span><span style="color:#a3be8c;">auth_user</span><span style="color:#c0c5ce;">"] = </span><span style="color:#8fa1b3;">std::string</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">alice</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">return</span><span style="color:#c0c5ce;"> httplib::Server::HandlerResponse::Unhandled;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/me</span><span style="color:#c0c5ce;">", [](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> </span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> user = std::</span><span style="color:#8fa1b3;">any_cast</span><span style="color:#c0c5ce;"><std::string>(req.</span><span style="color:#bf616a;">user_data</span><span style="color:#c0c5ce;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">auth_user</span><span style="color:#c0c5ce;">"));
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Hello, </span><span style="color:#c0c5ce;">" + user, "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_pre_routing_handler([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -359,15 +361,15 @@
|
||||
</span></pre>
|
||||
</div></div>
|
||||
<p>エラーや例外のハンドラーもカスタマイズできますよ。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_error_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Custom Error Page</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/html</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_exception_handler</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">auto </span><span style="color:#c0c5ce;">&res, std::exception_ptr ep) {
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;">= </span><span style="color:#d08770;">500</span><span style="color:#c0c5ce;">;
|
||||
</span><span style="color:#c0c5ce;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">Internal Server Error</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">text/plain</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_error_handler([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">auto &</span><span style="color:#323232;">res) {
|
||||
@@ -382,10 +384,10 @@
|
||||
</div></div>
|
||||
<h2>ロギング</h2>
|
||||
<p>サーバーでもクライアントでもロガーを設定できます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="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;">});
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_logger</span><span style="color:#c0c5ce;">([](</span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&req, </span><span style="color:#b48ead;">const auto </span><span style="color:#c0c5ce;">&res) {
|
||||
</span><span style="color:#c0c5ce;"> std::cout << req.</span><span style="color:#bf616a;">method </span><span style="color:#c0c5ce;"><< " " << req.</span><span style="color:#bf616a;">path </span><span style="color:#c0c5ce;"><< " " << res.</span><span style="color:#bf616a;">status </span><span style="color:#c0c5ce;"><< std::endl;
|
||||
</span><span style="color:#c0c5ce;">});
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="color:#323232;">svr.set_logger([](</span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">req, </span><span style="font-weight:bold;color:#a71d5d;">const auto &</span><span style="color:#323232;">res) {
|
||||
@@ -395,11 +397,11 @@
|
||||
</div></div>
|
||||
<h2>Unix Domain Socket</h2>
|
||||
<p>TCP以外に、Unix Domain Socketでの通信にも対応しています。同じマシン上のプロセス間通信に使えます。</p>
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// サーバー
|
||||
</span><span style="color:#d3d0c8;">httplib::Server svr;
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">set_address_family</span><span style="color:#d3d0c8;">(AF_UNIX);
|
||||
</span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/tmp/httplib.sock</span><span style="color:#d3d0c8;">", </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">);
|
||||
<div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// サーバー
|
||||
</span><span style="color:#c0c5ce;">httplib::Server svr;
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">set_address_family</span><span style="color:#c0c5ce;">(AF_UNIX);
|
||||
</span><span style="color:#c0c5ce;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/tmp/httplib.sock</span><span style="color:#c0c5ce;">", </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">);
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// サーバー
|
||||
@@ -407,13 +409,13 @@
|
||||
</span><span style="color:#323232;">svr.set_address_family(AF_UNIX);
|
||||
</span><span style="color:#323232;">svr.listen(</span><span style="color:#183691;">"/tmp/httplib.sock"</span><span style="color:#323232;">, </span><span style="color:#0086b3;">0</span><span style="color:#323232;">);
|
||||
</span></pre>
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2d2d2d;">
|
||||
<span style="color:#747369;">// クライアント
|
||||
</span><span style="color:#d3d0c8;">httplib::Client </span><span style="color:#6699cc;">cli</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">http://localhost</span><span style="color:#d3d0c8;">");
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_address_family</span><span style="color:#d3d0c8;">(AF_UNIX);
|
||||
</span><span style="color:#d3d0c8;">cli.</span><span style="color:#6699cc;">set_hostname_addr_map</span><span style="color:#d3d0c8;">({{"</span><span style="color:#99cc99;">localhost</span><span style="color:#d3d0c8;">", "</span><span style="color:#99cc99;">/tmp/httplib.sock</span><span style="color:#d3d0c8;">"}});
|
||||
</span><span style="color:#d3d0c8;">
|
||||
</span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> res = cli.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">("</span><span style="color:#99cc99;">/</span><span style="color:#d3d0c8;">");
|
||||
</div></div><div class="code-block-wrapper"><div data-code-theme="dark"><pre style="background-color:#2b303b;">
|
||||
<span style="color:#65737e;">// クライアント
|
||||
</span><span style="color:#c0c5ce;">httplib::Client </span><span style="color:#8fa1b3;">cli</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">http://localhost</span><span style="color:#c0c5ce;">");
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_address_family</span><span style="color:#c0c5ce;">(AF_UNIX);
|
||||
</span><span style="color:#c0c5ce;">cli.</span><span style="color:#8fa1b3;">set_hostname_addr_map</span><span style="color:#c0c5ce;">({{"</span><span style="color:#a3be8c;">localhost</span><span style="color:#c0c5ce;">", "</span><span style="color:#a3be8c;">/tmp/httplib.sock</span><span style="color:#c0c5ce;">"}});
|
||||
</span><span style="color:#c0c5ce;">
|
||||
</span><span style="color:#b48ead;">auto</span><span style="color:#c0c5ce;"> res = cli.</span><span style="color:#8fa1b3;">Get</span><span style="color:#c0c5ce;">("</span><span style="color:#a3be8c;">/</span><span style="color:#c0c5ce;">");
|
||||
</span></pre>
|
||||
</div><div data-code-theme="light"><pre style="background-color:#ffffff;">
|
||||
<span style="font-style:italic;color:#969896;">// クライアント
|
||||
@@ -440,7 +442,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner">
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<a href="/cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.36.0</span></a>
|
||||
<div class="header-spacer"></div>
|
||||
<nav class="header-nav">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<a href="/cpp-httplib/ja/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Home
|
||||
</a>
|
||||
|
||||
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<a href="/cpp-httplib/ja/tour/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>
|
||||
Tour
|
||||
</a>
|
||||
@@ -45,6 +45,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
</button>
|
||||
<button class="theme-toggle" aria-label="Toggle theme"></button>
|
||||
|
||||
<div class="lang-selector">
|
||||
<button class="lang-btn" aria-label="Language">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="sidebar-toggle" aria-label="Menu">☰</button>
|
||||
</div>
|
||||
@@ -121,7 +123,7 @@
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
© 2026 yhirose. All rights reserved.
|
||||
© 2026 Yuji Hirose. All rights reserved.
|
||||
</footer>
|
||||
|
||||
<!-- Search modal -->
|
||||
|
||||
Reference in New Issue
Block a user