Showing preview only (5,401K chars total). Download the full file or copy to clipboard to get everything.
Repository: yhirose/cpp-httplib
Branch: master
Commit: 45820de3327c
Files: 178
Total size: 5.1 MB
Directory structure:
gitextract_7tv2227u/
├── .gitattributes
├── .github/
│ └── workflows/
│ ├── abidiff.yaml
│ ├── cifuzz.yaml
│ ├── docs.yml
│ ├── release-docker.yml
│ ├── test-32bit.yml
│ ├── test.yaml
│ ├── test_benchmark.yaml
│ ├── test_no_exceptions.yaml
│ ├── test_offline.yaml
│ └── test_proxy.yaml
├── CMakeLists.txt
├── Dockerfile
├── LICENSE
├── README-sse.md
├── README-stream.md
├── README-websocket.md
├── README.md
├── benchmark/
│ ├── Makefile
│ ├── cpp-httplib/
│ │ └── main.cpp
│ └── crow/
│ ├── crow_all.h
│ └── main.cpp
├── cmake/
│ ├── FindBrotli.cmake
│ ├── httplibConfig.cmake.in
│ └── modules.cmake
├── docker/
│ ├── html/
│ │ └── index.html
│ └── main.cc
├── docker-compose.yml
├── docs-src/
│ ├── config.toml
│ └── pages/
│ ├── en/
│ │ ├── cookbook/
│ │ │ └── index.md
│ │ ├── index.md
│ │ ├── llm-app/
│ │ │ └── index.md
│ │ └── tour/
│ │ ├── 01-getting-started.md
│ │ ├── 02-basic-client.md
│ │ ├── 03-basic-server.md
│ │ ├── 04-static-file-server.md
│ │ ├── 05-tls-setup.md
│ │ ├── 06-https-client.md
│ │ ├── 07-https-server.md
│ │ ├── 08-websocket.md
│ │ ├── 09-whats-next.md
│ │ └── index.md
│ └── ja/
│ ├── cookbook/
│ │ └── index.md
│ ├── index.md
│ ├── llm-app/
│ │ └── index.md
│ └── tour/
│ ├── 01-getting-started.md
│ ├── 02-basic-client.md
│ ├── 03-basic-server.md
│ ├── 04-static-file-server.md
│ ├── 05-tls-setup.md
│ ├── 06-https-client.md
│ ├── 07-https-server.md
│ ├── 08-websocket.md
│ ├── 09-whats-next.md
│ └── index.md
├── example/
│ ├── Dockerfile.hello
│ ├── Makefile
│ ├── accept_header.cc
│ ├── benchmark.cc
│ ├── ca-bundle.crt
│ ├── client.cc
│ ├── client.vcxproj
│ ├── example.sln
│ ├── hello.cc
│ ├── one_time_request.cc
│ ├── redirect.cc
│ ├── server.cc
│ ├── server.vcxproj
│ ├── server_and_client.cc
│ ├── simplecli.cc
│ ├── simplesvr.cc
│ ├── ssecli-stream.cc
│ ├── ssecli.cc
│ ├── ssesvr.cc
│ ├── upload.cc
│ ├── uploader.sh
│ └── wsecho.cc
├── generate_module.py
├── httplib.h
├── justfile
├── meson.build
├── meson_options.txt
├── split.py
└── test/
├── CMakeLists.txt
├── Makefile
├── ca-bundle.crt
├── fuzzing/
│ ├── CMakeLists.txt
│ ├── Makefile
│ ├── corpus/
│ │ ├── 1
│ │ ├── 2
│ │ ├── 3
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5372331946541056
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5386708825800704
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5667822731132928
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5886572146327552
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5942767436562432
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-6007379124158464
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-6508706672541696
│ │ └── issue1264
│ ├── server_fuzzer.cc
│ ├── server_fuzzer.dict
│ └── standalone_fuzz_target_runner.cpp
├── gen-certs.sh
├── gtest/
│ ├── include/
│ │ └── gtest/
│ │ ├── gtest-assertion-result.h
│ │ ├── gtest-death-test.h
│ │ ├── gtest-matchers.h
│ │ ├── gtest-message.h
│ │ ├── gtest-param-test.h
│ │ ├── gtest-printers.h
│ │ ├── gtest-spi.h
│ │ ├── gtest-test-part.h
│ │ ├── gtest-typed-test.h
│ │ ├── gtest.h
│ │ ├── gtest_pred_impl.h
│ │ ├── gtest_prod.h
│ │ └── internal/
│ │ ├── custom/
│ │ │ ├── README.md
│ │ │ ├── gtest-port.h
│ │ │ ├── gtest-printers.h
│ │ │ └── gtest.h
│ │ ├── gtest-death-test-internal.h
│ │ ├── gtest-filepath.h
│ │ ├── gtest-internal.h
│ │ ├── gtest-param-util.h
│ │ ├── gtest-port-arch.h
│ │ ├── gtest-port.h
│ │ ├── gtest-string.h
│ │ └── gtest-type-util.h
│ └── src/
│ ├── gtest-all.cc
│ ├── gtest-assertion-result.cc
│ ├── gtest-death-test.cc
│ ├── gtest-filepath.cc
│ ├── gtest-internal-inl.h
│ ├── gtest-matchers.cc
│ ├── gtest-port.cc
│ ├── gtest-printers.cc
│ ├── gtest-test-part.cc
│ ├── gtest-typed-test.cc
│ ├── gtest.cc
│ └── gtest_main.cc
├── include_httplib.cc
├── include_windows_h.cc
├── lsan_suppressions.txt
├── make-shared-library.sh
├── meson.build
├── proxy/
│ ├── Dockerfile
│ ├── basic_passwd
│ ├── basic_squid.conf
│ ├── digest_passwd
│ ├── digest_squid.conf
│ ├── docker-compose.ci.yml
│ └── docker-compose.yml
├── test.cc
├── test.conf
├── test.rootCA.conf
├── test.sln
├── test.vcxproj
├── test_32bit_build.cpp
├── test_benchmark.cc
├── test_proxy.cc
├── test_thread_pool.cc
├── test_websocket_heartbeat.cc
├── www/
│ ├── dir/
│ │ ├── 1MB.txt
│ │ ├── index.html
│ │ ├── meson.build
│ │ ├── test.abcde
│ │ └── test.html
│ ├── empty_file
│ ├── file
│ ├── meson.build
│ └── 日本語Dir/
│ ├── meson.build
│ └── 日本語File.txt
├── www2/
│ └── dir/
│ ├── index.html
│ ├── meson.build
│ └── test.html
└── www3/
└── dir/
├── index.html
├── meson.build
└── test.html
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
/test/www*/dir/*.html text eol=lf
/test/www*/dir/*.txt text eol=lf
================================================
FILE: .github/workflows/abidiff.yaml
================================================
# SPDX-FileCopyrightText: 2025 Andrea Pappacoda <andrea@pappacoda.it>
# SPDX-License-Identifier: MIT
name: abidiff
on: [push, pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
defaults:
run:
shell: sh
jobs:
abi:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
container:
image: debian:testing
steps:
- name: Install dependencies
run: apt -y --update install --no-install-recommends
abigail-tools
ca-certificates
g++
git
libbrotli-dev
libssl-dev
libzstd-dev
meson
pkg-config
python3
zlib1g-dev
- uses: actions/checkout@v4
with:
path: current
- uses: actions/checkout@v4
with:
path: previous
fetch-depth: 0
- name: Checkout previous
working-directory: previous
run: |
git switch master
git describe --tags --abbrev=0 master | xargs git checkout
- name: Build current
working-directory: current
run: |
meson setup --buildtype=debug -Dcpp-httplib_compile=true build
ninja -C build
- name: Build previous
working-directory: previous
run: |
meson setup --buildtype=debug -Dcpp-httplib_compile=true build
ninja -C build
- name: Run abidiff
run: abidiff
--headers-dir1 previous/build
--headers-dir2 current/build
previous/build/libcpp-httplib.so
current/build/libcpp-httplib.so
================================================
FILE: .github/workflows/cifuzz.yaml
================================================
name: CIFuzz
on: [pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'cpp-httplib'
dry-run: false
language: c++
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'cpp-httplib'
fuzz-seconds: 600
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
================================================
FILE: .github/workflows/docs.yml
================================================
name: docs
on:
push:
branches: [master]
paths:
- 'docs-src/**'
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install docs-gen
run: cargo install docs-gen
- name: Build
run: docs-gen build docs-src docs
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: docs
- id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .github/workflows/release-docker.yml
================================================
name: Release Docker Image
on:
release:
types: [published]
workflow_dispatch:
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history and tags
- name: Extract tag (manual)
if: github.event_name == 'workflow_dispatch'
id: set_tag_manual
run: |
# Checkout the latest tag and set output
git fetch --tags
LATEST_TAG=$(git describe --tags --abbrev=0)
git checkout $LATEST_TAG
echo "tag=${LATEST_TAG#v}" >> $GITHUB_OUTPUT
- name: Extract tag (release)
if: github.event_name == 'release'
id: set_tag_release
run: echo "tag=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64,linux/arm64 # Build for both amd64 and arm64
# Use extracted tag without leading 'v'
tags: |
yhirose4dockerhub/cpp-httplib-server:latest
yhirose4dockerhub/cpp-httplib-server:${{ steps.set_tag_manual.outputs.tag || steps.set_tag_release.outputs.tag }}
================================================
FILE: .github/workflows/test-32bit.yml
================================================
name: 32-bit Build Test
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
jobs:
test-win32:
name: Windows 32-bit (MSVC x86)
runs-on: windows-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Build (Win32)
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86
cl /std:c++14 /EHsc /W4 /WX /c /Fo:NUL test\test_32bit_build.cpp
test-arm32:
name: ARM 32-bit (cross-compile)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Install cross compiler
run: sudo apt-get update && sudo apt-get install -y g++-arm-linux-gnueabihf
- name: Build (ARM 32-bit)
run: arm-linux-gnueabihf-g++ -std=c++11 -Wall -Wextra -Wno-psabi -Werror -c -o /dev/null test/test_32bit_build.cpp
================================================
FILE: .github/workflows/test.yaml
================================================
name: test
on:
push:
pull_request:
workflow_dispatch:
inputs:
gtest_filter:
description: 'Google Test filter'
test_linux:
description: 'Test on Linux'
type: boolean
default: true
test_macos:
description: 'Test on MacOS'
type: boolean
default: true
test_windows:
description: 'Test on Windows'
type: boolean
default: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
env:
GTEST_FILTER: ${{ github.event.inputs.gtest_filter || '*' }}
jobs:
style-check:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
continue-on-error: true
steps:
- name: checkout
uses: actions/checkout@v4
- name: run style check
run: |
clang-format --version
cd test && make style_check
build-and-test-on-32bit:
runs-on: ubuntu-latest
if: >
(github.event_name == 'push') ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.test_linux == 'true')
strategy:
matrix:
config:
- arch_flags: -m32
arch_suffix: :i386
name: (32-bit)
steps:
- name: checkout
uses: actions/checkout@v4
- name: install libraries
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y libc6-dev${{ matrix.config.arch_suffix }} libstdc++-13-dev${{ matrix.config.arch_suffix }} \
libssl-dev${{ matrix.config.arch_suffix }} libcurl4-openssl-dev${{ matrix.config.arch_suffix }} \
zlib1g-dev${{ matrix.config.arch_suffix }} libbrotli-dev${{ matrix.config.arch_suffix }} \
libzstd-dev${{ matrix.config.arch_suffix }}
- name: build and run tests
run: cd test && make test EXTRA_CXXFLAGS="${{ matrix.config.arch_flags }}"
ubuntu:
runs-on: ubuntu-latest
if: >
(github.event_name == 'push') ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.test_linux == 'true')
strategy:
matrix:
tls_backend: [openssl, mbedtls, wolfssl]
name: ubuntu (${{ matrix.tls_backend }})
steps:
- name: checkout
uses: actions/checkout@v4
- name: install common libraries
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev zlib1g-dev libbrotli-dev libzstd-dev
- name: install OpenSSL
if: matrix.tls_backend == 'openssl'
run: sudo apt-get install -y libssl-dev
- name: install Mbed TLS
if: matrix.tls_backend == 'mbedtls'
run: sudo apt-get install -y libmbedtls-dev
- name: install wolfSSL
if: matrix.tls_backend == 'wolfssl'
run: sudo apt-get install -y libwolfssl-dev
- name: build and run tests (OpenSSL)
if: matrix.tls_backend == 'openssl'
run: cd test && make test_split && make test_openssl_parallel
env:
LSAN_OPTIONS: suppressions=lsan_suppressions.txt
- name: build and run tests (Mbed TLS)
if: matrix.tls_backend == 'mbedtls'
run: cd test && make test_split_mbedtls && make test_mbedtls_parallel
- name: build and run tests (wolfSSL)
if: matrix.tls_backend == 'wolfssl'
run: cd test && make test_split_wolfssl && make test_wolfssl_parallel
- name: run fuzz test target
if: matrix.tls_backend == 'openssl'
run: cd test && make fuzz_test
- name: build and run WebSocket heartbeat test
if: matrix.tls_backend == 'openssl'
run: cd test && make test_websocket_heartbeat && ./test_websocket_heartbeat
- name: build and run ThreadPool test
run: cd test && make test_thread_pool && ./test_thread_pool
macos:
runs-on: macos-latest
if: >
(github.event_name == 'push') ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.test_macos == 'true')
strategy:
matrix:
tls_backend: [openssl, mbedtls, wolfssl]
name: macos (${{ matrix.tls_backend }})
steps:
- name: checkout
uses: actions/checkout@v4
- name: install Mbed TLS
if: matrix.tls_backend == 'mbedtls'
run: brew install mbedtls@3
- name: install wolfSSL
if: matrix.tls_backend == 'wolfssl'
run: brew install wolfssl
- name: build and run tests (OpenSSL)
if: matrix.tls_backend == 'openssl'
run: cd test && make test_split && make test_openssl_parallel
env:
LSAN_OPTIONS: suppressions=lsan_suppressions.txt
- name: build and run tests (Mbed TLS)
if: matrix.tls_backend == 'mbedtls'
run: cd test && make test_split_mbedtls && make test_mbedtls_parallel
- name: build and run tests (wolfSSL)
if: matrix.tls_backend == 'wolfssl'
run: cd test && make test_split_wolfssl && make test_wolfssl_parallel
- name: run fuzz test target
if: matrix.tls_backend == 'openssl'
run: cd test && make fuzz_test
- name: build and run WebSocket heartbeat test
if: matrix.tls_backend == 'openssl'
run: cd test && make test_websocket_heartbeat && ./test_websocket_heartbeat
- name: build and run ThreadPool test
run: cd test && make test_thread_pool && ./test_thread_pool
windows:
runs-on: windows-latest
if: >
(github.event_name == 'push') ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.test_windows == 'true')
strategy:
matrix:
config:
- with_ssl: false
compiled: false
run_tests: true
name: without SSL
- with_ssl: true
compiled: false
run_tests: true
name: with SSL
- with_ssl: false
compiled: true
run_tests: false
name: compiled
name: windows ${{ matrix.config.name }}
steps:
- name: Prepare Git for Checkout on Windows
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout
uses: actions/checkout@v4
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Setup msbuild on windows
uses: microsoft/setup-msbuild@v2
- name: Cache vcpkg packages
id: vcpkg-cache
uses: actions/cache@v4
with:
path: C:/vcpkg/installed
key: vcpkg-installed-windows-gtest-curl-zlib-brotli-zstd
- name: Install vcpkg dependencies
if: steps.vcpkg-cache.outputs.cache-hit != 'true'
run: vcpkg install gtest curl zlib brotli zstd
- name: Install OpenSSL
if: ${{ matrix.config.with_ssl }}
run: choco install openssl
- name: Configure CMake ${{ matrix.config.name }}
run: >
cmake -B build -S .
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
-DHTTPLIB_TEST=ON
-DHTTPLIB_COMPILE=${{ matrix.config.compiled && 'ON' || 'OFF' }}
-DHTTPLIB_USE_OPENSSL_IF_AVAILABLE=${{ matrix.config.with_ssl && 'ON' || 'OFF' }}
-DHTTPLIB_REQUIRE_ZLIB=ON
-DHTTPLIB_REQUIRE_BROTLI=ON
-DHTTPLIB_REQUIRE_ZSTD=ON
-DHTTPLIB_REQUIRE_OPENSSL=${{ matrix.config.with_ssl && 'ON' || 'OFF' }}
- name: Build ${{ matrix.config.name }}
run: cmake --build build --config Release -- /v:m /clp:ShowCommandLine
- name: Run tests ${{ matrix.config.name }}
if: ${{ matrix.config.run_tests }}
shell: pwsh
working-directory: build/test
run: |
$shards = 4
$procs = @()
for ($i = 0; $i -lt $shards; $i++) {
$log = "shard_${i}.log"
$procs += Start-Process -FilePath ./Release/httplib-test.exe `
-ArgumentList "--gtest_color=yes","--gtest_filter=${{ github.event.inputs.gtest_filter || '*' }}" `
-NoNewWindow -PassThru -RedirectStandardOutput $log -RedirectStandardError "${log}.err" `
-Environment @{ GTEST_TOTAL_SHARDS="$shards"; GTEST_SHARD_INDEX="$i" }
}
$procs | Wait-Process
$failed = $false
for ($i = 0; $i -lt $shards; $i++) {
$log = "shard_${i}.log"
if (Select-String -Path $log -Pattern "\[ PASSED \]" -Quiet) {
$passed = (Select-String -Path $log -Pattern "\[ PASSED \]").Line
Write-Host "Shard ${i}: $passed"
} else {
Write-Host "=== Shard $i FAILED ==="
Get-Content $log
if (Test-Path "${log}.err") { Get-Content "${log}.err" }
$failed = $true
}
}
if ($failed) { exit 1 }
Write-Host "All shards passed."
env:
VCPKG_ROOT: "C:/vcpkg"
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
================================================
FILE: .github/workflows/test_benchmark.yaml
================================================
name: benchmark
on:
push:
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
jobs:
ubuntu:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: checkout
uses: actions/checkout@v4
- name: build and run
run: cd test && make test_benchmark && ./test_benchmark
macos:
runs-on: macos-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: checkout
uses: actions/checkout@v4
- name: build and run
run: cd test && make test_benchmark && ./test_benchmark
windows:
runs-on: windows-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: Prepare Git for Checkout on Windows
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: checkout
uses: actions/checkout@v4
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Cache vcpkg packages
id: vcpkg-cache
uses: actions/cache@v4
with:
path: C:/vcpkg/installed
key: vcpkg-installed-windows-gtest
- name: Install vcpkg dependencies
if: steps.vcpkg-cache.outputs.cache-hit != 'true'
run: vcpkg install gtest
- name: Configure and build
shell: pwsh
run: |
$cmake_content = @"
cmake_minimum_required(VERSION 3.14)
project(httplib-benchmark CXX)
find_package(GTest REQUIRED)
add_executable(httplib-benchmark test/test_benchmark.cc)
target_include_directories(httplib-benchmark PRIVATE .)
target_link_libraries(httplib-benchmark PRIVATE GTest::gtest_main)
target_compile_options(httplib-benchmark PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
"@
New-Item -ItemType Directory -Force -Path build_bench/test | Out-Null
Set-Content -Path build_bench/CMakeLists.txt -Value $cmake_content
Copy-Item -Path httplib.h -Destination build_bench/
Copy-Item -Path test/test_benchmark.cc -Destination build_bench/test/
cmake -B build_bench/build -S build_bench `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"
cmake --build build_bench/build --config Release
- name: Run with retry
run: ctest --output-on-failure --test-dir build_bench/build -C Release --repeat until-pass:5
env:
VCPKG_ROOT: "C:/vcpkg"
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
================================================
FILE: .github/workflows/test_no_exceptions.yaml
================================================
name: No Exceptions Test
on: [push, pull_request]
jobs:
test-no-exceptions:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libssl-dev zlib1g-dev libcurl4-openssl-dev libbrotli-dev libzstd-dev
- name: Run tests with CPPHTTPLIB_NO_EXCEPTIONS
run: |
cd test && make test_split EXTRA_CXXFLAGS="-fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS" && make test_openssl_parallel EXTRA_CXXFLAGS="-fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS"
================================================
FILE: .github/workflows/test_offline.yaml
================================================
name: test_offline
on:
push:
pull_request:
workflow_dispatch:
inputs:
test_linux:
description: 'Test on Linux'
type: boolean
default: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
env:
GTEST_FILTER: "-*.*_Online"
jobs:
ubuntu:
runs-on: ubuntu-latest
if: >
(github.event_name == 'push') ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.test_linux == 'true')
strategy:
matrix:
tls_backend: [openssl, no-tls]
name: ubuntu (${{ matrix.tls_backend }})
steps:
- name: checkout
uses: actions/checkout@v4
- name: install common libraries
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev zlib1g-dev libbrotli-dev libzstd-dev
- name: install OpenSSL
if: matrix.tls_backend == 'openssl'
run: sudo apt-get install -y libssl-dev
- name: disable network
run: |
sudo iptables -A OUTPUT -o lo -j ACCEPT
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -j REJECT
sudo ip6tables -A OUTPUT -o lo -j ACCEPT
sudo ip6tables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A OUTPUT -j REJECT
- name: build and run tests (OpenSSL)
if: matrix.tls_backend == 'openssl'
run: cd test && make test_split && make test_openssl_parallel
env:
LSAN_OPTIONS: suppressions=lsan_suppressions.txt
- name: build and run tests (No TLS)
if: matrix.tls_backend == 'no-tls'
run: cd test && make test_no_tls_parallel
- name: restore network
if: always()
run: |
sudo iptables -F OUTPUT
sudo ip6tables -F OUTPUT
================================================
FILE: .github/workflows/test_proxy.yaml
================================================
name: Proxy Test
on: [push, pull_request]
jobs:
test-proxy:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
tls_backend: [openssl, mbedtls]
name: proxy (${{ matrix.tls_backend }})
steps:
- uses: actions/checkout@v4
- name: Install common dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential zlib1g-dev libcurl4-openssl-dev libbrotli-dev libzstd-dev netcat-openbsd
- name: Install OpenSSL
if: matrix.tls_backend == 'openssl'
run: sudo apt-get install -y libssl-dev
- name: Install Mbed TLS
if: matrix.tls_backend == 'mbedtls'
run: sudo apt-get install -y libmbedtls-dev
- name: Run proxy tests (OpenSSL)
if: matrix.tls_backend == 'openssl'
run: cd test && make proxy
env:
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
- name: Run proxy tests (Mbed TLS)
if: matrix.tls_backend == 'mbedtls'
run: cd test && make proxy_mbedtls
env:
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
================================================
FILE: CMakeLists.txt
================================================
#[[
Build options:
* Standard BUILD_SHARED_LIBS is supported and sets HTTPLIB_SHARED default value.
* HTTPLIB_USE_OPENSSL_IF_AVAILABLE (default on)
* HTTPLIB_USE_WOLFSSL_IF_AVAILABLE (default off)
* HTTPLIB_USE_MBEDTLS_IF_AVAILABLE (default off)
* HTTPLIB_USE_ZLIB_IF_AVAILABLE (default on)
* HTTPLIB_USE_BROTLI_IF_AVAILABLE (default on)
* HTTPLIB_USE_ZSTD_IF_AVAILABLE (default on)
* HTTPLIB_BUILD_MODULES (default off)
* HTTPLIB_REQUIRE_OPENSSL (default off)
* HTTPLIB_REQUIRE_WOLFSSL (default off)
* HTTPLIB_REQUIRE_MBEDTLS (default off)
* HTTPLIB_REQUIRE_ZLIB (default off)
* HTTPLIB_REQUIRE_BROTLI (default off)
* HTTPLIB_REQUIRE_ZSTD (default off)
* HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES (default off)
* HTTPLIB_USE_NON_BLOCKING_GETADDRINFO (default on)
* HTTPLIB_COMPILE (default off)
* HTTPLIB_INSTALL (default on)
* HTTPLIB_SHARED (default off) builds as a shared library (if HTTPLIB_COMPILE is ON)
* HTTPLIB_TEST (default off)
* BROTLI_USE_STATIC_LIBS - tells Cmake to use the static Brotli libs (only works if you have them installed).
* OPENSSL_USE_STATIC_LIBS - tells Cmake to use the static OpenSSL libs (only works if you have them installed).
-------------------------------------------------------------------------------
After installation with Cmake, a find_package(httplib COMPONENTS OpenSSL wolfssl MbedTLS ZLIB Brotli zstd) is available.
This creates a httplib::httplib target (if found and if listed components are supported).
It can be linked like so:
target_link_libraries(your_exe httplib::httplib)
The following will build & install for later use.
Linux/macOS:
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo cmake --build . --target install
Windows:
mkdir build
cd build
cmake ..
runas /user:Administrator "cmake --build . --config Release --target install"
-------------------------------------------------------------------------------
These variables are available after you run find_package(httplib)
* HTTPLIB_HEADER_PATH - this is the full path to the installed header (e.g. /usr/include/httplib.h).
* HTTPLIB_IS_USING_OPENSSL - a bool for if OpenSSL support is enabled.
* HTTPLIB_IS_USING_WOLFSSL - a bool for if wolfSSL support is enabled.
* HTTPLIB_IS_USING_MBEDTLS - a bool for if MbedTLS support is enabled.
* HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled.
* HTTPLIB_IS_USING_BROTLI - a bool for if Brotli support is enabled.
* HTTPLIB_IS_USING_ZSTD - a bool for if ZSTD support is enabled.
* HTTPLIB_IS_USING_MACOSX_AUTOMATIC_ROOT_CERTIFICATES - a bool for if support of loading system certs from the Apple Keychain is enabled.
* HTTPLIB_IS_USING_NON_BLOCKING_GETADDRINFO - a bool for if nonblocking getaddrinfo is enabled.
* HTTPLIB_IS_COMPILED - a bool for if the library is compiled, or otherwise header-only.
* HTTPLIB_INCLUDE_DIR - the root path to httplib's header (e.g. /usr/include).
* HTTPLIB_LIBRARY - the full path to the library if compiled (e.g. /usr/lib/libhttplib.so).
* httplib_VERSION or HTTPLIB_VERSION - the project's version string.
* HTTPLIB_FOUND - a bool for if the target was found.
Want to use precompiled headers (Cmake feature since v3.16)?
It's as simple as doing the following (before linking):
target_precompile_headers(httplib::httplib INTERFACE "${HTTPLIB_HEADER_PATH}")
-------------------------------------------------------------------------------
ARCH_INDEPENDENT option of write_basic_package_version_file() requires Cmake v3.14
]]
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
# Get the CPPHTTPLIB_VERSION value and use it as a version
# This gets the string with the CPPHTTPLIB_VERSION value from the header.
# This is so the maintainer doesn't actually need to update this manually.
file(STRINGS httplib.h _raw_version_string REGEX "CPPHTTPLIB_VERSION \"([0-9]+\\.[0-9]+\\.[0-9]+)\"")
# Extracts just the version string itself from the whole string contained in _raw_version_string
# since _raw_version_string would contain the entire line of code where it found the version string
string(REGEX MATCH "([0-9]+\\.?)+" _httplib_version "${_raw_version_string}")
project(httplib
VERSION ${_httplib_version}
LANGUAGES CXX
DESCRIPTION "A C++ header-only HTTP/HTTPS server and client library."
HOMEPAGE_URL "https://github.com/yhirose/cpp-httplib"
)
# Change as needed to set an OpenSSL minimum version.
# This is used in the installed Cmake config file.
set(_HTTPLIB_OPENSSL_MIN_VER "3.0.0")
# Lets you disable C++ exception during CMake configure time.
# The value is used in the install CMake config file.
option(HTTPLIB_NO_EXCEPTIONS "Disable the use of C++ exceptions" OFF)
# Allow for a build to require OpenSSL to pass, instead of just being optional
option(HTTPLIB_REQUIRE_OPENSSL "Requires OpenSSL to be found & linked, or fails build." OFF)
option(HTTPLIB_REQUIRE_WOLFSSL "Requires wolfSSL to be found & linked, or fails build." OFF)
option(HTTPLIB_REQUIRE_MBEDTLS "Requires MbedTLS to be found & linked, or fails build." OFF)
option(HTTPLIB_REQUIRE_ZLIB "Requires ZLIB to be found & linked, or fails build." OFF)
# Allow for a build to casually enable OpenSSL/ZLIB support, but silently continue if not found.
# Make these options so their automatic use can be specifically disabled (as needed)
option(HTTPLIB_USE_OPENSSL_IF_AVAILABLE "Uses OpenSSL (if available) to enable HTTPS support." ON)
option(HTTPLIB_USE_WOLFSSL_IF_AVAILABLE "Uses wolfSSL (if available) to enable HTTPS support." OFF)
option(HTTPLIB_USE_MBEDTLS_IF_AVAILABLE "Uses MbedTLS (if available) to enable HTTPS support." OFF)
option(HTTPLIB_USE_ZLIB_IF_AVAILABLE "Uses ZLIB (if available) to enable Zlib compression support." ON)
# Lets you compile the program as a regular library instead of header-only
option(HTTPLIB_COMPILE "If ON, uses a Python script to split the header into a compilable header & source file (requires Python v3)." OFF)
# Lets you disable the installation (useful when fetched from another CMake project)
option(HTTPLIB_INSTALL "Enables the installation target" ON)
option(HTTPLIB_TEST "Enables testing and builds tests" OFF)
option(HTTPLIB_REQUIRE_BROTLI "Requires Brotli to be found & linked, or fails build." OFF)
option(HTTPLIB_USE_BROTLI_IF_AVAILABLE "Uses Brotli (if available) to enable Brotli decompression support." ON)
option(HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES "Disable loading system certs from the Apple Keychain on macOS." OFF)
option(HTTPLIB_USE_NON_BLOCKING_GETADDRINFO "Enables the non-blocking alternatives for getaddrinfo." ON)
option(HTTPLIB_REQUIRE_ZSTD "Requires ZSTD to be found & linked, or fails build." OFF)
option(HTTPLIB_USE_ZSTD_IF_AVAILABLE "Uses ZSTD (if available) to enable zstd support." ON)
# C++20 modules support requires CMake 3.28 or later
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.28")
option(HTTPLIB_BUILD_MODULES "Build httplib modules (requires HTTPLIB_COMPILE to be ON)." OFF)
else()
set(HTTPLIB_BUILD_MODULES OFF CACHE INTERNAL "Build httplib modules disabled (requires CMake 3.28+)" FORCE)
if(DEFINED CACHE{HTTPLIB_BUILD_MODULES} AND HTTPLIB_BUILD_MODULES)
message(WARNING "HTTPLIB_BUILD_MODULES requires CMake 3.28 or later. Current version is ${CMAKE_VERSION}. Modules support has been disabled.")
endif()
endif()
# Incompatibility between TLS libraries
set(TLS_LIBRARIES_USED_TMP 0)
foreach(tls_library OPENSSL WOLFSSL MBEDTLS)
set(TLS_REQUIRED ${HTTPLIB_REQUIRE_${tls_library}})
set(TLS_IF_AVAILABLE ${HTTPLIB_USE_${tls_library}_IF_AVAILABLE})
if(TLS_REQUIRED OR TLS_IF_AVAILABLE)
math(EXPR TLS_LIBRARIES_USED_TMP "${TLS_LIBRARIES_USED_TMP} + 1")
endif()
endforeach()
if(TLS_LIBRARIES_USED_TMP GREATER 1)
message(FATAL_ERROR "TLS libraries are mutually exclusive.")
endif()
# Defaults to static library but respects standard BUILD_SHARED_LIBS if set
include(CMakeDependentOption)
cmake_dependent_option(HTTPLIB_SHARED "Build the library as a shared library instead of static. Has no effect if using header-only."
"${BUILD_SHARED_LIBS}" HTTPLIB_COMPILE OFF
)
if(HTTPLIB_SHARED)
set(HTTPLIB_LIB_TYPE SHARED)
if(WIN32)
# Necessary for Windows if building shared libs
# See https://stackoverflow.com/a/40743080
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
else()
set(HTTPLIB_LIB_TYPE STATIC)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
if(CMAKE_SYSTEM_VERSION)
if(${CMAKE_SYSTEM_VERSION} VERSION_LESS "10.0.0")
message(WARNING "Windows ${CMAKE_SYSTEM_VERSION} or lower is not supported. Please use Windows 10 or later.")
endif()
else()
set(CMAKE_SYSTEM_VERSION "10.0.19041.0")
message(WARNING "The target is Windows but CMAKE_SYSTEM_VERSION is not set, the default system version is set to Windows 10.")
endif()
endif()
# Set some variables that are used in-tree and while building based on our options
set(HTTPLIB_IS_COMPILED ${HTTPLIB_COMPILE})
set(HTTPLIB_IS_USING_MACOSX_AUTOMATIC_ROOT_CERTIFICATES TRUE)
if(HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES)
set(HTTPLIB_IS_USING_MACOSX_AUTOMATIC_ROOT_CERTIFICATES FALSE)
endif()
set(HTTPLIB_IS_USING_NON_BLOCKING_GETADDRINFO ${HTTPLIB_USE_NON_BLOCKING_GETADDRINFO})
# Threads needed for <thread> on some systems, and for <pthread.h> on Linux
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
# Since Cmake v3.11, Crypto & SSL became optional when not specified as COMPONENTS.
if(HTTPLIB_REQUIRE_OPENSSL)
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} COMPONENTS Crypto SSL REQUIRED)
set(HTTPLIB_IS_USING_OPENSSL TRUE)
elseif(HTTPLIB_USE_OPENSSL_IF_AVAILABLE)
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} COMPONENTS Crypto SSL QUIET)
# Avoid a rare circumstance of not finding all components but the end-user did their
# own call for OpenSSL, which might trick us into thinking we'd otherwise have what we wanted
if (TARGET OpenSSL::SSL AND TARGET OpenSSL::Crypto)
set(HTTPLIB_IS_USING_OPENSSL ${OPENSSL_FOUND})
else()
set(HTTPLIB_IS_USING_OPENSSL FALSE)
endif()
endif()
if(HTTPLIB_REQUIRE_WOLFSSL)
find_package(wolfssl REQUIRED)
set(HTTPLIB_IS_USING_WOLFSSL TRUE)
elseif(HTTPLIB_USE_WOLFSSL_IF_AVAILABLE)
find_package(wolfssl QUIET)
set(HTTPLIB_IS_USING_WOLFSSL ${wolfssl_FOUND})
endif()
if(HTTPLIB_REQUIRE_MBEDTLS)
find_package(MbedTLS REQUIRED)
set(HTTPLIB_IS_USING_MBEDTLS TRUE)
elseif(HTTPLIB_USE_MBEDTLS_IF_AVAILABLE)
find_package(MbedTLS QUIET)
set(HTTPLIB_IS_USING_MBEDTLS ${MbedTLS_FOUND})
endif()
if(HTTPLIB_REQUIRE_ZLIB)
find_package(ZLIB REQUIRED)
set(HTTPLIB_IS_USING_ZLIB TRUE)
elseif(HTTPLIB_USE_ZLIB_IF_AVAILABLE)
find_package(ZLIB QUIET)
# FindZLIB doesn't have a ZLIB_FOUND variable, so check the target.
if(TARGET ZLIB::ZLIB)
set(HTTPLIB_IS_USING_ZLIB TRUE)
endif()
endif()
# Adds our cmake folder to the search path for find_package
# This is so we can use our custom FindBrotli.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(HTTPLIB_REQUIRE_BROTLI)
find_package(Brotli COMPONENTS encoder decoder common REQUIRED)
set(HTTPLIB_IS_USING_BROTLI TRUE)
elseif(HTTPLIB_USE_BROTLI_IF_AVAILABLE)
find_package(Brotli COMPONENTS encoder decoder common QUIET)
set(HTTPLIB_IS_USING_BROTLI ${Brotli_FOUND})
endif()
# NOTE:
# zstd < 1.5.6 does not provide the CMake imported target `zstd::libzstd`.
# Older versions must be consumed via their pkg-config file.
if(HTTPLIB_REQUIRE_ZSTD)
find_package(zstd 1.5.6 CONFIG)
if(NOT zstd_FOUND)
find_package(PkgConfig REQUIRED)
pkg_check_modules(zstd REQUIRED IMPORTED_TARGET libzstd)
add_library(zstd::libzstd ALIAS PkgConfig::zstd)
endif()
set(HTTPLIB_IS_USING_ZSTD TRUE)
elseif(HTTPLIB_USE_ZSTD_IF_AVAILABLE)
find_package(zstd 1.5.6 CONFIG QUIET)
if(NOT zstd_FOUND)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(zstd QUIET IMPORTED_TARGET libzstd)
if(TARGET PkgConfig::zstd)
add_library(zstd::libzstd ALIAS PkgConfig::zstd)
endif()
endif()
endif()
# Both find_package and PkgConf set a XXX_FOUND var
set(HTTPLIB_IS_USING_ZSTD ${zstd_FOUND})
endif()
# Used for default, common dirs that the end-user can change (if needed)
# like CMAKE_INSTALL_INCLUDEDIR or CMAKE_INSTALL_DATADIR
include(GNUInstallDirs)
if(HTTPLIB_COMPILE)
# Put the split script into the build dir
configure_file(split.py "${CMAKE_CURRENT_BINARY_DIR}/split.py"
COPYONLY
)
# Needs to be in the same dir as the python script
configure_file(httplib.h "${CMAKE_CURRENT_BINARY_DIR}/httplib.h"
COPYONLY
)
# Used outside of this if-else
set(_INTERFACE_OR_PUBLIC PUBLIC)
# Brings in the Python3_EXECUTABLE path we can use.
find_package(Python3 REQUIRED)
# Actually split the file
# Keeps the output in the build dir to not pollute the main dir
execute_process(COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/split.py"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ERROR_VARIABLE _httplib_split_error
)
if(_httplib_split_error)
message(FATAL_ERROR "Failed when trying to split cpp-httplib with the Python script.\n${_httplib_split_error}")
endif()
# If building modules, also generate the module file
if(HTTPLIB_BUILD_MODULES)
# Put the generate_module script into the build dir
configure_file(generate_module.py "${CMAKE_CURRENT_BINARY_DIR}/generate_module.py"
COPYONLY
)
# Generate the module file
execute_process(COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/generate_module.py"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ERROR_VARIABLE _httplib_module_error
)
if(_httplib_module_error)
message(FATAL_ERROR "Failed when trying to generate cpp-httplib module with the Python script.\n${_httplib_module_error}")
endif()
endif()
# split.py puts output in "out"
set(_httplib_build_includedir "${CMAKE_CURRENT_BINARY_DIR}/out")
add_library(${PROJECT_NAME} ${HTTPLIB_LIB_TYPE} "${_httplib_build_includedir}/httplib.cc")
target_sources(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${_httplib_build_includedir}/httplib.h>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/httplib.h>
)
# Add C++20 module support if requested
# Include from separate file to prevent parse errors on older CMake versions
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.28")
include(cmake/modules.cmake)
endif()
set_target_properties(${PROJECT_NAME}
PROPERTIES
VERSION ${${PROJECT_NAME}_VERSION}
SOVERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}"
OUTPUT_NAME cpp-httplib
)
else()
# This is for header-only.
set(_INTERFACE_OR_PUBLIC INTERFACE)
add_library(${PROJECT_NAME} INTERFACE)
set(_httplib_build_includedir "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
# Lets you address the target with httplib::httplib
# Only useful if building in-tree, versus using it from an installation.
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
# Require C++11, or C++20 if modules are enabled
if(HTTPLIB_BUILD_MODULES)
target_compile_features(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC} cxx_std_20)
else()
target_compile_features(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC} cxx_std_11)
endif()
target_include_directories(${PROJECT_NAME} SYSTEM ${_INTERFACE_OR_PUBLIC}
$<BUILD_INTERFACE:${_httplib_build_includedir}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_link_libraries(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
# Always require threads
Threads::Threads
# Needed for Windows libs on Mingw, as the pragma comment(lib, "xyz") aren't triggered.
$<$<PLATFORM_ID:Windows>:ws2_32>
$<$<PLATFORM_ID:Windows>:crypt32>
# Needed for API from MacOS Security framework
"$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>,$<BOOL:${HTTPLIB_IS_USING_MACOSX_AUTOMATIC_ROOT_CERTIFICATES}>>:-framework CFNetwork -framework CoreFoundation -framework Security>"
# Needed for non-blocking getaddrinfo on MacOS
"$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_USE_NON_BLOCKING_GETADDRINFO}>>:-framework CFNetwork -framework CoreFoundation>"
# Can't put multiple targets in a single generator expression or it bugs out.
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::common>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::encoder>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::decoder>
$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:ZLIB::ZLIB>
$<$<BOOL:${HTTPLIB_IS_USING_ZSTD}>:zstd::libzstd>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::SSL>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::Crypto>
$<$<BOOL:${HTTPLIB_IS_USING_WOLFSSL}>:wolfssl::wolfssl>
$<$<BOOL:${HTTPLIB_IS_USING_MBEDTLS}>:MbedTLS::mbedtls>
)
# Set the definitions to enable optional features
target_compile_definitions(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
$<$<BOOL:${HTTPLIB_NO_EXCEPTIONS}>:CPPHTTPLIB_NO_EXCEPTIONS>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:CPPHTTPLIB_BROTLI_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:CPPHTTPLIB_ZLIB_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_ZSTD}>:CPPHTTPLIB_ZSTD_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:CPPHTTPLIB_OPENSSL_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_WOLFSSL}>:CPPHTTPLIB_WOLFSSL_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_MBEDTLS}>:CPPHTTPLIB_MBEDTLS_SUPPORT>
$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES}>>:CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES>
$<$<BOOL:${HTTPLIB_USE_NON_BLOCKING_GETADDRINFO}>:CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO>
)
# CMake configuration files installation directory
set(_TARGET_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
include(CMakePackageConfigHelpers)
# Configures the meta-file httplibConfig.cmake.in to replace variables with paths/values/etc.
configure_package_config_file("cmake/${PROJECT_NAME}Config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${_TARGET_INSTALL_CMAKEDIR}"
# Passes the includedir install path
PATH_VARS CMAKE_INSTALL_FULL_INCLUDEDIR
)
if(HTTPLIB_COMPILE)
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
# Example: if you find_package(httplib 0.5.4)
# then anything >= 0.5.4 and < 0.6 is accepted
COMPATIBILITY SameMinorVersion
)
else()
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
# Example: if you find_package(httplib 0.5.4)
# then anything >= 0.5.4 and < 0.6 is accepted
COMPATIBILITY SameMinorVersion
# Tells Cmake that it's a header-only lib
# Mildly useful for end-users :)
ARCH_INDEPENDENT
)
endif()
if(HTTPLIB_INSTALL)
# Creates the export httplibTargets.cmake
# This is strictly what holds compilation requirements
# and linkage information (doesn't find deps though).
if(HTTPLIB_BUILD_MODULES)
install(TARGETS ${PROJECT_NAME} EXPORT httplibTargets FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/httplib/modules CXX_MODULES_BMI DESTINATION ${CMAKE_INSTALL_LIBDIR}/httplib/modules)
else()
install(TARGETS ${PROJECT_NAME} EXPORT httplibTargets)
endif()
install(FILES "${_httplib_build_includedir}/httplib.h" TYPE INCLUDE)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
# Install it so it can be used later by the httplibConfig.cmake file.
# Put it in the same dir as our config file instead of a global path so we don't potentially stomp on other packages.
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindBrotli.cmake"
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
)
# NOTE: This path changes depending on if it's on Windows or Linux
install(EXPORT httplibTargets
# Puts the targets into the httplib namespace
# So this makes httplib::httplib linkable after doing find_package(httplib)
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
)
# Install documentation & license
# ex: /usr/share/doc/httplib/README.md and /usr/share/licenses/httplib/LICENSE
install(FILES "README.md" DESTINATION "${CMAKE_INSTALL_DOCDIR}")
install(FILES "LICENSE" DESTINATION "${CMAKE_INSTALL_DATADIR}/licenses/${PROJECT_NAME}")
include(CPack)
endif()
if(HTTPLIB_BUILD_MODULES AND NOT HTTPLIB_COMPILE)
message(FATAL_ERROR "HTTPLIB_BUILD_MODULES requires HTTPLIB_COMPILE to be ON.")
endif()
if(HTTPLIB_TEST)
include(CTest)
add_subdirectory(test)
endif()
================================================
FILE: Dockerfile
================================================
FROM yhirose4dockerhub/ubuntu-builder AS builder
WORKDIR /build
COPY httplib.h .
COPY docker/main.cc .
RUN g++ -std=c++23 -static -o server -O2 -I. main.cc && strip server
FROM scratch
COPY --from=builder /build/server /server
COPY docker/html/index.html /html/index.html
EXPOSE 80
ENTRYPOINT ["/server"]
CMD ["--host", "0.0.0.0", "--port", "80", "--mount", "/:./html"]
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2017 yhirose
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README-sse.md
================================================
# SSEClient - Server-Sent Events Client
A simple, EventSource-like SSE client for C++11.
## Features
- **Auto-reconnect**: Automatically reconnects on connection loss
- **Last-Event-ID**: Sends last received ID on reconnect for resumption
- **retry field**: Respects server's reconnect interval
- **Event types**: Supports custom event types via `on_event()`
- **Async support**: Run in background thread with `start_async()`
- **C++11 compatible**: No C++14/17/20 features required
## Quick Start
```cpp
httplib::Client cli("http://localhost:8080");
httplib::sse::SSEClient sse(cli, "/events");
sse.on_message([](const httplib::sse::SSEMessage &msg) {
std::cout << "Event: " << msg.event << std::endl;
std::cout << "Data: " << msg.data << std::endl;
});
sse.start(); // Blocking, with auto-reconnect
```
## API Reference
### SSEMessage
```cpp
struct SSEMessage {
std::string event; // Event type (default: "message")
std::string data; // Event payload
std::string id; // Event ID
};
```
### SSEClient
#### Constructor
```cpp
// Basic
SSEClient(Client &client, const std::string &path);
// With custom headers
SSEClient(Client &client, const std::string &path, const Headers &headers);
```
#### Event Handlers
```cpp
// Called for all events (or events without a specific handler)
sse.on_message([](const SSEMessage &msg) { });
// Called for specific event types
sse.on_event("update", [](const SSEMessage &msg) { });
sse.on_event("delete", [](const SSEMessage &msg) { });
// Called when connection is established
sse.on_open([]() { });
// Called on connection errors
sse.on_error([](httplib::Error err) { });
```
#### Configuration
```cpp
// Set reconnect interval (default: 3000ms)
sse.set_reconnect_interval(5000);
// Set max reconnect attempts (default: 0 = unlimited)
sse.set_max_reconnect_attempts(10);
```
#### Control
```cpp
// Blocking start with auto-reconnect
sse.start();
// Non-blocking start (runs in background thread)
sse.start_async();
// Stop the client (thread-safe)
sse.stop();
```
#### State
```cpp
bool connected = sse.is_connected();
const std::string &id = sse.last_event_id();
```
## Examples
### Basic Usage
```cpp
httplib::Client cli("http://localhost:8080");
httplib::sse::SSEClient sse(cli, "/events");
sse.on_message([](const httplib::sse::SSEMessage &msg) {
std::cout << msg.data << std::endl;
});
sse.start();
```
### With Custom Event Types
```cpp
httplib::sse::SSEClient sse(cli, "/events");
sse.on_event("notification", [](const httplib::sse::SSEMessage &msg) {
std::cout << "Notification: " << msg.data << std::endl;
});
sse.on_event("update", [](const httplib::sse::SSEMessage &msg) {
std::cout << "Update: " << msg.data << std::endl;
});
sse.start();
```
### Async with Stop
```cpp
httplib::sse::SSEClient sse(cli, "/events");
sse.on_message([](const httplib::sse::SSEMessage &msg) {
std::cout << msg.data << std::endl;
});
sse.start_async(); // Returns immediately
// ... do other work ...
sse.stop(); // Stop when done
```
### With Custom Headers (e.g., Authentication)
```cpp
httplib::Headers headers = {
{"Authorization", "Bearer token123"}
};
httplib::sse::SSEClient sse(cli, "/events", headers);
sse.start();
```
### Error Handling
```cpp
sse.on_error([](httplib::Error err) {
std::cerr << "Error: " << httplib::to_string(err) << std::endl;
});
sse.set_reconnect_interval(1000);
sse.set_max_reconnect_attempts(5);
sse.start();
```
## SSE Protocol
The client parses SSE format according to the [W3C specification](https://html.spec.whatwg.org/multipage/server-sent-events.html):
```
event: custom-type
id: 123
data: {"message": "hello"}
data: simple message
: this is a comment (ignored)
```
================================================
FILE: README-stream.md
================================================
# cpp-httplib Streaming API
This document describes the streaming extensions for cpp-httplib, providing an iterator-style API for handling HTTP responses incrementally with **true socket-level streaming**.
> **Important Notes**:
>
> - **No Keep-Alive**: Each `stream::Get()` call uses a dedicated connection that is closed after the response is fully read. For connection reuse, use `Client::Get()`.
> - **Single iteration only**: The `next()` method can only iterate through the body once.
> - **Result is not thread-safe**: While `stream::Get()` can be called from multiple threads simultaneously, the returned `stream::Result` must be used from a single thread only.
## Overview
The streaming API allows you to process HTTP response bodies chunk by chunk using an iterator-style pattern. Data is read directly from the network socket, enabling low-memory processing of large responses. This is particularly useful for:
- **LLM/AI streaming responses** (e.g., ChatGPT, Claude, Ollama)
- **Server-Sent Events (SSE)**
- **Large file downloads** with progress tracking
- **Reverse proxy implementations**
## Quick Start
```cpp
#include "httplib.h"
int main() {
httplib::Client cli("http://localhost:8080");
// Get streaming response
auto result = httplib::stream::Get(cli, "/stream");
if (result) {
// Process response body in chunks
while (result.next()) {
std::cout.write(result.data(), result.size());
}
}
return 0;
}
```
## API Layers
cpp-httplib provides multiple API layers for different use cases:
```text
┌─────────────────────────────────────────────┐
│ SSEClient │ ← SSE-specific, parsed events
│ - on_message(), on_event() │
│ - Auto-reconnect, Last-Event-ID │
├─────────────────────────────────────────────┤
│ stream::Get() / stream::Result │ ← Iterator-based streaming
│ - while (result.next()) { ... } │
├─────────────────────────────────────────────┤
│ open_stream() / StreamHandle │ ← General-purpose streaming
│ - handle.read(buf, len) │
├─────────────────────────────────────────────┤
│ Client::Get() │ ← Traditional, full buffering
└─────────────────────────────────────────────┘
```
| Use Case | Recommended API |
|----------|----------------|
| SSE with auto-reconnect | `SSEClient` (see [README-sse.md](README-sse.md)) |
| LLM streaming (JSON Lines) | `stream::Get()` |
| Large file download | `stream::Get()` or `open_stream()` |
| Reverse proxy | `open_stream()` |
| Small responses with Keep-Alive | `Client::Get()` |
## API Reference
### Low-Level API: `StreamHandle`
The `StreamHandle` struct provides direct control over streaming responses. It takes ownership of the socket connection and reads data directly from the network.
> **Note:** When using `open_stream()`, the connection is dedicated to streaming and **Keep-Alive is not supported**. For Keep-Alive connections, use `client.Get()` instead.
```cpp
// Open a stream (takes ownership of socket)
httplib::Client cli("http://localhost:8080");
auto handle = cli.open_stream("GET", "/path");
// Check validity
if (handle.is_valid()) {
// Access response headers immediately
int status = handle.response->status;
auto content_type = handle.response->get_header_value("Content-Type");
// Read body incrementally
char buf[4096];
ssize_t n;
while ((n = handle.read(buf, sizeof(buf))) > 0) {
process(buf, n);
}
}
```
#### StreamHandle Members
| Member | Type | Description |
|--------|------|-------------|
| `response` | `std::unique_ptr<Response>` | HTTP response with headers |
| `error` | `Error` | Error code if request failed |
| `is_valid()` | `bool` | Returns true if response is valid |
| `read(buf, len)` | `ssize_t` | Read up to `len` bytes directly from socket |
| `get_read_error()` | `Error` | Get the last read error |
| `has_read_error()` | `bool` | Check if a read error occurred |
### High-Level API: `stream::Get()` and `stream::Result`
The `httplib.h` header provides a more ergonomic iterator-style API.
```cpp
#include "httplib.h"
httplib::Client cli("http://localhost:8080");
cli.set_follow_location(true);
...
// Simple GET
auto result = httplib::stream::Get(cli, "/path");
// GET with custom headers
httplib::Headers headers = {{"Authorization", "Bearer token"}};
auto result = httplib::stream::Get(cli, "/path", headers);
// Process the response
if (result) {
while (result.next()) {
process(result.data(), result.size());
}
}
// Or read entire body at once
auto result2 = httplib::stream::Get(cli, "/path");
if (result2) {
std::string body = result2.read_all();
}
```
#### stream::Result Members
| Member | Type | Description |
|--------|------|-------------|
| `operator bool()` | `bool` | Returns true if response is valid |
| `is_valid()` | `bool` | Same as `operator bool()` |
| `status()` | `int` | HTTP status code |
| `headers()` | `const Headers&` | Response headers |
| `get_header_value(key, def)` | `std::string` | Get header value (with optional default) |
| `has_header(key)` | `bool` | Check if header exists |
| `next()` | `bool` | Read next chunk, returns false when done |
| `data()` | `const char*` | Pointer to current chunk data |
| `size()` | `size_t` | Size of current chunk |
| `read_all()` | `std::string` | Read entire remaining body into string |
| `error()` | `Error` | Get the connection/request error |
| `read_error()` | `Error` | Get the last read error |
| `has_read_error()` | `bool` | Check if a read error occurred |
## Usage Examples
### Example 1: SSE (Server-Sent Events) Client
```cpp
#include "httplib.h"
#include <iostream>
int main() {
httplib::Client cli("http://localhost:1234");
auto result = httplib::stream::Get(cli, "/events");
if (!result) { return 1; }
while (result.next()) {
std::cout.write(result.data(), result.size());
std::cout.flush();
}
return 0;
}
```
For a complete SSE client with auto-reconnection and event parsing, see `example/ssecli-stream.cc`.
### Example 2: LLM Streaming Response
```cpp
#include "httplib.h"
#include <iostream>
int main() {
httplib::Client cli("http://localhost:11434"); // Ollama
auto result = httplib::stream::Get(cli, "/api/generate");
if (result && result.status() == 200) {
while (result.next()) {
std::cout.write(result.data(), result.size());
std::cout.flush();
}
}
// Check for connection errors
if (result.read_error() != httplib::Error::Success) {
std::cerr << "Connection lost\n";
}
return 0;
}
```
### Example 3: Large File Download with Progress
```cpp
#include "httplib.h"
#include <fstream>
#include <iostream>
int main() {
httplib::Client cli("http://example.com");
auto result = httplib::stream::Get(cli, "/large-file.zip");
if (!result || result.status() != 200) {
std::cerr << "Download failed\n";
return 1;
}
std::ofstream file("download.zip", std::ios::binary);
size_t total = 0;
while (result.next()) {
file.write(result.data(), result.size());
total += result.size();
std::cout << "\rDownloaded: " << (total / 1024) << " KB" << std::flush;
}
std::cout << "\nComplete!\n";
return 0;
}
```
### Example 4: Reverse Proxy Streaming
```cpp
#include "httplib.h"
httplib::Server svr;
svr.Get("/proxy/(.*)", [](const httplib::Request& req, httplib::Response& res) {
httplib::Client upstream("http://backend:8080");
auto handle = upstream.open_stream("/" + req.matches[1].str());
if (!handle.is_valid()) {
res.status = 502;
return;
}
res.status = handle.response->status;
res.set_chunked_content_provider(
handle.response->get_header_value("Content-Type"),
[handle = std::move(handle)](size_t, httplib::DataSink& sink) mutable {
char buf[8192];
auto n = handle.read(buf, sizeof(buf));
if (n > 0) {
sink.write(buf, static_cast<size_t>(n));
return true;
}
sink.done();
return true;
}
);
});
svr.listen("0.0.0.0", 3000);
```
## Comparison with Existing APIs
| Feature | `Client::Get()` | `open_stream()` | `stream::Get()` |
|---------|----------------|-----------------|----------------|
| Headers available | After complete | Immediately | Immediately |
| Body reading | All at once | Direct from socket | Iterator-based |
| Memory usage | Full body in RAM | Minimal (controlled) | Minimal (controlled) |
| Keep-Alive support | ✅ Yes | ❌ No | ❌ No |
| Compression | Auto-handled | Auto-handled | Auto-handled |
| Best for | Small responses, Keep-Alive | Low-level streaming | Easy streaming |
## Features
- **True socket-level streaming**: Data is read directly from the network socket
- **Low memory footprint**: Only the current chunk is held in memory
- **Compression support**: Automatic decompression for gzip, brotli, and zstd
- **Chunked transfer**: Full support for chunked transfer encoding
- **SSL/TLS support**: Works with HTTPS connections
## Important Notes
### Keep-Alive Behavior
The streaming API (`stream::Get()` / `open_stream()`) takes ownership of the socket connection for the duration of the stream. This means:
- **Keep-Alive is not supported** for streaming connections
- The socket is closed when `StreamHandle` is destroyed
- For Keep-Alive scenarios, use the standard `client.Get()` API instead
```cpp
// Use for streaming (no Keep-Alive)
auto result = httplib::stream::Get(cli, "/large-stream");
while (result.next()) { /* ... */ }
// Use for Keep-Alive connections
auto res = cli.Get("/api/data"); // Connection can be reused
```
## Related
- [Issue #2269](https://github.com/yhirose/cpp-httplib/issues/2269) - Original feature request
- [example/ssecli-stream.cc](./example/ssecli-stream.cc) - SSE client with auto-reconnection
================================================
FILE: README-websocket.md
================================================
# WebSocket - RFC 6455 WebSocket Support
A simple, blocking WebSocket implementation for C++11.
> [!IMPORTANT]
> This is a blocking I/O WebSocket implementation using a thread-per-connection model. If you need high-concurrency WebSocket support with non-blocking/async I/O (e.g., thousands of simultaneous connections), this is not the one that you want.
## Features
- **RFC 6455 compliant**: Full WebSocket protocol support
- **Server and Client**: Both sides included
- **SSL/TLS support**: `wss://` scheme for secure connections
- **Text and Binary**: Both message types supported
- **Automatic heartbeat**: Periodic Ping/Pong keeps connections alive
- **Subprotocol negotiation**: `Sec-WebSocket-Protocol` support for GraphQL, MQTT, etc.
## Quick Start
### Server
```cpp
httplib::Server svr;
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) {
std::string msg;
while (ws.read(msg)) {
ws.send("echo: " + msg);
}
});
svr.listen("localhost", 8080);
```
### Client
```cpp
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws");
if (ws.connect()) {
ws.send("hello");
std::string msg;
if (ws.read(msg)) {
std::cout << msg << std::endl; // "echo: hello"
}
ws.close();
}
```
## API Reference
### ReadResult
```cpp
enum ReadResult : int {
Fail = 0, // Connection closed or error
Text = 1, // UTF-8 text message
Binary = 2, // Binary message
};
```
Returned by `read()`. Since `Fail` is `0`, the result works naturally in boolean contexts — `while (ws.read(msg))` continues until the connection closes. When you need to distinguish text from binary, check the return value directly.
### CloseStatus
```cpp
enum class CloseStatus : uint16_t {
Normal = 1000,
GoingAway = 1001,
ProtocolError = 1002,
UnsupportedData = 1003,
NoStatus = 1005,
Abnormal = 1006,
InvalidPayload = 1007,
PolicyViolation = 1008,
MessageTooBig = 1009,
MandatoryExtension = 1010,
InternalError = 1011,
};
```
### Server Registration
```cpp
// Basic handler
Server &WebSocket(const std::string &pattern, WebSocketHandler handler);
// With subprotocol negotiation
Server &WebSocket(const std::string &pattern, WebSocketHandler handler,
SubProtocolSelector sub_protocol_selector);
```
**Type aliases:**
```cpp
using WebSocketHandler =
std::function<void(const Request &, ws::WebSocket &)>;
using SubProtocolSelector =
std::function<std::string(const std::vector<std::string> &protocols)>;
```
The `SubProtocolSelector` receives the list of subprotocols proposed by the client (from the `Sec-WebSocket-Protocol` header) and returns the selected one. Return an empty string to decline all proposed subprotocols.
### WebSocket (Server-side)
Passed to the handler registered with `Server::WebSocket()`. The handler runs in a dedicated thread per connection.
```cpp
// Read next message (blocks until received, returns Fail/Text/Binary)
ReadResult read(std::string &msg);
// Send messages
bool send(const std::string &data); // Text
bool send(const char *data, size_t len); // Binary
// Close the connection
void close(CloseStatus status = CloseStatus::Normal,
const std::string &reason = "");
// Access the original HTTP upgrade request
const Request &request() const;
// Check if the connection is still open
bool is_open() const;
```
### WebSocketClient
```cpp
// Constructor - accepts ws:// or wss:// URL
explicit WebSocketClient(const std::string &scheme_host_port_path,
const Headers &headers = {});
// Check if the URL was parsed successfully
bool is_valid() const;
// Connect (performs HTTP upgrade handshake)
bool connect();
// Get the subprotocol selected by the server (empty if none)
const std::string &subprotocol() const;
// Read/Send/Close (same as server-side WebSocket)
ReadResult read(std::string &msg);
bool send(const std::string &data);
bool send(const char *data, size_t len);
void close(CloseStatus status = CloseStatus::Normal,
const std::string &reason = "");
bool is_open() const;
// Timeouts
void set_read_timeout(time_t sec, time_t usec = 0);
void set_write_timeout(time_t sec, time_t usec = 0);
// SSL configuration (wss:// only, requires CPPHTTPLIB_OPENSSL_SUPPORT)
void set_ca_cert_path(const std::string &path);
void set_ca_cert_store(tls::ca_store_t store);
void enable_server_certificate_verification(bool enabled);
```
## Examples
### Echo Server with Connection Logging
```cpp
httplib::Server svr;
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) {
std::cout << "Connected from " << req.remote_addr << std::endl;
std::string msg;
while (ws.read(msg)) {
ws.send("echo: " + msg);
}
std::cout << "Disconnected" << std::endl;
});
svr.listen("localhost", 8080);
```
### Client: Continuous Read Loop
```cpp
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws");
if (ws.connect()) {
ws.send("hello");
ws.send("world");
std::string msg;
while (ws.read(msg)) { // blocks until a message arrives
std::cout << msg << std::endl; // "echo: hello", "echo: world"
}
// read() returns false when the server closes the connection
}
```
### Text and Binary Messages
Check the `ReadResult` return value to distinguish between text and binary:
```cpp
// Server
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) {
std::string msg;
httplib::ws::ReadResult ret;
while ((ret = ws.read(msg))) {
if (ret == httplib::ws::Text) {
ws.send("echo: " + msg);
} else {
ws.send(msg.data(), msg.size()); // Binary echo
}
}
});
// Client
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws");
if (ws.connect()) {
// Send binary data
const char binary[] = {0x00, 0x01, 0x02, 0x03};
ws.send(binary, sizeof(binary));
// Receive and check the type
std::string msg;
if (ws.read(msg) == httplib::ws::Binary) {
// Process binary data in msg
}
ws.close();
}
```
### SSL Client
```cpp
httplib::ws::WebSocketClient ws("wss://echo.example.com/ws");
if (ws.connect()) {
ws.send("hello over TLS");
std::string msg;
if (ws.read(msg)) {
std::cout << msg << std::endl;
}
ws.close();
}
```
### Close with Status
```cpp
// Client-side: close with a specific status code and reason
ws.close(httplib::ws::CloseStatus::GoingAway, "shutting down");
// Server-side: close with a policy violation status
ws.close(httplib::ws::CloseStatus::PolicyViolation, "forbidden");
```
### Accessing the Upgrade Request
```cpp
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) {
// Access headers from the original HTTP upgrade request
auto auth = req.get_header_value("Authorization");
if (auth.empty()) {
ws.close(httplib::ws::CloseStatus::PolicyViolation, "unauthorized");
return;
}
std::string msg;
while (ws.read(msg)) {
ws.send("echo: " + msg);
}
});
```
### Custom Headers and Timeouts
```cpp
httplib::Headers headers = {
{"Authorization", "Bearer token123"}
};
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws", headers);
ws.set_read_timeout(30, 0); // 30 seconds
ws.set_write_timeout(10, 0); // 10 seconds
if (ws.connect()) {
std::string msg;
while (ws.read(msg)) {
std::cout << msg << std::endl;
}
}
```
### Subprotocol Negotiation
The server can negotiate a subprotocol with the client using `Sec-WebSocket-Protocol`. This is required for protocols like GraphQL over WebSocket (`graphql-ws`) and MQTT.
```cpp
// Server: register a handler with a subprotocol selector
svr.WebSocket(
"/ws",
[](const httplib::Request &req, httplib::ws::WebSocket &ws) {
std::string msg;
while (ws.read(msg)) {
ws.send("echo: " + msg);
}
},
[](const std::vector<std::string> &protocols) -> std::string {
// The client proposed a list of subprotocols; pick one
for (const auto &p : protocols) {
if (p == "graphql-ws" || p == "graphql-transport-ws") {
return p;
}
}
return ""; // Decline all
});
// Client: propose subprotocols via Sec-WebSocket-Protocol header
httplib::Headers headers = {
{"Sec-WebSocket-Protocol", "graphql-ws, graphql-transport-ws"}
};
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws", headers);
if (ws.connect()) {
// Check which subprotocol the server selected
std::cout << "Subprotocol: " << ws.subprotocol() << std::endl;
// => "graphql-ws"
ws.close();
}
```
### SSL Client with Certificate Configuration
```cpp
httplib::ws::WebSocketClient ws("wss://example.com/ws");
ws.set_ca_cert_path("/path/to/ca-bundle.crt");
ws.enable_server_certificate_verification(true);
if (ws.connect()) {
ws.send("secure message");
ws.close();
}
```
## Configuration
| Macro | Default | Description |
|---------------------------------------------|-------------------|----------------------------------------------------------|
| `CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH` | `16777216` (16MB) | Maximum payload size per message |
| `CPPHTTPLIB_WEBSOCKET_READ_TIMEOUT_SECOND` | `300` | Read timeout for WebSocket connections (seconds) |
| `CPPHTTPLIB_WEBSOCKET_CLOSE_TIMEOUT_SECOND` | `5` | Timeout for waiting peer's Close response (seconds) |
| `CPPHTTPLIB_WEBSOCKET_PING_INTERVAL_SECOND` | `30` | Automatic Ping interval for heartbeat (seconds) |
### Runtime Ping Interval
You can override the ping interval at runtime instead of changing the compile-time macro. Set it to `0` to disable automatic pings entirely.
```cpp
// Server side
httplib::Server svr;
svr.set_websocket_ping_interval(10); // 10 seconds
// Or using std::chrono
svr.set_websocket_ping_interval(std::chrono::seconds(10));
// Client side
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws");
ws.set_websocket_ping_interval(10); // 10 seconds
// Disable automatic pings
ws.set_websocket_ping_interval(0);
```
## Threading Model
WebSocket connections share the same thread pool as HTTP requests. Each WebSocket connection occupies one thread for its entire lifetime.
The default thread pool uses dynamic scaling: it maintains a base thread count of `CPPHTTPLIB_THREAD_POOL_COUNT` (8 or `std::thread::hardware_concurrency() - 1`, whichever is greater) and can scale up to 4x that count under load (`CPPHTTPLIB_THREAD_POOL_MAX_COUNT`). When all base threads are busy, temporary threads are spawned automatically up to the maximum. These dynamic threads exit after an idle timeout (`CPPHTTPLIB_THREAD_POOL_IDLE_TIMEOUT`, default 3 seconds).
This dynamic scaling helps accommodate WebSocket connections alongside HTTP requests. However, if you expect many simultaneous WebSocket connections, you should configure the thread pool accordingly:
```cpp
httplib::Server svr;
svr.new_task_queue = [] {
return new httplib::ThreadPool(/*base_threads=*/8, /*max_threads=*/128);
};
```
Choose sizes that account for both your expected HTTP load and the maximum number of simultaneous WebSocket connections.
## Protocol
The implementation follows [RFC 6455](https://tools.ietf.org/html/rfc6455):
- Handshake via HTTP Upgrade with `Sec-WebSocket-Key` / `Sec-WebSocket-Accept`
- Subprotocol negotiation via `Sec-WebSocket-Protocol`
- Frame masking (client-to-server)
- Control frames: Close, Ping, Pong
- Message fragmentation and reassembly
- Close handshake with status codes
## Browser Test
Run the echo server example and open `http://localhost:8080` in a browser:
```bash
cd example && make wsecho && ./wsecho
```
================================================
FILE: README.md
================================================
# cpp-httplib
[](https://github.com/yhirose/cpp-httplib/actions)
A C++11 single-file header-only cross platform HTTP/HTTPS library.<br>
It's extremely easy to set up. Just include the **[httplib.h](https://raw.githubusercontent.com/yhirose/cpp-httplib/refs/heads/master/httplib.h)** file in your code!
Learn more in the [official documentation](https://yhirose.github.io/cpp-httplib/) (built with [docs-gen](https://github.com/yhirose/docs-gen)).
> [!IMPORTANT]
> This library uses 'blocking' socket I/O. If you are looking for a library with 'non-blocking' socket I/O, this is not the one that you want.
> [!WARNING]
> 32-bit platforms are **NOT supported**. Use at your own risk. The library may compile on 32-bit targets, but no security review has been conducted for 32-bit environments. Integer truncation and other 32-bit-specific issues may exist. **Security reports that only affect 32-bit platforms will be closed without action.** The maintainer does not have access to 32-bit environments for testing or fixing issues. CI includes basic compile checks only, not functional or security testing.
## Main Features
- HTTP Server/Client
- SSL/TLS support (OpenSSL, MbedTLS, wolfSSL)
- [Stream API](README-stream.md)
- [Server-Sent Events](README-sse.md)
- [WebSocket](README-websocket.md)
## Simple examples
### Server
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// HTTP
httplib::Server svr;
// HTTPS
httplib::SSLServer svr;
svr.Get("/hi", [](const httplib::Request &, httplib::Response &res) {
res.set_content("Hello World!", "text/plain");
});
svr.listen("0.0.0.0", 8080);
```
### Client
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// HTTP
httplib::Client cli("http://yhirose.github.io");
// HTTPS
httplib::Client cli("https://yhirose.github.io");
if (auto res = cli.Get("/hi")) {
res->status;
res->body;
}
```
## SSL/TLS Support
cpp-httplib supports multiple TLS backends through an abstraction layer:
| Backend | Define | Libraries | Notes |
| :------ | :----- | :-------- | :---- |
| OpenSSL | `CPPHTTPLIB_OPENSSL_SUPPORT` | `libssl`, `libcrypto` | [3.0 or later](https://www.openssl.org/policies/releasestrat.html) required |
| Mbed TLS | `CPPHTTPLIB_MBEDTLS_SUPPORT` | `libmbedtls`, `libmbedx509`, `libmbedcrypto` | 2.x and 3.x supported (auto-detected) |
| wolfSSL | `CPPHTTPLIB_WOLFSSL_SUPPORT` | `libwolfssl` | 5.x supported; must build with `--enable-opensslall` |
> [!NOTE]
> **Mbed TLS / wolfSSL limitation:** `get_ca_certs()` and `get_ca_names()` only reflect CA certificates loaded via `load_ca_cert_store()`. Certificates loaded through `set_ca_cert_path()` or system certificates (`load_system_certs`) are not enumerable.
```c++
// Use either OpenSSL, Mbed TLS, or wolfSSL
#define CPPHTTPLIB_OPENSSL_SUPPORT // or CPPHTTPLIB_MBEDTLS_SUPPORT or CPPHTTPLIB_WOLFSSL_SUPPORT
#include "path/to/httplib.h"
// Server
httplib::SSLServer svr("./cert.pem", "./key.pem");
// Client
httplib::Client cli("https://localhost:1234"); // scheme + host
httplib::SSLClient cli("localhost:1234"); // host
httplib::SSLClient cli("localhost", 1234); // host, port
// Use your CA bundle
cli.set_ca_cert_path("./ca-bundle.crt");
// Disable cert verification
cli.enable_server_certificate_verification(false);
// Disable host verification
cli.enable_server_hostname_verification(false);
```
### SSL Error Handling
When SSL operations fail, cpp-httplib provides detailed error information through `ssl_error()` and `ssl_backend_error()`:
- `ssl_error()` - Returns the TLS-level error code (e.g., `SSL_ERROR_SSL` for OpenSSL)
- `ssl_backend_error()` - Returns the backend-specific error code (e.g., `ERR_get_error()` for OpenSSL/wolfSSL, return value for Mbed TLS)
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT // or CPPHTTPLIB_MBEDTLS_SUPPORT or CPPHTTPLIB_WOLFSSL_SUPPORT
#include "path/to/httplib.h"
httplib::Client cli("https://example.com");
auto res = cli.Get("/");
if (!res) {
// Check the error type
const auto err = res.error();
switch (err) {
case httplib::Error::SSLConnection:
std::cout << "SSL connection failed, SSL error: "
<< res.ssl_error() << std::endl;
break;
case httplib::Error::SSLLoadingCerts:
std::cout << "SSL cert loading failed, backend error: "
<< std::hex << res.ssl_backend_error() << std::endl;
break;
case httplib::Error::SSLServerVerification:
std::cout << "SSL verification failed, verify error: "
<< res.ssl_backend_error() << std::endl;
break;
case httplib::Error::SSLServerHostnameVerification:
std::cout << "SSL hostname verification failed, verify error: "
<< res.ssl_backend_error() << std::endl;
break;
default:
std::cout << "HTTP error: " << httplib::to_string(err) << std::endl;
}
}
```
### Custom Certificate Verification
You can set a custom verification callback using `tls::VerifyCallback`:
```c++
httplib::Client cli("https://example.com");
cli.set_server_certificate_verifier(
[](const httplib::tls::VerifyContext &ctx) -> bool {
std::cout << "Subject CN: " << ctx.subject_cn() << std::endl;
std::cout << "Issuer: " << ctx.issuer_name() << std::endl;
std::cout << "Depth: " << ctx.depth << std::endl;
std::cout << "Pre-verified: " << ctx.preverify_ok << std::endl;
// Inspect SANs (Subject Alternative Names)
for (const auto &san : ctx.sans()) {
std::cout << "SAN: " << san.value << std::endl;
}
// Return true to accept, false to reject
return ctx.preverify_ok;
});
```
### Peer Certificate Inspection
On the server side, you can inspect the client's peer certificate from a request handler:
```c++
httplib::SSLServer svr("./cert.pem", "./key.pem",
"./client-ca-cert.pem");
svr.Get("/", [](const httplib::Request &req, httplib::Response &res) {
auto cert = req.peer_cert();
if (cert) {
std::cout << "Client CN: " << cert.subject_cn() << std::endl;
std::cout << "Serial: " << cert.serial() << std::endl;
}
auto sni = req.sni();
std::cout << "SNI: " << sni << std::endl;
});
```
### Platform-specific Certificate Handling
cpp-httplib automatically integrates with the OS certificate store on macOS and Windows. This works with all TLS backends.
| Platform | Behavior | Disable (compile time) |
| :------- | :------- | :--------------------- |
| macOS | Loads system certs from Keychain (link `CoreFoundation` and `Security` with `-framework`) | `CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES` |
| Windows | Verifies certs via CryptoAPI (`CertGetCertificateChain` / `CertVerifyCertificateChainPolicy`) with revocation checking | `CPPHTTPLIB_DISABLE_WINDOWS_AUTOMATIC_ROOT_CERTIFICATES_UPDATE` |
On Windows, verification can also be disabled at runtime:
```c++
cli.enable_windows_certificate_verification(false);
```
> [!NOTE]
> When using SSL, it seems impossible to avoid SIGPIPE in all cases, since on some operating systems, SIGPIPE can only be suppressed on a per-message basis, but there is no way to make the OpenSSL library do so for its internal communications. If your program needs to avoid being terminated on SIGPIPE, the only fully general way might be to set up a signal handler for SIGPIPE to handle or ignore it yourself.
## Server
```c++
#include <httplib.h>
int main(void)
{
using namespace httplib;
Server svr;
svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain");
});
// Match the request path against a regular expression
// and extract its captures
svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
});
// Capture the second segment of the request path as "id" path param
svr.Get("/users/:id", [&](const Request& req, Response& res) {
auto user_id = req.path_params.at("id");
res.set_content(user_id, "text/plain");
});
// Extract values from HTTP headers and URL query params
svr.Get("/body-header-param", [](const Request& req, Response& res) {
if (req.has_header("Content-Length")) {
auto val = req.get_header_value("Content-Length");
}
if (req.has_param("key")) {
auto val = req.get_param_value("key");
}
res.set_content(req.body, "text/plain");
});
// If the handler takes time to finish, you can also poll the connection state
svr.Get("/task", [&](const Request& req, Response& res) {
const char * result = nullptr;
process.run(); // for example, starting an external process
while (result == nullptr) {
sleep(1);
if (req.is_connection_closed()) {
process.kill(); // kill the process
return;
}
result = process.stdout(); // != nullptr if the process finishes
}
res.set_content(result, "text/plain");
});
svr.Get("/stop", [&](const Request& req, Response& res) {
svr.stop();
});
svr.listen("localhost", 1234);
}
```
`Post`, `Put`, `Patch`, `Delete` and `Options` methods are also supported.
### Bind a socket to multiple interfaces and any available port
```cpp
int port = svr.bind_to_any_port("0.0.0.0");
svr.listen_after_bind();
```
### Static File Server
```cpp
// Mount / to ./www directory
auto ret = svr.set_mount_point("/", "./www");
if (!ret) {
// The specified base directory doesn't exist...
}
// Mount /public to ./www directory
ret = svr.set_mount_point("/public", "./www");
// Mount /public to ./www1 and ./www2 directories
ret = svr.set_mount_point("/public", "./www1"); // 1st order to search
ret = svr.set_mount_point("/public", "./www2"); // 2nd order to search
// Remove mount /
ret = svr.remove_mount_point("/");
// Remove mount /public
ret = svr.remove_mount_point("/public");
```
```cpp
// User defined file extension and MIME type mappings
svr.set_file_extension_and_mimetype_mapping("cc", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("cpp", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("hh", "text/x-h");
```
The following are built-in mappings:
| Extension | MIME Type | Extension | MIME Type |
| :--------- | :-------------------------- | :--------- | :-------------------------- |
| css | text/css | mpga | audio/mpeg |
| csv | text/csv | weba | audio/webm |
| txt | text/plain | wav | audio/wave |
| vtt | text/vtt | otf | font/otf |
| html, htm | text/html | ttf | font/ttf |
| apng | image/apng | woff | font/woff |
| avif | image/avif | woff2 | font/woff2 |
| bmp | image/bmp | 7z | application/x-7z-compressed |
| gif | image/gif | atom | application/atom+xml |
| png | image/png | pdf | application/pdf |
| svg | image/svg+xml | mjs, js | text/javascript |
| webp | image/webp | json | application/json |
| ico | image/x-icon | rss | application/rss+xml |
| tif | image/tiff | tar | application/x-tar |
| tiff | image/tiff | xhtml, xht | application/xhtml+xml |
| jpeg, jpg | image/jpeg | xslt | application/xslt+xml |
| mp4 | video/mp4 | xml | application/xml |
| mpeg | video/mpeg | gz | application/gzip |
| webm | video/webm | zip | application/zip |
| mp3 | audio/mp3 | wasm | application/wasm |
> [!WARNING]
> These static file server methods are not thread-safe.
<!-- -->
> [!NOTE]
> On POSIX systems, the static file server rejects requests that resolve (via symlinks) to a path outside the mounted base directory. Ensure that the served directory has appropriate permissions, as managing access to the served directory is the application developer's responsibility.
### File request handler
```cpp
// The handler is called right before the response is sent to a client
svr.set_file_request_handler([](const Request &req, Response &res) {
...
});
```
### Logging
cpp-httplib provides separate logging capabilities for access logs and error logs, similar to web servers like Nginx and Apache.
#### Access Logging
Access loggers capture successful HTTP requests and responses:
```cpp
svr.set_logger([](const httplib::Request& req, const httplib::Response& res) {
std::cout << req.method << " " << req.path << " -> " << res.status << std::endl;
});
```
#### Pre-compression Logging
You can also set a pre-compression logger to capture request/response data before compression is applied:
```cpp
svr.set_pre_compression_logger([](const httplib::Request& req, const httplib::Response& res) {
// Log before compression - res.body contains uncompressed content
// Content-Encoding header is not yet set
your_pre_compression_logger(req, res);
});
```
The pre-compression logger is only called when compression would be applied. For responses without compression, only the access logger is called.
#### Error Logging
Error loggers capture failed requests and connection issues. Unlike access loggers, error loggers only receive the Error and Request information, as errors typically occur before a meaningful Response can be generated.
```cpp
svr.set_error_logger([](const httplib::Error& err, const httplib::Request* req) {
std::cerr << httplib::to_string(err) << " while processing request";
if (req) {
std::cerr << ", client: " << req->get_header_value("X-Forwarded-For")
<< ", request: '" << req->method << " " << req->path << " " << req->version << "'"
<< ", host: " << req->get_header_value("Host");
}
std::cerr << std::endl;
});
```
### Error handler
```cpp
svr.set_error_handler([](const auto& req, auto& res) {
auto fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
```
### Exception handler
The exception handler gets called if a user routing handler throws an error.
```cpp
svr.set_exception_handler([](const auto& req, auto& res, std::exception_ptr ep) {
auto fmt = "<h1>Error 500</h1><p>%s</p>";
char buf[BUFSIZ];
try {
std::rethrow_exception(ep);
} catch (std::exception &e) {
snprintf(buf, sizeof(buf), fmt, e.what());
} catch (...) { // See the following NOTE
snprintf(buf, sizeof(buf), fmt, "Unknown Exception");
}
res.set_content(buf, "text/html");
res.status = StatusCode::InternalServerError_500;
});
```
> [!CAUTION]
> if you don't provide the `catch (...)` block for a rethrown exception pointer, an uncaught exception will end up causing the server crash. Be careful!
### Pre routing handler
```cpp
svr.set_pre_routing_handler([](const auto& req, auto& res) {
if (req.path == "/hello") {
res.set_content("world", "text/html");
return Server::HandlerResponse::Handled;
}
return Server::HandlerResponse::Unhandled;
});
```
### Post routing handler
```cpp
svr.set_post_routing_handler([](const auto& req, auto& res) {
res.set_header("ADDITIONAL_HEADER", "value");
});
```
### Pre request handler
```cpp
svr.set_pre_request_handler([](const auto& req, auto& res) {
if (req.matched_route == "/user/:user") {
auto user = req.path_params.at("user");
if (user != "john") {
res.status = StatusCode::Forbidden_403;
res.set_content("error", "text/html");
return Server::HandlerResponse::Handled;
}
}
return Server::HandlerResponse::Unhandled;
});
```
### Response user data
`res.user_data` is a `std::map<std::string, httplib::any>` that lets pre-routing or pre-request handlers pass arbitrary data to route handlers.
```cpp
struct AuthContext {
std::string user_id;
std::string role;
};
svr.set_pre_routing_handler([](const auto& req, auto& res) {
auto token = req.get_header_value("Authorization");
res.user_data["auth"] = AuthContext{decode_token(token)};
return Server::HandlerResponse::Unhandled;
});
svr.Get("/me", [](const auto& /*req*/, auto& res) {
auto* ctx = httplib::any_cast<AuthContext>(&res.user_data["auth"]);
if (!ctx) {
res.status = StatusCode::Unauthorized_401;
return;
}
res.set_content("Hello " + ctx->user_id, "text/plain");
});
```
`httplib::any` mirrors the C++17 `std::any` API. On C++17 and later it is an alias for `std::any`; on C++11/14 a compatible implementation is provided.
### Form data handling
#### URL-encoded form data ('application/x-www-form-urlencoded')
```cpp
svr.Post("/form", [&](const auto& req, auto& res) {
// URL query parameters and form-encoded data are accessible via req.params
std::string username = req.get_param_value("username");
std::string password = req.get_param_value("password");
// Handle multiple values with same name
auto interests = req.get_param_values("interests");
// Check existence
if (req.has_param("newsletter")) {
// Handle newsletter subscription
}
});
```
#### 'multipart/form-data' POST data
```cpp
svr.Post("/multipart", [&](const Request& req, Response& res) {
// Access text fields (from form inputs without files)
std::string username = req.form.get_field("username");
std::string bio = req.form.get_field("bio");
// Access uploaded files
if (req.form.has_file("avatar")) {
const auto& file = req.form.get_file("avatar");
std::cout << "Uploaded file: " << file.filename
<< " (" << file.content_type << ") - "
<< file.content.size() << " bytes" << std::endl;
// Access additional headers if needed
for (const auto& header : file.headers) {
std::cout << "Header: " << header.first << " = " << header.second << std::endl;
}
// IMPORTANT: file.filename is an untrusted value from the client.
// Always sanitize to prevent path traversal attacks.
auto safe_name = httplib::sanitize_filename(file.filename);
if (safe_name.empty()) {
res.status = StatusCode::BadRequest_400;
res.set_content("Invalid filename", "text/plain");
return;
}
// Save to disk
std::ofstream ofs(upload_dir + "/" + safe_name, std::ios::binary);
ofs << file.content;
}
// Handle multiple values with same name
auto tags = req.form.get_fields("tags"); // e.g., multiple checkboxes
for (const auto& tag : tags) {
std::cout << "Tag: " << tag << std::endl;
}
auto documents = req.form.get_files("documents"); // multiple file upload
for (const auto& doc : documents) {
std::cout << "Document: " << doc.filename
<< " (" << doc.content.size() << " bytes)" << std::endl;
}
// Check existence before accessing
if (req.form.has_field("newsletter")) {
std::cout << "Newsletter subscription: " << req.form.get_field("newsletter") << std::endl;
}
// Get counts for validation
if (req.form.get_field_count("tags") > 5) {
res.status = StatusCode::BadRequest_400;
res.set_content("Too many tags", "text/plain");
return;
}
// Summary
std::cout << "Received " << req.form.fields.size() << " text fields and "
<< req.form.files.size() << " files" << std::endl;
res.set_content("Upload successful", "text/plain");
});
```
#### Filename Sanitization
`file.filename` in multipart uploads is an untrusted value from the client. Always sanitize before using it in file paths:
```cpp
auto safe = httplib::sanitize_filename(file.filename);
```
This function strips path separators (`/`, `\`), null bytes, leading/trailing whitespace, and rejects `.` and `..`. Returns an empty string if the filename is unsafe.
### Receive content with a content receiver
```cpp
svr.Post("/content_receiver",
[&](const Request &req, Response &res, const ContentReader &content_reader) {
if (req.is_multipart_form_data()) {
// NOTE: `content_reader` is blocking until every form data field is read
// This approach allows streaming processing of large files
std::vector<FormData> items;
content_reader(
[&](const FormData &item) {
items.push_back(item);
return true;
},
[&](const char *data, size_t data_length) {
items.back().content.append(data, data_length);
return true;
});
// Process the received items
for (const auto& item : items) {
if (item.filename.empty()) {
// Text field
std::cout << "Field: " << item.name << " = " << item.content << std::endl;
} else {
// File
std::cout << "File: " << item.name << " (" << item.filename << ") - "
<< item.content.size() << " bytes" << std::endl;
}
}
} else {
std::string body;
content_reader([&](const char *data, size_t data_length) {
body.append(data, data_length);
return true;
});
}
});
```
### Send content with the content provider
```cpp
const size_t DATA_CHUNK_SIZE = 4;
svr.Get("/stream", [&](const Request &req, Response &res) {
auto data = new std::string("abcdefg");
res.set_content_provider(
data->size(), // Content length
"text/plain", // Content type
[&, data](size_t offset, size_t length, DataSink &sink) {
const auto &d = *data;
sink.write(&d[offset], std::min(length, DATA_CHUNK_SIZE));
return true; // return 'false' if you want to cancel the process.
},
[data](bool success) { delete data; });
});
```
Without content length:
```cpp
svr.Get("/stream", [&](const Request &req, Response &res) {
res.set_content_provider(
"text/plain", // Content type
[&](size_t offset, DataSink &sink) {
if (/* there is still data */) {
std::vector<char> data;
// prepare data...
sink.write(data.data(), data.size());
} else {
sink.done(); // No more data
}
return true; // return 'false' if you want to cancel the process.
});
});
```
### Chunked transfer encoding
```cpp
svr.Get("/chunked", [&](const Request& req, Response& res) {
res.set_chunked_content_provider(
"text/plain",
[](size_t offset, DataSink &sink) {
sink.write("123", 3);
sink.write("345", 3);
sink.write("789", 3);
sink.done(); // No more data
return true; // return 'false' if you want to cancel the process.
}
);
});
```
With trailer:
```cpp
svr.Get("/chunked", [&](const Request& req, Response& res) {
res.set_header("Trailer", "Dummy1, Dummy2");
res.set_chunked_content_provider(
"text/plain",
[](size_t offset, DataSink &sink) {
sink.write("123", 3);
sink.write("345", 3);
sink.write("789", 3);
sink.done_with_trailer({
{"Dummy1", "DummyVal1"},
{"Dummy2", "DummyVal2"}
});
return true;
}
);
});
```
### Send file content
```cpp
svr.Get("/content", [&](const Request &req, Response &res) {
res.set_file_content("./path/to/content.html");
});
svr.Get("/content", [&](const Request &req, Response &res) {
res.set_file_content("./path/to/content", "text/html");
});
```
### 'Expect: 100-continue' handler
By default, the server sends a `100 Continue` response for an `Expect: 100-continue` header.
```cpp
// Send a '417 Expectation Failed' response.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return StatusCode::ExpectationFailed_417;
});
```
```cpp
// Send a final status without reading the message body.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return res.status = StatusCode::Unauthorized_401;
});
```
### Keep-Alive connection
```cpp
svr.set_keep_alive_max_count(2); // Default is 100
svr.set_keep_alive_timeout(10); // Default is 5
```
### Timeout
```c++
svr.set_read_timeout(5, 0); // 5 seconds
svr.set_write_timeout(5, 0); // 5 seconds
svr.set_idle_interval(0, 100000); // 100 milliseconds
```
### Set maximum payload length for reading a request body
```c++
svr.set_payload_max_length(1024 * 1024 * 512); // 512MB
```
> [!NOTE]
> When the request body content type is 'www-form-urlencoded', the actual payload length shouldn't exceed `CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH`.
### Server-Sent Events
Please see [Server example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssesvr.cc) and [Client example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssecli.cc).
### Default thread pool support
`ThreadPool` is used as the **default** task queue, with dynamic scaling support. By default, it maintains a base thread count of 8 or `std::thread::hardware_concurrency() - 1` (whichever is greater), and can scale up to 4x that count under load. You can change these with `CPPHTTPLIB_THREAD_POOL_COUNT` and `CPPHTTPLIB_THREAD_POOL_MAX_COUNT`.
When all threads are busy and a new task arrives, a temporary thread is spawned (up to the maximum). When a dynamic thread finishes its task and the queue is empty, or after an idle timeout, it exits automatically. The idle timeout defaults to 3 seconds, configurable via `CPPHTTPLIB_THREAD_POOL_IDLE_TIMEOUT`.
If you want to set the thread counts at runtime:
```cpp
svr.new_task_queue = [] { return new ThreadPool(/*base_threads=*/8, /*max_threads=*/64); };
```
#### Max queued requests
You can also provide an optional parameter to limit the maximum number
of pending requests, i.e. requests `accept()`ed by the listener but
still waiting to be serviced by worker threads.
```cpp
svr.new_task_queue = [] { return new ThreadPool(/*base_threads=*/12, /*max_threads=*/0, /*max_queued_requests=*/18); };
```
Default limit is 0 (unlimited). Once the limit is reached, the listener
will shutdown the client connection.
### Override the default thread pool with yours
You can supply your own thread pool implementation according to your need.
```cpp
class YourThreadPoolTaskQueue : public TaskQueue {
public:
YourThreadPoolTaskQueue(size_t n) {
pool_.start_with_thread_count(n);
}
virtual bool enqueue(std::function<void()> fn) override {
/* Return true if the task was actually enqueued, or false
* if the caller must drop the corresponding connection. */
return pool_.enqueue(fn);
}
virtual void shutdown() override {
pool_.shutdown_gracefully();
}
private:
YourThreadPool pool_;
};
svr.new_task_queue = [] {
return new YourThreadPoolTaskQueue(12);
};
```
## Client
```c++
#include <httplib.h>
#include <iostream>
int main(void)
{
httplib::Client cli("localhost", 1234);
if (auto res = cli.Get("/hi")) {
if (res->status == StatusCode::OK_200) {
std::cout << res->body << std::endl;
}
} else {
auto err = res.error();
std::cout << "HTTP error: " << httplib::to_string(err) << std::endl;
}
}
```
> [!TIP]
> Constructor with scheme-host-port string is now supported!
```c++
httplib::Client cli("localhost");
httplib::Client cli("localhost:8080");
httplib::Client cli("http://localhost");
httplib::Client cli("http://localhost:8080");
httplib::Client cli("https://localhost");
httplib::SSLClient cli("localhost");
```
### Error code
Here is the list of errors from `Result::error()`.
```c++
enum class Error {
Success = 0,
Unknown,
Connection,
BindIPAddress,
Read,
Write,
ExceedRedirectCount,
Canceled,
SSLConnection,
SSLLoadingCerts,
SSLServerVerification,
SSLServerHostnameVerification,
UnsupportedMultipartBoundaryChars,
Compression,
ConnectionTimeout,
ProxyConnection,
ConnectionClosed,
Timeout,
ResourceExhaustion,
TooManyFormDataFiles,
ExceedMaxPayloadSize,
ExceedUriMaxLength,
ExceedMaxSocketDescriptorCount,
InvalidRequestLine,
InvalidHTTPMethod,
InvalidHTTPVersion,
InvalidHeaders,
MultipartParsing,
OpenFile,
Listen,
GetSockName,
UnsupportedAddressFamily,
HTTPParsing,
InvalidRangeHeader,
};
```
### Client Logging
#### Access Logging
```cpp
cli.set_logger([](const httplib::Request& req, const httplib::Response& res) {
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start_time).count();
std::cout << "✓ " << req.method << " " << req.path
<< " -> " << res.status << " (" << res.body.size() << " bytes, "
<< duration << "ms)" << std::endl;
});
```
#### Error Logging
```cpp
cli.set_error_logger([](const httplib::Error& err, const httplib::Request* req) {
std::cerr << "✗ ";
if (req) {
std::cerr << req->method << " " << req->path << " ";
}
std::cerr << "failed: " << httplib::to_string(err);
// Add specific guidance based on error type
switch (err) {
case httplib::Error::Connection:
std::cerr << " (verify server is running and reachable)";
break;
case httplib::Error::SSLConnection:
std::cerr << " (check SSL certificate and TLS configuration)";
break;
case httplib::Error::ConnectionTimeout:
std::cerr << " (increase timeout or check network latency)";
break;
case httplib::Error::Read:
std::cerr << " (server may have closed connection prematurely)";
break;
default:
break;
}
std::cerr << std::endl;
});
```
### GET with HTTP headers
```c++
httplib::Headers headers = {
{ "Hello", "World!" }
};
auto res = cli.Get("/hi", headers);
```
or
```c++
auto res = cli.Get("/hi", {{"Hello", "World!"}});
```
or
```c++
cli.set_default_headers({
{ "Hello", "World!" }
});
auto res = cli.Get("/hi");
```
### POST
```c++
res = cli.Post("/post", "text", "text/plain");
res = cli.Post("/person", "name=john1¬e=coder", "application/x-www-form-urlencoded");
```
### POST with parameters
```c++
httplib::Params params;
params.emplace("name", "john");
params.emplace("note", "coder");
auto res = cli.Post("/post", params);
```
or
```c++
httplib::Params params{
{ "name", "john" },
{ "note", "coder" }
};
auto res = cli.Post("/post", params);
```
### POST with Multipart Form Data
```c++
httplib::UploadFormDataItems items = {
{ "text1", "text default", "", "" },
{ "text2", "aωb", "", "" },
{ "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
{ "file2", "{\n \"world\", true\n}\n", "world.json", "application/json" },
{ "file3", "", "", "application/octet-stream" },
};
auto res = cli.Post("/multipart", items);
```
To upload files from disk without loading them entirely into memory, use `make_file_provider`. The file is sent with chunked transfer encoding.
```cpp
httplib::FormDataProviderItems providers = {
httplib::make_file_provider("file1", "/path/to/large.bin", "large.bin", "application/octet-stream"),
httplib::make_file_provider("avatar", "/path/to/photo.jpg", "photo.jpg", "image/jpeg"),
};
auto res = cli.Post("/upload", {}, {}, providers);
```
### POST with a file body
To POST a file as a raw binary body with `Content-Length`, use `make_file_body`.
```cpp
auto [size, provider] = httplib::make_file_body("/path/to/data.bin");
auto res = cli.Post("/upload", size, provider, "application/octet-stream");
```
### PUT
```c++
res = cli.Put("/resource/foo", "text", "text/plain");
```
### PATCH
```c++
res = cli.Patch("/resource/foo", "text", "text/plain");
```
### DELETE
```c++
res = cli.Delete("/resource/foo");
```
### OPTIONS
```c++
res = cli.Options("*");
res = cli.Options("/resource/foo");
```
### Timeout
```c++
cli.set_connection_timeout(0, 300000); // 300 milliseconds
cli.set_read_timeout(5, 0); // 5 seconds
cli.set_write_timeout(5, 0); // 5 seconds
// This method works the same as curl's `--max-time` option
cli.set_max_timeout(5000); // 5 seconds
```
### Set maximum payload length for reading a response body
```c++
cli.set_payload_max_length(1024 * 1024 * 512); // 512MB
```
### Receive content with a content receiver
```c++
std::string body;
auto res = cli.Get("/large-data",
[&](const char *data, size_t data_length) {
body.append(data, data_length);
return true;
});
```
```cpp
std::string body;
auto res = cli.Get(
"/stream", Headers(),
[&](const Response &response) {
EXPECT_EQ(StatusCode::OK_200, response.status);
return true; // return 'false' if you want to cancel the request.
},
[&](const char *data, size_t data_length) {
body.append(data, data_length);
return true; // return 'false' if you want to cancel the request.
});
```
### Send content with a content provider
```cpp
std::string body = ...;
auto res = cli.Post(
"/stream", body.size(),
[](size_t offset, size_t length, DataSink &sink) {
sink.write(body.data() + offset, length);
return true; // return 'false' if you want to cancel the request.
},
"text/plain");
```
### Chunked transfer encoding
```cpp
auto res = cli.Post(
"/stream",
[](size_t offset, DataSink &sink) {
sink.os << "chunked data 1";
sink.os << "chunked data 2";
sink.os << "chunked data 3";
sink.done();
return true; // return 'false' if you want to cancel the request.
},
"text/plain");
```
### With Progress Callback
```cpp
httplib::Client cli(url, port);
// prints: 0 / 000 bytes => 50% complete
auto res = cli.Get("/", [](size_t len, size_t total) {
printf("%lld / %lld bytes => %d%% complete\n",
len, total,
(int)(len*100/total));
return true; // return 'false' if you want to cancel the request.
}
);
```

### Authentication
```cpp
// Basic Authentication
cli.set_basic_auth("user", "pass");
// Digest Authentication
cli.set_digest_auth("user", "pass");
// Bearer Token Authentication
cli.set_bearer_token_auth("token");
```
> [!NOTE]
> OpenSSL is required for Digest Authentication.
### Proxy server support
```cpp
cli.set_proxy("host", port);
// Basic Authentication
cli.set_proxy_basic_auth("user", "pass");
// Digest Authentication
cli.set_proxy_digest_auth("user", "pass");
// Bearer Token Authentication
cli.set_proxy_bearer_token_auth("pass");
```
> [!NOTE]
> OpenSSL is required for Digest Authentication.
### Range
```cpp
httplib::Client cli("httpcan.org");
auto res = cli.Get("/range/32", {
httplib::make_range_header({{1, 10}}) // 'Range: bytes=1-10'
});
// res->status should be 206.
// res->body should be "bcdefghijk".
```
```cpp
httplib::make_range_header({{1, 10}, {20, -1}}) // 'Range: bytes=1-10, 20-'
httplib::make_range_header({{100, 199}, {500, 599}}) // 'Range: bytes=100-199, 500-599'
httplib::make_range_header({{0, 0}, {-1, 1}}) // 'Range: bytes=0-0, -1'
```
### Keep-Alive connection
```cpp
httplib::Client cli("localhost", 1234);
cli.Get("/hello"); // with "Connection: close"
cli.set_keep_alive(true);
cli.Get("/world");
cli.set_keep_alive(false);
cli.Get("/last-request"); // with "Connection: close"
```
### Redirect
```cpp
httplib::Client cli("yahoo.com");
auto res = cli.Get("/");
res->status; // 301
cli.set_follow_location(true);
res = cli.Get("/");
res->status; // 200
```
### Use a specific network interface
> [!NOTE]
> This feature is not available on Windows, yet.
```cpp
cli.set_interface("eth0"); // Interface name, IP address or host name
```
### Automatic Path Encoding
The client automatically encodes special characters in URL paths by default:
```cpp
httplib::Client cli("https://example.com");
// Automatic path encoding (default behavior)
cli.set_path_encode(true);
auto res = cli.Get("/path with spaces/file.txt"); // Automatically encodes spaces
// Disable automatic path encoding
cli.set_path_encode(false);
auto res = cli.Get("/already%20encoded/path"); // Use pre-encoded paths
```
- `set_path_encode(bool on)` - Controls automatic encoding of special characters in URL paths
- `true` (default): Automatically encodes spaces, plus signs, newlines, and other special characters
- `false`: Sends paths as-is without encoding (useful for pre-encoded URLs)
### Performance Note for Local Connections
> [!WARNING]
> On Windows systems with improperly configured IPv6 settings, using "localhost" as the hostname may cause significant connection delays (up to 2 seconds per request) due to DNS resolution issues. This affects both client and server operations. For better performance when connecting to local services, use "127.0.0.1" instead of "localhost".
>
> See: https://github.com/yhirose/cpp-httplib/issues/366#issuecomment-593004264
```cpp
// May be slower on Windows due to DNS resolution delays
httplib::Client cli("localhost", 8080);
httplib::Server svr;
svr.listen("localhost", 8080);
// Faster alternative for local connections
httplib::Client cli("127.0.0.1", 8080);
httplib::Server svr;
svr.listen("127.0.0.1", 8080);
```
## Payload Limit
The maximum payload body size is limited to 100MB by default for both server and client. You can change it with `set_payload_max_length()` or by defining `CPPHTTPLIB_PAYLOAD_MAX_LENGTH` at compile time. Setting it to `0` disables the limit entirely.
## Compression
The server can apply compression to the following MIME type contents:
- all text types except text/event-stream
- image/svg+xml
- application/javascript
- application/json
- application/xml
- application/protobuf
- application/xhtml+xml
### Zlib Support
'gzip' compression is available with `CPPHTTPLIB_ZLIB_SUPPORT`. `libz` should be linked.
### Brotli Support
Brotli compression is available with `CPPHTTPLIB_BROTLI_SUPPORT`. Necessary libraries should be linked.
Please see https://github.com/google/brotli for more detail.
### Zstd Support
Zstd compression is available with `CPPHTTPLIB_ZSTD_SUPPORT`. Necessary libraries should be linked.
Please see https://github.com/facebook/zstd for more detail.
### Default `Accept-Encoding` value
The default `Accept-Encoding` value contains all possible compression types. So, the following two examples are same.
```c++
res = cli.Get("/resource/foo");
res = cli.Get("/resource/foo", {{"Accept-Encoding", "br, gzip, deflate, zstd"}});
```
If we don't want a response without compression, we have to set `Accept-Encoding` to an empty string. This behavior is similar to curl.
```c++
res = cli.Get("/resource/foo", {{"Accept-Encoding", ""}});
```
### Compress request body on client
```c++
cli.set_compress(true);
res = cli.Post("/resource/foo", "...", "text/plain");
```
### Compress response body on client
```c++
cli.set_decompress(false);
res = cli.Get("/resource/foo");
res->body; // Compressed data
```
Unix Domain Socket Support
--------------------------
Unix Domain Socket support is available on Linux and macOS.
```c++
// Server
httplib::Server svr;
svr.set_address_family(AF_UNIX).listen("./my-socket.sock", 80);
// Client
httplib::Client cli("./my-socket.sock");
cli.set_address_family(AF_UNIX);
```
"my-socket.sock" can be a relative path or an absolute path. Your application must have the appropriate permissions for the path. You can also use an abstract socket address on Linux. To use an abstract socket address, prepend a null byte ('\x00') to the path.
This library automatically sets the Host header to "localhost" for Unix socket connections, similar to curl's behavior:
URI Encoding/Decoding Utilities
-------------------------------
cpp-httplib provides utility functions for URI encoding and decoding:
```cpp
#include <httplib.h>
std::string url = "https://example.com/search?q=hello world";
std::string encoded = httplib::encode_uri(url);
std::string decoded = httplib::decode_uri(encoded);
std::string param = "hello world";
std::string encoded_component = httplib::encode_uri_component(param);
std::string decoded_component = httplib::decode_uri_component(encoded_component);
```
### Functions
- `encode_uri(const std::string &value)` - Encodes a full URI, preserving reserved characters like `://`, `?`, `&`, `=`
- `decode_uri(const std::string &value)` - Decodes a URI-encoded string
- `encode_uri_component(const std::string &value)` - Encodes a URI component (query parameter, path segment), encoding all reserved characters
- `decode_uri_component(const std::string &value)` - Decodes a URI component
Use `encode_uri()` for full URLs and `encode_uri_component()` for individual query parameters or path segments.
## Stream API
Process large responses without loading everything into memory.
```c++
httplib::Client cli("localhost", 8080);
cli.set_follow_location(true);
...
auto result = httplib::stream::Get(cli, "/large-file");
if (result) {
while (result.next()) {
process(result.data(), result.size()); // Process each chunk as it arrives
}
}
// Or read the entire body at once
auto result2 = httplib::stream::Get(cli, "/file");
if (result2) {
std::string body = result2.read_all();
}
```
All HTTP methods are supported: `stream::Get`, `Post`, `Put`, `Patch`, `Delete`, `Head`, `Options`.
See [README-stream.md](README-stream.md) for more details.
## SSE Client
```cpp
#include <httplib.h>
int main() {
httplib::Client cli("http://localhost:8080");
httplib::sse::SSEClient sse(cli, "/events");
sse.on_message([](const httplib::sse::SSEMessage &msg) {
std::cout << "Event: " << msg.event << std::endl;
std::cout << "Data: " << msg.data << std::endl;
});
sse.start(); // Blocking, with auto-reconnect
return 0;
}
```
See [README-sse.md](README-sse.md) for more details.
## WebSocket
```cpp
// Server
httplib::Server svr;
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) {
httplib::ws::Message msg;
while (ws.read(msg)) {
if (msg.is_text()) {
ws.send("Echo: " + msg.data);
}
}
});
svr.listen("localhost", 8080);
```
```cpp
// Client
httplib::ws::WebSocketClient ws("ws://localhost:8080/ws");
if (ws.connect()) {
ws.send("Hello, WebSocket!");
std::string msg;
if (ws.read(msg)) {
std::cout << "Received: " << msg << std::endl;
}
ws.close();
}
```
SSL is also supported via `wss://` scheme (e.g. `WebSocketClient("wss://example.com/ws")`). Subprotocol negotiation (`Sec-WebSocket-Protocol`) is supported via `SubProtocolSelector` callback.
> **Note:** WebSocket connections occupy a thread for their entire lifetime. If you plan to handle many simultaneous WebSocket connections, consider using a dynamic thread pool: `svr.new_task_queue = [] { return new ThreadPool(8, 64); };`
See [README-websocket.md](README-websocket.md) for more details.
## Split httplib.h into .h and .cc
```console
$ ./split.py -h
usage: split.py [-h] [-e EXTENSION] [-o OUT]
This script splits httplib.h into .h and .cc parts.
optional arguments:
-h, --help show this help message and exit
-e EXTENSION, --extension EXTENSION
extension of the implementation file (default: cc)
-o OUT, --out OUT where to write the files (default: out)
$ ./split.py
Wrote out/httplib.h and out/httplib.cc
```
## Dockerfile for Static HTTP Server
Dockerfile for static HTTP server is available. Port number of this HTTP server is 80, and it serves static files from `/html` directory in the container.
```bash
> docker build -t cpp-httplib-server .
...
> docker run --rm -it -p 8080:80 -v ./docker/html:/html cpp-httplib-server
Serving HTTP on 0.0.0.0 port 80 ...
192.168.65.1 - - [31/Aug/2024:21:33:56 +0000] "GET / HTTP/1.1" 200 599 "-" "curl/8.7.1"
192.168.65.1 - - [31/Aug/2024:21:34:26 +0000] "GET / HTTP/1.1" 200 599 "-" "Mozilla/5.0 ..."
192.168.65.1 - - [31/Aug/2024:21:34:26 +0000] "GET /favicon.ico HTTP/1.1" 404 152 "-" "Mozilla/5.0 ..."
```
From Docker Hub
```bash
> docker run --rm -it -p 8080:80 -v ./docker/html:/html yhirose4dockerhub/cpp-httplib-server
Serving HTTP on 0.0.0.0 port 80 ...
192.168.65.1 - - [31/Aug/2024:21:33:56 +0000] "GET / HTTP/1.1" 200 599 "-" "curl/8.7.1"
192.168.65.1 - - [31/Aug/2024:21:34:26 +0000] "GET / HTTP/1.1" 200 599 "-" "Mozilla/5.0 ..."
192.168.65.1 - - [31/Aug/2024:21:34:26 +0000] "GET /favicon.ico HTTP/1.1" 404 152 "-" "Mozilla/5.0 ..."
```
NOTE
----
### Regular Expression Stack Overflow
> [!CAUTION]
> When using complex regex patterns in route handlers, be aware that certain patterns may cause stack overflow during pattern matching. This is a known issue with `std::regex` implementations and affects the `dispatch_request()` method.
>
> ```cpp
> // This pattern can cause stack overflow with large input
> svr.Get(".*", handler);
> ```
>
> Consider using simpler patterns or path parameters to avoid this issue:
>
> ```cpp
> // Safer alternatives
> svr.Get("/users/:id", handler); // Path parameters
> svr.Get(R"(/api/v\d+/.*)", handler); // More specific patterns
> ```
### g++
g++ 4.8 and below cannot build this library since `<regex>` in the versions are [broken](https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions).
### Windows
Include `httplib.h` before `Windows.h` or include `Windows.h` by defining `WIN32_LEAN_AND_MEAN` beforehand.
```cpp
#include <httplib.h>
#include <Windows.h>
```
```cpp
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <httplib.h>
```
> [!NOTE]
> cpp-httplib officially supports only the latest Visual Studio. It might work with former versions of Visual Studio, but I can no longer verify it. Pull requests are always welcome for the older versions of Visual Studio unless they break the C++11 conformance.
> [!NOTE]
> Windows 8 or lower, Visual Studio 2015 or lower, and Cygwin and MSYS2 including MinGW are neither supported nor tested.
## License
MIT license (© 2026 Yuji Hirose)
## Special Thanks To
[These folks](https://github.com/yhirose/cpp-httplib/graphs/contributors) made great contributions to polish this library to totally another level from a simple toy!
================================================
FILE: benchmark/Makefile
================================================
CXXFLAGS = -O2 -I..
CPPHTTPLIB_CXXFLAGS = -std=c++11
CROW_CXXFLAGS = -std=c++17
CPPHTTPLIB_FLAGS = -DCPPHTTPLIB_THREAD_POOL_COUNT=16
BENCH = bombardier -c 10 -d 5s localhost:8080
MONITOR = ali http://localhost:8080
# cpp-httplib
bench: server
@echo "--------------------\n cpp-httplib latest\n--------------------\n"
@./server & export PID=$$!; $(BENCH); kill $${PID}
@echo ""
monitor: server
@./server & export PID=$$!; $(MONITOR); kill $${PID}
run : server
@./server
server : cpp-httplib/main.cpp ../httplib.h
@g++ -o $@ $(CXXFLAGS) $(CPPHTTPLIB_CXXFLAGS) $(CPPHTTPLIB_FLAGS) cpp-httplib/main.cpp
# crow
bench-crow: server-crow
@echo "-------------\n Crow v1.3.1\n-------------\n"
@./server-crow & export PID=$$!; $(BENCH); kill $${PID}
@echo ""
monitor-crow: server-crow
@./server-crow & export PID=$$!; $(MONITOR); kill $${PID}
run-crow : server-crow
@./server-crow
server-crow : crow/main.cpp crow/crow_all.h
@g++ -o $@ $(CXXFLAGS) $(CROW_CXXFLAGS) crow/main.cpp
# misc
build: server server-crow
bench-all: bench-crow bench
issue:
bombardier -c 10 -d 30s localhost:8080
clean:
rm -rf server*
================================================
FILE: benchmark/cpp-httplib/main.cpp
================================================
#include "httplib.h"
using namespace httplib;
int main() {
Server svr;
svr.Get("/", [](const Request &, Response &res) {
res.set_content("Hello World!", "text/plain");
});
svr.listen("0.0.0.0", 8080);
}
================================================
FILE: benchmark/crow/crow_all.h
================================================
// SPDX-License-Identifier: BSD-3-Clause AND ISC AND MIT
/*BSD 3-Clause License
Copyright (c) 2014-2017, ipkn
2020-2026, CrowCpp
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Crow logo and other graphic material (excluding third party logos) used are
under exclusive Copyright (c) 2021-2022, Farook Al-Sammarraie (The-EDev), All
rights reserved.
*/
#pragma once
#ifdef CROW_ENABLE_COMPRESSION
#include <string>
#include <zlib.h>
// http://zlib.net/manual.html
namespace crow // NOTE: Already documented in "crow/app.h"
{
namespace compression {
// Values used in the 'windowBits' parameter for deflateInit2.
enum algorithm {
// 15 is the default value for deflate
DEFLATE = 15,
// windowBits can also be greater than 15 for optional gzip encoding.
// Add 16 to windowBits to write a simple gzip header and trailer around the
// compressed data instead of a zlib wrapper.
GZIP = 15 | 16,
};
inline std::string compress_string(std::string const &str, algorithm algo) {
std::string compressed_str;
z_stream stream{};
// Initialize with the default values
if (::deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, algo, 8,
Z_DEFAULT_STRATEGY) == Z_OK) {
char buffer[8192];
stream.avail_in = str.size();
// zlib does not take a const pointer. The data is not altered.
stream.next_in =
const_cast<Bytef *>(reinterpret_cast<const Bytef *>(str.c_str()));
int code = Z_OK;
do {
stream.avail_out = sizeof(buffer);
stream.next_out = reinterpret_cast<Bytef *>(&buffer[0]);
code = ::deflate(&stream, Z_FINISH);
// Successful and non-fatal error code returned by deflate when used with
// Z_FINISH flush
if (code == Z_OK || code == Z_STREAM_END) {
std::copy(&buffer[0], &buffer[sizeof(buffer) - stream.avail_out],
std::back_inserter(compressed_str));
}
} while (code == Z_OK);
if (code != Z_STREAM_END) compressed_str.clear();
::deflateEnd(&stream);
}
return compressed_str;
}
inline std::string decompress_string(std::string const &deflated_string) {
std::string inflated_string;
Bytef tmp[8192];
z_stream zstream{};
zstream.avail_in = deflated_string.size();
// Nasty const_cast but zlib won't alter its contents
zstream.next_in = const_cast<Bytef *>(
reinterpret_cast<Bytef const *>(deflated_string.c_str()));
// Initialize with automatic header detection, for gzip support
if (::inflateInit2(&zstream, MAX_WBITS | 32) == Z_OK) {
do {
zstream.avail_out = sizeof(tmp);
zstream.next_out = &tmp[0];
auto ret = ::inflate(&zstream, Z_NO_FLUSH);
if (ret == Z_OK || ret == Z_STREAM_END) {
std::copy(&tmp[0], &tmp[sizeof(tmp) - zstream.avail_out],
std::back_inserter(inflated_string));
} else {
// Something went wrong with inflate; make sure we return an empty
// string
inflated_string.clear();
break;
}
} while (zstream.avail_out == 0);
// Free zlib's internal memory
::inflateEnd(&zstream);
}
return inflated_string;
}
} // namespace compression
} // namespace crow
#endif
namespace crow {
constexpr const char VERSION[] = "master";
}
/*
* SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1
*
* Copyright (c) 2012-22 SAURAV MOHAPATRA <mohaps@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* \file TinySHA1.hpp
* \author SAURAV MOHAPATRA <mohaps@gmail.com>
* \date 2012-22
* \brief TinySHA1 - a header only implementation of the SHA1 algorithm in C++.
* Based on the implementation in boost::uuid::details.
*
* In this file are defined:
* - sha1::SHA1
*/
#ifndef _TINY_SHA1_HPP_
#define _TINY_SHA1_HPP_
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdint.h>
/**
* \namespace sha1
* \brief Here is defined the SHA1 class
*/
namespace sha1 {
/**
* \class SHA1
* \brief A tiny SHA1 algorithm implementation used internally in the
* Crow server (specifically in crow/websocket.h).
*/
class SHA1 {
public:
typedef uint32_t digest32_t[5];
typedef uint8_t digest8_t[20];
inline static uint32_t LeftRotate(uint32_t value, size_t count) {
return (value << count) ^ (value >> (32 - count));
}
SHA1() { reset(); }
virtual ~SHA1() {}
SHA1(const SHA1 &s) { *this = s; }
const SHA1 &operator=(const SHA1 &s) {
memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
memcpy(m_block, s.m_block, 64);
m_blockByteIndex = s.m_blockByteIndex;
m_byteCount = s.m_byteCount;
return *this;
}
SHA1 &reset() {
m_digest[0] = 0x67452301;
m_digest[1] = 0xEFCDAB89;
m_digest[2] = 0x98BADCFE;
m_digest[3] = 0x10325476;
m_digest[4] = 0xC3D2E1F0;
m_blockByteIndex = 0;
m_byteCount = 0;
return *this;
}
SHA1 &processByte(uint8_t octet) {
this->m_block[this->m_blockByteIndex++] = octet;
++this->m_byteCount;
if (m_blockByteIndex == 64) {
this->m_blockByteIndex = 0;
processBlock();
}
return *this;
}
SHA1 &processBlock(const void *const start, const void *const end) {
const uint8_t *begin = static_cast<const uint8_t *>(start);
const uint8_t *finish = static_cast<const uint8_t *>(end);
while (begin != finish) {
processByte(*begin);
begin++;
}
return *this;
}
SHA1 &processBytes(const void *const data, size_t len) {
const uint8_t *block = static_cast<const uint8_t *>(data);
processBlock(block, block + len);
return *this;
}
const uint32_t *getDigest(digest32_t digest) {
size_t bitCount = this->m_byteCount * 8;
processByte(0x80);
if (this->m_blockByteIndex > 56) {
while (m_blockByteIndex != 0) {
processByte(0);
}
while (m_blockByteIndex < 56) {
processByte(0);
}
} else {
while (m_blockByteIndex < 56) {
processByte(0);
}
}
processByte(0);
processByte(0);
processByte(0);
processByte(0);
processByte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
processByte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
processByte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
processByte(static_cast<unsigned char>((bitCount) & 0xFF));
memcpy(digest, m_digest, 5 * sizeof(uint32_t));
return digest;
}
const uint8_t *getDigestBytes(digest8_t digest) {
digest32_t d32;
getDigest(d32);
size_t di = 0;
digest[di++] = ((d32[0] >> 24) & 0xFF);
digest[di++] = ((d32[0] >> 16) & 0xFF);
digest[di++] = ((d32[0] >> 8) & 0xFF);
digest[di++] = ((d32[0]) & 0xFF);
digest[di++] = ((d32[1] >> 24) & 0xFF);
digest[di++] = ((d32[1] >> 16) & 0xFF);
digest[di++] = ((d32[1] >> 8) & 0xFF);
digest[di++] = ((d32[1]) & 0xFF);
digest[di++] = ((d32[2] >> 24) & 0xFF);
digest[di++] = ((d32[2] >> 16) & 0xFF);
digest[di++] = ((d32[2] >> 8) & 0xFF);
digest[di++] = ((d32[2]) & 0xFF);
digest[di++] = ((d32[3] >> 24) & 0xFF);
digest[di++] = ((d32[3] >> 16) & 0xFF);
digest[di++] = ((d32[3] >> 8) & 0xFF);
digest[di++] = ((d32[3]) & 0xFF);
digest[di++] = ((d32[4] >> 24) & 0xFF);
digest[di++] = ((d32[4] >> 16) & 0xFF);
digest[di++] = ((d32[4] >> 8) & 0xFF);
digest[di++] = ((d32[4]) & 0xFF);
return digest;
}
protected:
void processBlock() {
uint32_t w[80];
for (size_t i = 0; i < 16; i++) {
w[i] = (m_block[i * 4 + 0] << 24);
w[i] |= (m_block[i * 4 + 1] << 16);
w[i] |= (m_block[i * 4 + 2] << 8);
w[i] |= (m_block[i * 4 + 3]);
}
for (size_t i = 16; i < 80; i++) {
w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
}
uint32_t a = m_digest[0];
uint32_t b = m_digest[1];
uint32_t c = m_digest[2];
uint32_t d = m_digest[3];
uint32_t e = m_digest[4];
for (std::size_t i = 0; i < 80; ++i) {
uint32_t f = 0;
uint32_t k = 0;
if (i < 20) {
f = (b & c) | (~b & d);
k = 0x5A827999;
} else if (i < 40) {
f = b ^ c ^ d;
k = 0x6ED9EBA1;
} else if (i < 60) {
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
} else {
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
e = d;
d = c;
c = LeftRotate(b, 30);
b = a;
a = temp;
}
m_digest[0] += a;
m_digest[1] += b;
m_digest[2] += c;
m_digest[3] += d;
m_digest[4] += e;
}
private:
digest32_t m_digest;
uint8_t m_block[64];
size_t m_blockByteIndex;
size_t m_byteCount;
};
} // namespace sha1
#endif
#include <iostream>
#include <memory>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <vector>
namespace crow {
// ----------------------------------------------------------------------------
// qs_parse (modified)
// https://github.com/bartgrantham/qs_parse
// ----------------------------------------------------------------------------
/* Similar to strncmp, but handles URL-encoding for either string */
int qs_strncmp(const char *s, const char *qs, size_t n);
/* Finds the beginning of each key/value pair and stores a pointer in qs_kv.
* Also decodes the value portion of the k/v pair *in-place*. In a future
* enhancement it will also have a compile-time option of sorting qs_kv
* alphabetically by key. */
size_t qs_parse(char *qs, char *qs_kv[], size_t qs_kv_size, bool parse_url);
/* Used by qs_parse to decode the value portion of a k/v pair */
int qs_decode(char *qs);
/* Looks up the value according to the key on a pre-processed query string
* A future enhancement will be a compile-time option to look up the key
* in a pre-sorted qs_kv array via a binary search. */
// char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size);
char *qs_k2v(const char *key, char *const *qs_kv, size_t qs_kv_size, int nth);
/* Non-destructive lookup of value, based on key. User provides the
* destinaton string and length. */
char *qs_scanvalue(const char *key, const char *qs, char *val, size_t val_len);
// TODO: implement sorting of the qs_kv array; for now ensure it's not compiled
#undef _qsSORTING
// isxdigit _is_ available in <ctype.h>, but let's avoid another header instead
#define CROW_QS_ISHEX(x) \
((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') || \
((x) >= 'a' && (x) <= 'f')) \
? 1 \
: 0)
#define CROW_QS_HEX2DEC(x) \
(((x) >= '0' && (x) <= '9') ? (x) - 48 \
: ((x) >= 'A' && (x) <= 'F') ? (x) - 55 \
: ((x) >= 'a' && (x) <= 'f') ? (x) - 87 \
: 0)
#define CROW_QS_ISQSCHR(x) \
((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1)
inline int qs_strncmp(const char *s, const char *qs, size_t n) {
unsigned char u1, u2, unyb, lnyb;
while (n-- > 0) {
u1 = static_cast<unsigned char>(*s++);
u2 = static_cast<unsigned char>(*qs++);
if (!CROW_QS_ISQSCHR(u1)) { u1 = '\0'; }
if (!CROW_QS_ISQSCHR(u2)) { u2 = '\0'; }
if (u1 == '+') { u1 = ' '; }
if (u1 == '%') // easier/safer than scanf
{
unyb = static_cast<unsigned char>(*s++);
lnyb = static_cast<unsigned char>(*s++);
if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb))
u1 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb);
else
u1 = '\0';
}
if (u2 == '+') { u2 = ' '; }
if (u2 == '%') // easier/safer than scanf
{
unyb = static_cast<unsigned char>(*qs++);
lnyb = static_cast<unsigned char>(*qs++);
if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb))
u2 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb);
else
u2 = '\0';
}
if (u1 != u2) return u1 - u2;
if (u1 == '\0') return 0;
}
if (CROW_QS_ISQSCHR(*qs))
return -1;
else
return 0;
}
inline size_t qs_parse(char *qs, char *qs_kv[], size_t qs_kv_size,
bool parse_url = true) {
size_t i, j;
char *substr_ptr;
for (i = 0; i < qs_kv_size; i++)
qs_kv[i] = NULL;
// find the beginning of the k/v substrings or the fragment
substr_ptr = parse_url ? qs + strcspn(qs, "?#") : qs;
if (parse_url) {
if (substr_ptr[0] != '\0')
substr_ptr++;
else
return 0; // no query or fragment
}
i = 0;
while (i < qs_kv_size) {
qs_kv[i] = substr_ptr;
j = strcspn(substr_ptr, "&");
if (substr_ptr[j] == '\0') {
i++;
break;
} // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
substr_ptr += j + 1;
i++;
}
// we only decode the values in place, the keys could have '='s in them
// which will hose our ability to distinguish keys from values later
for (j = 0; j < i; j++) {
substr_ptr = qs_kv[j] + strcspn(qs_kv[j], "=&#");
if (substr_ptr[0] == '&' ||
substr_ptr[0] == '\0') // blank value: skip decoding
substr_ptr[0] = '\0';
else
qs_decode(++substr_ptr);
}
#ifdef _qsSORTING
// TODO: qsort qs_kv, using qs_strncmp() for the comparison
#endif
return i;
}
inline int qs_decode(char *qs) {
int i = 0, j = 0;
while (CROW_QS_ISQSCHR(qs[j])) {
if (qs[j] == '+') {
qs[i] = ' ';
} else if (qs[j] == '%') // easier/safer than scanf
{
if (!CROW_QS_ISHEX(qs[j + 1]) || !CROW_QS_ISHEX(qs[j + 2])) {
qs[i] = '\0';
return i;
}
qs[i] = (CROW_QS_HEX2DEC(qs[j + 1]) * 16) + CROW_QS_HEX2DEC(qs[j + 2]);
j += 2;
} else {
qs[i] = qs[j];
}
i++;
j++;
}
qs[i] = '\0';
return i;
}
inline char *qs_k2v(const char *key, char *const *qs_kv, size_t qs_kv_size,
int nth = 0) {
size_t i;
size_t key_len, skip;
key_len = strlen(key);
#ifdef _qsSORTING
// TODO: binary search for key in the sorted qs_kv
#else // _qsSORTING
for (i = 0; i < qs_kv_size; i++) {
// we rely on the unambiguous '=' to find the value in our k/v pair
if (qs_strncmp(key, qs_kv[i], key_len) == 0) {
skip = strcspn(qs_kv[i], "=");
if (qs_kv[i][skip] == '=') skip++;
// return (zero-char value) ? ptr to trailing '\0' : ptr to value
if (nth == 0)
return qs_kv[i] + skip;
else
--nth;
}
}
#endif // _qsSORTING
return nullptr;
}
inline std::unique_ptr<std::pair<std::string, std::string>>
qs_dict_name2kv(const char *dict_name, char *const *qs_kv, size_t qs_kv_size,
int nth = 0) {
size_t i;
size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close;
name_len = strlen(dict_name);
#ifdef _qsSORTING
// TODO: binary search for key in the sorted qs_kv
#else // _qsSORTING
for (i = 0; i < qs_kv_size; i++) {
if (strncmp(dict_name, qs_kv[i], name_len) == 0) {
skip_to_eq = strcspn(qs_kv[i], "=");
if (qs_kv[i][skip_to_eq] == '=') skip_to_eq++;
skip_to_brace_open = strcspn(qs_kv[i], "[");
if (qs_kv[i][skip_to_brace_open] == '[') skip_to_brace_open++;
skip_to_brace_close = strcspn(qs_kv[i], "]");
if (skip_to_brace_open <= skip_to_brace_close && skip_to_brace_open > 0 &&
skip_to_brace_close > 0 && nth == 0) {
auto key = std::string(qs_kv[i] + skip_to_brace_open,
skip_to_brace_close - skip_to_brace_open);
auto value = std::string(qs_kv[i] + skip_to_eq);
return std::unique_ptr<std::pair<std::string, std::string>>(
new std::pair<std::string, std::string>(key, value));
} else {
--nth;
}
}
}
#endif // _qsSORTING
return nullptr;
}
inline char *qs_scanvalue(const char *key, const char *qs, char *val,
size_t val_len) {
const char *tmp = strchr(qs, '?');
// find the beginning of the k/v substrings
if (tmp != nullptr) qs = tmp + 1;
const size_t key_len = strlen(key);
while (*qs != '#' && *qs != '\0') {
if (qs_strncmp(key, qs, key_len) == 0) break;
qs += strcspn(qs, "&");
if (*qs == '&') qs++;
}
if (qs[0] == '\0') return nullptr;
qs += strcspn(qs, "=&#");
if (qs[0] == '=') {
qs++;
size_t i = strcspn(qs, "&=#");
#ifdef _MSC_VER
strncpy_s(val, val_len, qs,
(val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
#else
strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
#endif
qs_decode(val);
} else {
if (val_len > 0) val[0] = '\0';
}
return val;
}
} // namespace crow
// ----------------------------------------------------------------------------
namespace crow {
struct request;
/// A class to represent any data coming after the `?` in the request URL into
/// key-value pairs.
class query_string {
public:
static const int MAX_KEY_VALUE_PAIRS_COUNT = 256;
query_string() = default;
query_string(const query_string &qs) : url_(qs.url_) {
for (auto p : qs.key_value_pairs_) {
key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str()));
}
}
query_string &operator=(const query_string &qs) {
url_ = qs.url_;
key_value_pairs_.clear();
for (auto p : qs.key_value_pairs_) {
key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str()));
}
return *this;
}
query_string &operator=(query_string &&qs) noexcept {
key_value_pairs_ = std::move(qs.key_value_pairs_);
char *old_data = (char *)qs.url_.c_str();
url_ = std::move(qs.url_);
for (auto &p : key_value_pairs_) {
p += (char *)url_.c_str() - old_data;
}
return *this;
}
query_string(std::string params, bool url = true) : url_(std::move(params)) {
if (url_.empty()) return;
key_value_pairs_.resize(MAX_KEY_VALUE_PAIRS_COUNT);
size_t count = qs_parse(&url_[0], &key_value_pairs_[0],
MAX_KEY_VALUE_PAIRS_COUNT, url);
key_value_pairs_.resize(count);
key_value_pairs_.shrink_to_fit();
}
void clear() {
key_value_pairs_.clear();
url_.clear();
}
friend std::ostream &operator<<(std::ostream &os, const query_string &qs) {
os << "[ ";
for (size_t i = 0; i < qs.key_value_pairs_.size(); ++i) {
if (i) os << ", ";
os << qs.key_value_pairs_[i];
}
os << " ]";
return os;
}
/// Get a value from a name, used for `?name=value`.
///
/// Note: this method returns the value of the first occurrence of the key
/// only, to return all occurrences, see \ref get_list().
char *get(const std::string &name) const {
char *ret =
qs_k2v(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size());
return ret;
}
/// Works similar to \ref get() except it removes the item from the query
/// string.
char *pop(const std::string &name) {
char *ret = get(name);
if (ret != nullptr) {
const std::string key_name = name + '=';
for (unsigned int i = 0; i < key_value_pairs_.size(); i++) {
std::string str_item(key_value_pairs_[i]);
if (str_item.find(key_name) == 0) {
key_value_pairs_.erase(key_value_pairs_.begin() + i);
break;
}
}
}
return ret;
}
/// Returns a list of values, passed as
/// `?name[]=value1&name[]=value2&...name[]=valuen` with n being the size of
/// the list.
///
/// Note: Square brackets in the above example are controlled by
/// `use_brackets` boolean (true by default). If set to false, the example
/// becomes `?name=value1,name=value2...name=valuen`
std::vector<char *> get_list(const std::string &name,
bool use_brackets = true) const {
std::vector<char *> ret;
std::string plus = name + (use_brackets ? "[]" : "");
char *element = nullptr;
int count = 0;
while (1) {
element = qs_k2v(plus.c_str(), key_value_pairs_.data(),
key_value_pairs_.size(), count++);
if (!element) break;
ret.push_back(element);
}
return ret;
}
/// Similar to \ref get_list() but it removes the
std::vector<char *> pop_list(const std::string &name,
bool use_brackets = true) {
std::vector<char *> ret = get_list(name, use_brackets);
const size_t name_len = name.length();
if (!ret.empty()) {
for (unsigned int i = 0; i < key_value_pairs_.size(); i++) {
std::string str_item(key_value_pairs_[i]);
if (str_item.find(name) == 0) {
if (use_brackets && str_item.find("[]=", name_len) == name_len) {
key_value_pairs_.erase(key_value_pairs_.begin() + i--);
} else if (!use_brackets &&
str_item.find('=', name_len) == name_len) {
key_value_pairs_.erase(key_value_pairs_.begin() + i--);
}
}
}
}
return ret;
}
/// Works similar to \ref get_list() except the brackets are mandatory must
/// not be empty.
///
/// For example calling `get_dict(yourname)` on
/// `?yourname[sub1]=42&yourname[sub2]=84` would give a map containing `{sub1
/// : 42, sub2 : 84}`.
///
/// if your query string has both empty brackets and ones with a key inside,
/// use pop_list() to get all the values without a key before running this
/// method.
std::unordered_map<std::string, std::string>
get_dict(const std::string &name) const {
std::unordered_map<std::string, std::string> ret;
int count = 0;
while (1) {
if (auto element = qs_dict_name2kv(name.c_str(), key_value_pairs_.data(),
key_value_pairs_.size(), count++))
ret.insert(*element);
else
break;
}
return ret;
}
/// Works the same as \ref get_dict() but removes the values from the query
/// string.
std::unordered_map<std::string, std::string>
pop_dict(const std::string &name) {
const std::string name_value = name + '[';
std::unordered_map<std::string, std::string> ret = get_dict(name);
if (!ret.empty()) {
for (unsigned int i = 0; i < key_value_pairs_.size(); i++) {
std::string str_item(key_value_pairs_[i]);
if (str_item.find(name_value) == 0) {
key_value_pairs_.erase(key_value_pairs_.begin() + i--);
}
}
}
return ret;
}
std::vector<std::string> keys() const {
std::vector<std::string> keys;
keys.reserve(key_value_pairs_.size());
for (const char *const element : key_value_pairs_) {
const char *delimiter = strchr(element, '=');
if (delimiter)
keys.emplace_back(element, delimiter);
else
keys.emplace_back(element);
}
return keys;
}
private:
std::string url_;
std::vector<char *> key_value_pairs_;
};
} // namespace crow
// This file is generated from nginx/conf/mime.types using nginx_mime2cpp.py on
// 2021-12-03.
#include <string>
#include <unordered_map>
namespace crow {
const std::unordered_map<std::string, std::string> mime_types{
{"gz", "application/gzip"},
{"shtml", "text/html"},
{"htm", "text/html"},
{"html", "text/html"},
{"css", "text/css"},
{"xml", "text/xml"},
{"gif", "image/gif"},
{"jpg", "image/jpeg"},
{"jpeg", "image/jpeg"},
{"js", "application/javascript"},
{"atom", "application/atom+xml"},
{"rss", "application/rss+xml"},
{"mml", "text/mathml"},
{"txt", "text/plain"},
{"jad", "text/vnd.sun.j2me.app-descriptor"},
{"wml", "text/vnd.wap.wml"},
{"htc", "text/x-component"},
{"avif", "image/avif"},
{"png", "image/png"},
{"svgz", "image/svg+xml"},
{"svg", "image/svg+xml"},
{"tiff", "image/tiff"},
{"tif", "image/tiff"},
{"wbmp", "image/vnd.wap.wbmp"},
{"webp", "image/webp"},
{"ico", "image/x-icon"},
{"jng", "image/x-jng"},
{"bmp", "image/x-ms-bmp"},
{"woff", "font/woff"},
{"woff2", "font/woff2"},
{"ear", "application/java-archive"},
{"war", "application/java-archive"},
{"jar", "application/java-archive"},
{"json", "application/json"},
{"hqx", "application/mac-binhex40"},
{"doc", "application/msword"},
{"pdf", "application/pdf"},
{"ai", "application/postscript"},
{"eps", "application/postscript"},
{"ps", "application/postscript"},
{"rtf", "application/rtf"},
{"m3u8", "application/vnd.apple.mpegurl"},
{"kml", "application/vnd.google-earth.kml+xml"},
{"kmz", "application/vnd.google-earth.kmz"},
{"xls", "application/vnd.ms-excel"},
{"eot", "application/vnd.ms-fontobject"},
{"ppt", "application/vnd.ms-powerpoint"},
{"odg", "application/vnd.oasis.opendocument.graphics"},
{"odp", "application/vnd.oasis.opendocument.presentation"},
{"ods", "application/vnd.oasis.opendocument.spreadsheet"},
{"odt", "application/vnd.oasis.opendocument.text"},
{"pptx", "application/"
"vnd.openxmlformats-officedocument.presentationml.presentation"},
{"xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{"docx",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
{"wmlc", "application/vnd.wap.wmlc"},
{"wasm", "application/wasm"},
{"7z", "application/x-7z-compressed"},
{"cco", "application/x-cocoa"},
{"jardiff", "application/x-java-archive-diff"},
{"jnlp", "application/x-java-jnlp-file"},
{"run", "application/x-makeself"},
{"pm", "application/x-perl"},
{"pl", "application/x-perl"},
{"pdb", "application/x-pilot"},
{"prc", "application/x-pilot"},
{"rar", "application/x-rar-compressed"},
{"rpm", "application/x-redhat-package-manager"},
{"sea", "application/x-sea"},
{"swf", "application/x-shockwave-flash"},
{"sit", "application/x-stuffit"},
{"tk", "application/x-tcl"},
{"tcl", "application/x-tcl"},
{"crt", "application/x-x509-ca-cert"},
{"pem", "application/x-x509-ca-cert"},
{"der", "application/x-x509-ca-cert"},
{"xpi", "application/x-xpinstall"},
{"xhtml", "application/xhtml+xml"},
{"xspf", "application/xspf+xml"},
{"zip", "application/zip"},
{"dll", "application/octet-stream"},
{"exe", "application/octet-stream"},
{"bin", "application/octet-stream"},
{"deb", "application/octet-stream"},
{"dmg", "application/octet-stream"},
{"img", "application/octet-stream"},
{"iso", "application/octet-stream"},
{"msm", "application/octet-stream"},
{"msp", "application/octet-stream"},
{"msi", "application/octet-stream"},
{"kar", "audio/midi"},
{"midi", "audio/midi"},
{"mid", "audio/midi"},
{"mp3", "audio/mpeg"},
{"ogg", "audio/ogg"},
{"m4a", "audio/x-m4a"},
{"ra", "audio/x-realaudio"},
{"3gp", "video/3gpp"},
{"3gpp", "video/3gpp"},
{"ts", "video/mp2t"},
{"mp4", "video/mp4"},
{"mpg", "video/mpeg"},
{"mpeg", "video/mpeg"},
{"mov", "video/quicktime"},
{"webm", "video/webm"},
{"flv", "video/x-flv"},
{"m4v", "video/x-m4v"},
{"mng", "video/x-mng"},
{"asf", "video/x-ms-asf"},
{"asx", "video/x-ms-asf"},
{"wmv", "video/x-ms-wmv"},
{"avi", "video/x-msvideo"}};
}
// settings for crow
// TODO(ipkn) replace with runtime config. libucl?
/* #ifdef - enables debug mode */
// #define CROW_ENABLE_DEBUG
/* #ifdef - enables logging */
#define CROW_ENABLE_LOGGING
/* #ifdef - enforces section 5.2 and 6.1 of RFC6455 (only accepting masked
* messages from clients) */
// #define CROW_ENFORCE_WS_SPEC
/* #define - specifies log level */
/*
Debug = 0
Info = 1
Warning = 2
Error = 3
Critical = 4
default to INFO
*/
#ifndef CROW_LOG_LEVEL
#define CROW_LOG_LEVEL 1
#endif
#ifndef CROW_STATIC_DIRECTORY
#define CROW_STATIC_DIRECTORY "static/"
#endif
#ifndef CROW_STATIC_ENDPOINT
#define CROW_STATIC_ENDPOINT "/static/<path>"
#endif
// compiler flags
#if defined(_MSC_VER)
#if _MSC_VER < 1900
#define CROW_MSVC_WORKAROUND
#define constexpr const
#define noexcept throw()
#endif
#endif
#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#include <boost/asio/version.hpp>
#ifdef CROW_ENABLE_SSL
#include <boost/asio/ssl.hpp>
#endif
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#include <asio/version.hpp>
#ifdef CROW_ENABLE_SSL
#include <asio/ssl.hpp>
#endif
#endif
#if (defined(CROW_USE_BOOST) && BOOST_VERSION >= 107000) || \
(ASIO_VERSION >= 101008)
#define GET_IO_CONTEXT(s) ((asio::io_context &)(s).get_executor().context())
#else
#define GET_IO_CONTEXT(s) ((s).get_io_service())
#endif
namespace crow {
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
using error_code = boost::system::error_code;
#else
using error_code = asio::error_code;
#endif
using tcp = asio::ip::tcp;
using stream_protocol = asio::local::stream_protocol;
/// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
struct SocketAdaptor {
using context = void;
SocketAdaptor(asio::io_context &io_context, context *)
: socket_(io_context) {}
asio::io_context &get_io_context() { return GET_IO_CONTEXT(socket_); }
/// Get the TCP socket handling data transfers, regardless of what layer is
/// handling transfers on top of the socket.
tcp::socket &raw_socket() { return socket_; }
/// Get the object handling data transfers, this can be either a TCP socket or
/// an SSL stream (if SSL is enabled).
tcp::socket &socket() { return socket_; }
tcp::endpoint remote_endpoint() const { return socket_.remote_endpoint(); }
std::string address() const {
return socket_.remote_endpoint().address().to_string();
}
bool is_open() const { return socket_.is_open(); }
void close() {
error_code ec;
socket_.close(ec);
}
void shutdown_readwrite() {
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
}
void shutdown_write() {
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
}
void shutdown_read() {
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
}
template <typename F> void start(F f) { f(error_code()); }
tcp::socket socket_;
};
struct UnixSocketAdaptor {
using context = void;
UnixSocketAdaptor(asio::io_context &io_context, context *)
: socket_(io_context) {}
asio::io_context &get_io_context() { return GET_IO_CONTEXT(socket_); }
stream_protocol::socket &raw_socket() { return socket_; }
stream_protocol::socket &socket() { return socket_; }
stream_protocol::endpoint remote_endpoint() {
return socket_.local_endpoint();
}
std::string address() const { return ""; }
bool is_open() { return socket_.is_open(); }
void close() {
error_code ec;
socket_.close(ec);
}
void shutdown_readwrite() {
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
}
void shutdown_write() {
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
}
void shutdown_read() {
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
}
template <typename F> void start(F f) { f(error_code()); }
stream_protocol::socket socket_;
};
#ifdef CROW_ENABLE_SSL
struct SSLAdaptor {
using context = asio::ssl::context;
using ssl_socket_t = asio::ssl::stream<tcp::socket>;
SSLAdaptor(asio::io_context &io_context, context *ctx)
: ssl_socket_(new ssl_socket_t(io_context, *ctx)) {}
asio::ssl::stream<tcp::socket> &socket() { return *ssl_socket_; }
tcp::socket::lowest_layer_type &raw_socket() {
return ssl_socket_->lowest_layer();
}
tcp::endpoint remote_endpoint() { return raw_socket().remote_endpoint(); }
std::string address() const {
return ssl_socket_->lowest_layer().remote_endpoint().address().to_string();
}
bool is_open() { return ssl_socket_ ? raw_socket().is_open() : false; }
void close() {
if (is_open()) {
error_code ec;
raw_socket().close(ec);
}
}
void shutdown_readwrite() {
if (is_open()) {
error_code ec;
raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_both,
ec);
}
}
void shutdown_write() {
if (is_open()) {
error_code ec;
raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_send,
ec);
}
}
void shutdown_read() {
if (is_open()) {
error_code ec;
raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_receive,
ec);
}
}
asio::io_context &get_io_context() { return GET_IO_CONTEXT(raw_socket()); }
template <typename F> void start(F f) {
ssl_socket_->async_handshake(asio::ssl::stream_base::server,
[f](const error_code &ec) { f(ec); });
}
std::unique_ptr<asio::ssl::stream<tcp::socket>> ssl_socket_;
};
#endif
} // namespace crow
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <sstream>
#include <string>
namespace crow {
enum class LogLevel {
#ifndef ERROR
#ifndef DEBUG
DEBUG = 0,
INFO,
WARNING,
ERROR,
CRITICAL,
#endif
#endif
Debug = 0,
Info,
Warning,
Error,
Critical,
};
class ILogHandler {
public:
virtual ~ILogHandler() = default;
virtual void log(const std::string &message, LogLevel level) = 0;
};
class CerrLogHandler : public ILogHandler {
public:
void log(const std::string &message, LogLevel level) override {
std::string log_msg;
log_msg.reserve(message.length() + 1 + 32 + 3 + 8 + 2);
log_msg.append("(").append(timestamp()).append(") [");
switch (level) {
case LogLevel::Debug: log_msg.append("DEBUG "); break;
case LogLevel::Info: log_msg.append("INFO "); break;
case LogLevel::Warning: log_msg.append("WARNING "); break;
case LogLevel::Error: log_msg.append("ERROR "); break;
case LogLevel::Critical: log_msg.append("CRITICAL"); break;
}
log_msg.append("] ").append(message);
std::cerr << log_msg << std::endl;
}
private:
static std::string timestamp() {
char date[32];
time_t t = time(0);
tm my_tm;
#if defined(_MSC_VER) || defined(__MINGW32__)
#ifdef CROW_USE_LOCALTIMEZONE
localtime_s(&my_tm, &t);
#else
gmtime_s(&my_tm, &t);
#endif
#else
#ifdef CROW_USE_LOCALTIMEZONE
localtime_r(&t, &my_tm);
#else
gmtime_r(&t, &my_tm);
#endif
#endif
size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm);
return std::string(date, date + sz);
}
};
class logger {
public:
logger(LogLevel level) : level_(level) {}
~logger() {
#ifdef CROW_ENABLE_LOGGING
if (level_ >= get_current_log_level()) {
get_handler_ref()->log(stringstream_.str(), level_);
}
#endif
}
//
template <typename T> logger &operator<<(T const &value) {
#ifdef CROW_ENABLE_LOGGING
if (level_ >= get_current_log_level()) { stringstream_ << value; }
#endif
return *this;
}
//
static void setLogLevel(LogLevel level) { get_log_level_ref() = level; }
static void setHandler(ILogHandler *handler) { get_handler_ref() = handler; }
static LogLevel get_current_log_level() { return get_log_level_ref(); }
private:
//
static LogLevel &get_log_level_ref() {
static LogLevel current_level = static_cast<LogLevel>(CROW_LOG_LEVEL);
return current_level;
}
static ILogHandler *&get_handler_ref() {
static CerrLogHandler default_handler;
static ILogHandler *current_handler = &default_handler;
return current_handler;
}
//
std::ostringstream stringstream_;
LogLevel level_;
};
} // namespace crow
#define CROW_LOG_CRITICAL \
if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
crow::logger(crow::LogLevel::Critical)
#define CROW_LOG_ERROR \
if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
crow::logger(crow::LogLevel::Error)
#define CROW_LOG_WARNING \
if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
crow::logger(crow::LogLevel::Warning)
#define CROW_LOG_INFO \
if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
crow::logger(crow::LogLevel::Info)
#define CROW_LOG_DEBUG \
if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
crow::logger(crow::LogLevel::Debug)
#include <string>
namespace crow {
/// An abstract class that allows any other class to be returned by a handler.
struct returnable {
std::string content_type;
virtual std::string dump() const = 0;
returnable(std::string ctype) : content_type{ctype} {}
virtual ~returnable() {}
};
} // namespace crow
#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#ifdef CROW_ENABLE_SSL
#include <boost/asio/ssl.hpp>
#endif
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#ifdef CROW_ENABLE_SSL
#include <asio/ssl.hpp>
#endif
#endif
namespace crow {
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
using error_code = boost::system::error_code;
#else
using error_code = asio::error_code;
#endif
using tcp = asio::ip::tcp;
using stream_protocol = asio::local::stream_protocol;
struct TCPAcceptor {
using endpoint = tcp::endpoint;
tcp::acceptor acceptor_;
TCPAcceptor(asio::io_context &io_context) : acceptor_(io_context) {}
int16_t port() const { return acceptor_.local_endpoint().port(); }
std::string address() const {
return acceptor_.local_endpoint().address().to_string();
}
std::string url_display(bool ssl_used) const {
auto address = acceptor_.local_endpoint().address();
return (ssl_used ? "https://" : "http://") +
(address.is_v4() ? address.to_string()
: "[" + address.to_string() + "]") +
":" + std::to_string(acceptor_.local_endpoint().port());
}
tcp::acceptor &raw_acceptor() { return acceptor_; }
endpoint local_endpoint() const { return acceptor_.local_endpoint(); }
inline static tcp::acceptor::reuse_address reuse_address_option() {
return tcp::acceptor::reuse_address(true);
}
};
struct UnixSocketAcceptor {
using endpoint = stream_protocol::endpoint;
stream_protocol::acceptor acceptor_;
UnixSocketAcceptor(asio::io_context &io_context) : acceptor_(io_context) {}
int16_t port() const { return 0; }
std::string address() const { return acceptor_.local_endpoint().path(); }
std::string url_display(bool) const {
return acceptor_.local_endpoint().path();
}
stream_protocol::acceptor &raw_acceptor() { return acceptor_; }
endpoint local_endpoint() const { return acceptor_.local_endpoint(); }
inline static stream_protocol::acceptor::reuse_address
reuse_address_option() {
// reuse addr must be false
// (https://github.com/chriskohlhoff/asio/issues/622)
return stream_protocol::acceptor::reuse_address(false);
}
};
} // namespace crow
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <functional>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <filesystem>
// TODO(EDev): Adding C++20's [[likely]] and [[unlikely]] attributes might be
// useful
#if defined(__GNUG__) || defined(__clang__)
#define CROW_LIKELY(X) __builtin_expect(!!(X), 1)
#define CROW_UNLIKELY(X) __builtin_expect(!!(X), 0)
#else
#define CROW_LIKELY(X) (X)
#define CROW_UNLIKELY(X) (X)
#endif
namespace crow {
/// @cond SKIP
namespace black_magic {
#ifndef CROW_MSVC_WORKAROUND
/// Out of Range Exception for const_str
struct OutOfRange {
OutOfRange(unsigned /*pos*/, unsigned /*length*/) {}
};
/// Helper function to throw an exception if i is larger than len
constexpr unsigned requires_in_range(unsigned i, unsigned len) {
return i >= len ? throw OutOfRange(i, len) : i;
}
/// A constant string implementation.
class const_str {
const char *const begin_;
unsigned size_;
public:
template <unsigned N>
constexpr const_str(const char (&arr)[N]) : begin_(arr), size_(N - 1) {
static_assert(N >= 1, "not a string literal");
}
constexpr char operator[](unsigned i) const {
return requires_in_range(i, size_), begin_[i];
}
constexpr operator const char *() const { return begin_; }
constexpr const char *begin() const { return begin_; }
constexpr const char *end() const { return begin_ + size_; }
constexpr unsigned size() const { return size_; }
};
constexpr unsigned find_closing_tag(const_str s, unsigned p) {
return s[p] == '>' ? p : find_closing_tag(s, p + 1);
}
/// Check that the CROW_ROUTE string is valid
constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0) {
return i == s.size() ? f == 0
: f < 0 || f >= 2 ? false
: s[i] == '<' ? is_valid(s, i + 1, f + 1)
: s[i] == '>' ? is_valid(s, i + 1, f - 1)
: is_valid(s, i + 1, f);
}
constexpr bool is_equ_p(const char *a, const char *b, unsigned n) {
return *a == 0 && *b == 0 && n == 0 ? true
: (*a == 0 || *b == 0) ? false
: n == 0 ? true
: *a != *b ? false
: is_equ_p(a + 1, b + 1, n - 1);
}
constexpr bool is_equ_n(const_str a, unsigned ai, const_str b, unsigned bi,
unsigned n) {
return ai + n > a.size() || bi + n > b.size() ? false
: n == 0 ? true
: a[ai] != b[bi] ? false
: is_equ_n(a, ai + 1, b, bi + 1, n - 1);
}
constexpr bool is_int(const_str s, unsigned i) {
return is_equ_n(s, i, "<int>", 0, 5);
}
constexpr bool is_uint(const_str s, unsigned i) {
return is_equ_n(s, i, "<uint>", 0, 6);
}
constexpr bool is_float(const_str s, unsigned i) {
return is_equ_n(s, i, "<float>", 0, 7) || is_equ_n(s, i, "<double>", 0, 8);
}
constexpr bool is_str(const_str s, unsigned i) {
return is_equ_n(s, i, "<str>", 0, 5) || is_equ_n(s, i, "<string>", 0, 8);
}
constexpr bool is_path(const_str s, unsigned i) {
return is_equ_n(s, i, "<path>", 0, 6);
}
#endif
template <typename T> struct parameter_tag {
static const int value = 0;
};
#define CROW_INTERNAL_PARAMETER_TAG(t, i) \
template <> struct parameter_tag<t> { \
static const int value = i; \
}
CROW_INTERNAL_PARAMETER_TAG(int, 1);
CROW_INTERNAL_PARAMETER_TAG(char, 1);
CROW_INTERNAL_PARAMETER_TAG(short, 1);
CROW_INTERNAL_PARAMETER_TAG(long, 1);
CROW_INTERNAL_PARAMETER_TAG(long long, 1);
CROW_INTERNAL_PARAMETER_TAG(unsigned int, 2);
CROW_INTERNAL_PARAMETER_TAG(unsigned char, 2);
CROW_INTERNAL_PARAMETER_TAG(unsigned short, 2);
CROW_INTERNAL_PARAMETER_TAG(unsigned long, 2);
CROW_INTERNAL_PARAMETER_TAG(unsigned long long, 2);
CROW_INTERNAL_PARAMETER_TAG(double, 3);
CROW_INTERNAL_PARAMETER_TAG(std::string, 4);
#undef CROW_INTERNAL_PARAMETER_TAG
template <typename... Args> struct compute_parameter_tag_from_args_list;
template <> struct compute_parameter_tag_from_args_list<> {
static const int value = 0;
};
template <typename Arg, typename... Args>
struct compute_parameter_tag_from_args_list<Arg, Args...> {
static const int sub_value =
compute_parameter_tag_from_args_list<Args...>::value;
static const int value =
parameter_tag<typename std::decay<Arg>::type>::value
? sub_value * 6 + parameter_tag<typename std::decay<Arg>::type>::value
: sub_value;
};
static inline bool is_parameter_tag_compatible(uint64_t a, uint64_t b) {
if (a == 0) return b == 0;
if (b == 0) return a == 0;
int sa = a % 6;
int sb = a % 6;
if (sa == 5) sa = 4;
if (sb == 5) sb = 4;
if (sa != sb) return false;
return is_parameter_tag_compatible(a / 6, b / 6);
}
static inline unsigned find_closing_tag_runtime(const char *s, unsigned p) {
return s[p] == 0 ? throw std::runtime_error("unmatched tag <")
: s[p] == '>' ? p
: find_closing_tag_runtime(s, p + 1);
}
static inline uint64_t get_parameter_tag_runtime(const char *s,
unsigned p = 0) {
return s[p] == 0 ? 0
: s[p] == '<'
? (std::strncmp(s + p, "<int>", 5) == 0
? get_parameter_tag_runtime(
s, find_closing_tag_runtime(s, p)) *
6 +
1
: std::strncmp(s + p, "<uint>", 6) == 0
? get_parameter_tag_runtime(
s, find_closing_tag_runtime(s, p)) *
6 +
2
: (std::strncmp(s + p, "<float>", 7) == 0 ||
std::strncmp(s + p, "<double>", 8) == 0)
? get_parameter_tag_runtime(
s, find_closing_tag_runtime(s, p)) *
6 +
3
: (std::strncmp(s + p, "<str>", 5) == 0 ||
std::strncmp(s + p, "<string>", 8) == 0)
? get_parameter_tag_runtime(
s, find_closing_tag_runtime(s, p)) *
6 +
4
: std::strncmp(s + p, "<path>", 6) == 0
? get_parameter_tag_runtime(
s, find_closing_tag_runtime(s, p)) *
6 +
5
: throw std::runtime_error("invalid parameter type"))
: get_parameter_tag_runtime(s, p + 1);
}
#ifndef CROW_MSVC_WORKAROUND
constexpr uint64_t get_parameter_tag(const_str s, unsigned p = 0) {
return p == s.size() ? 0
: s[p] == '<'
? (is_int(s, p)
? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 1
: is_uint(s, p)
? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 2
: is_float(s, p)
? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 3
: is_str(s, p)
? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 4
: is_path(s, p)
? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 5
: throw std::runtime_error("invalid parameter type"))
: get_parameter_tag(s, p + 1);
}
#endif
template <typename... T> struct S {
template <typename U> using push = S<U, T...>;
template <typename U> using push_back = S<T..., U>;
template <template <typename... Args> class U> using rebind = U<T...>;
};
// Check whether the template function can be called with specific arguments
template <typename F, typename Set> struct CallHelper;
template <typename F, typename... Args> struct CallHelper<F, S<Args...>> {
template <typename F1, typename... Args1,
typename = decltype(std::declval<F1>()(std::declval<Args1>()...))>
static char __test(int);
template <typename...> static int __test(...);
static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
};
// Check Tuple contains type T
template <typename T, typename Tuple> struct has_type;
template <typename T> struct has_type<T, std::tuple<>> : std::false_type {};
template <typename T, typename U, typename... Ts>
struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};
template <typename T, typename... Ts>
struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
// Find index of type in tuple
template <class T, class Tuple> struct tuple_index;
template <class T, class... Types>
struct tuple_index<T, std::tuple<T, Types...>> {
static const int value = 0;
};
template <class T, class U, class... Types>
struct tuple_index<T, std::tuple<U, Types...>> {
static const int value = 1 + tuple_index<T, std::tuple<Types...>>::value;
};
// Extract element from forward tuple or get default
template <typename T, typename Tup>
typename std::enable_if<has_type<T &, Tup>::value,
typename std::decay<T>::type &&>::type
tuple_extract(Tup &tup) {
return std::move(std::get<T &>(tup));
}
template <typename T, typename Tup>
typename std::enable_if<!has_type<T &, Tup>::value, T>::type
tuple_extract(Tup &) {
return T{};
}
// Kind of fold expressions in C++11
template <bool...> struct bool_pack;
template <bool... bs>
using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
template <int N> struct single_tag_to_type {};
template <> struct single_tag_to_type<1> {
using type = int64_t;
};
template <> struct single_tag_to_type<2> {
using type = uint64_t;
};
template <> struct single_tag_to_type<3> {
using type = double;
};
template <> struct single_tag_to_type<4> {
using type = std::string;
};
template <> struct single_tag_to_type<5> {
using type = std::string;
};
template <uint64_t Tag> struct arguments {
using subarguments = typename arguments<Tag / 6>::type;
using type = typename subarguments::template push<
typename single_tag_to_type<Tag % 6>::type>;
};
template <> struct arguments<0> {
using type = S<>;
};
template <typename... T> struct last_element_type {
using type =
typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type;
};
template <> struct last_element_type<> {};
// from
// http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth
template <class T> using Invoke = typename T::type;
template <unsigned...> struct seq {
using type = seq;
};
template <class S1, class S2> struct concat;
template <unsigned... I1, unsigned... I2>
struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1) + I2)...> {};
template <class S1, class S2> using Concat = Invoke<concat<S1, S2>>;
template <unsigned N> struct gen_seq;
template <unsigned N> using GenSeq = Invoke<gen_seq<N>>;
template <unsigned N>
struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {};
template <> struct gen_seq<0> : seq<> {};
template <> struct gen_seq<1> : seq<0> {};
template <typename Seq, typename Tuple> struct pop_back_helper;
template <unsigned... N, typename Tuple>
struct pop_back_helper<seq<N...>, Tuple> {
template <template <typename... Args> class U>
using rebind = U<typename std::tuple_element<N, Tuple>::type...>;
};
template <typename... T>
struct pop_back //: public pop_back_helper<typename
//: gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>
{
template <template <typename... Args> class U>
using rebind =
typename pop_back_helper<typename gen_seq<sizeof...(T) - 1>::type,
std::tuple<T...>>::template rebind<U>;
};
template <> struct pop_back<> {
template <template <typename... Args> class U> using rebind = U<>;
};
// from
// http://stackoverflow.com/questions/2118541/check-if-c0x-parameter-pack-contains-a-type
template <typename Tp, typename... List> struct contains : std::true_type {};
template <typename Tp, typename Head, typename... Rest>
struct contains<Tp, Head, Rest...>
: std::conditional<std::is_same<Tp, Head>::value, std::true_type,
contains<Tp, Rest...>>::type {};
template <typename Tp> struct contains<Tp> : std::false_type {};
template <typename T> struct empty_context {};
template <typename T> struct promote {
using type = T;
};
#define CROW_INTERNAL_PROMOTE_TYPE(t1, t2) \
template <> struct promote<t1> { \
using type = t2; \
}
CROW_INTERNAL_PROMOTE_TYPE(char, int64_t);
CROW_INTERNAL_PROMOTE_TYPE(short, int64_t);
CROW_INTERNAL_PROMOTE_TYPE(int, int64_t);
CROW_INTERNAL_PROMOTE_TYPE(long, int64_t);
CROW_INTERNAL_PROMOTE_TYPE(long long, int64_t);
CROW_INTERNAL_PROMOTE_TYPE(unsigned char, uint64_t);
CROW_INTERNAL_PROMOTE_TYPE(unsigned short, uint64_t);
CROW_INTERNAL_PROMOTE_TYPE(unsigned int, uint64_t);
CROW_INTERNAL_PROMOTE_TYPE(unsigned long, uint64_t);
CROW_INTERNAL_PROMOTE_TYPE(unsigned long long, uint64_t);
CROW_INTERNAL_PROMOTE_TYPE(float, double);
#undef CROW_INTERNAL_PROMOTE_TYPE
template <typename T> using promote_t = typename promote<T>::type;
} // namespace black_magic
namespace detail {
template <class T, std::size_t N, class... Args>
struct get_index_of_element_from_tuple_by_type_impl {
static constexpr auto value = N;
};
template <class T, std::size_t N, class... Args>
struct get_index_of_element_from_tuple_by_type_impl<T, N, T, Args...> {
static constexpr auto value = N;
};
template <class T, std::size_t N, class U, class... Args>
struct get_index_of_element_from_tuple_by_type_impl<T, N, U, Args...> {
static constexpr auto value =
get_index_of_element_from_tuple_by_type_impl<T, N + 1, Args...>::value;
};
} // namespace detail
namespace utility {
template <class T, class... Args>
T &get_element_by_type(std::tuple<Args...> &t) {
return std::get<detail::get_index_of_element_from_tuple_by_type_impl<
T, 0, Args...>::value>(t);
}
template <typename T> struct function_traits;
#ifndef CROW_MSVC_WORKAROUND
template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {
using parent_t = function_traits<decltype(&T::operator())>;
static const size_t arity = parent_t::arity;
using result_type = typename parent_t::result_type;
template <size_t i> using arg = typename parent_t::template arg<i>;
};
#endif
template <typename ClassType, typename R, typename... Args>
struct function_traits<R (ClassType::*)(Args...) const> {
static const size_t arity = sizeof...(Args);
typedef R result_type;
template <size_t i>
using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
template <typename ClassType, typename R, typename... Args>
struct function_traits<R (ClassType::*)(Args...)> {
static const size_t arity = sizeof...(Args);
typedef R result_type;
template <size_t i>
using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
template <typename R, typename... Args>
struct function_traits<std::function<R(Args...)>> {
static const size_t arity = sizeof...(Args);
typedef R result_type;
template <size_t i>
using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
/// @endcond
inline static std::string base64encode(
const unsigned char *data, size_t size,
const char *key =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") {
std::string ret;
ret.resize((size + 2) / 3 * 4);
auto it = ret.begin();
while (size >= 3) {
*it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
unsigned char h = (static_cast<unsigned char>(*data++) & 0x03) << 4;
*it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)];
h = (static_cast<unsigned char>(*data++) & 0x0F) << 2;
*it++ = key[h | ((static_cast<unsigned char>(*data) & 0xC0) >> 6)];
*it++ = key[static_cast<unsigned char>(*data++) & 0x3F];
size -= 3;
}
if (size == 1) {
*it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
unsigned char h = (static_cast<unsigned char>(*data++) & 0x03) << 4;
*it++ = key[h];
*it++ = '=';
*it++ = '=';
} else if (size == 2) {
*it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
unsigned char h = (static_cast<unsigned char>(*data++) & 0x03) << 4;
*it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)];
h = (static_cast<unsigned char>(*data++) & 0x0F) << 2;
*it++ = key[h];
*it++ = '=';
}
return ret;
}
inline static std::string base64encode(
std::string data, size_t size,
const char *key =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") {
return base64encode((const unsigned char *)data.c_str(), size, key);
}
inline static std::string base64encode_urlsafe(const unsigned char *data,
size_t size) {
return base64encode(
data, size,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
}
inline static std::string base64encode_urlsafe(std::string data, size_t size) {
return base64encode(
(const unsigned char *)data.c_str(), size,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
}
inline static std::string base64decode(const char *data, size_t size) {
// We accept both regular and url encoding here, as there does not seem to be
// any downside to that. If we want to distinguish that we should use +/ for
// non-url and -_ for url.
// Mapping logic from characters to [0-63]
auto key = [](char c) -> unsigned char {
if ((c >= 'A') && (c <= 'Z')) return c - 'A';
if ((c >= 'a') && (c <= 'z')) return c - 'a' + 26;
if ((c >= '0') && (c <= '9')) return c - '0' + 52;
if ((c == '+') || (c == '-')) return 62;
if ((c == '/') || (c == '_')) return 63;
return 0;
};
// Not padded
if (size % 4 == 2) // missing last 2 characters
size = (size / 4 * 3) + 1; // Not subtracting extra characters because
// they're truncated in int division
else if (size % 4 == 3) // missing last character
size = (size / 4 * 3) + 2; // Not subtracting extra characters because
// they're truncated in int division
// Padded
else if (size >= 2 && data[size - 2] == '=') // padded with '=='
size = (size / 4 * 3) - 2; // == padding means the last block only has 1
// character instead of 3, hence the '-2'
else if (size >= 1 && data[size - 1] == '=') // padded with '='
size = (size / 4 * 3) - 1; // = padding means the last block only has 2
// character instead of 3, hence the '-1'
// Padding not needed
else
size = size / 4 * 3;
std::string ret;
ret.resize(size);
auto it = ret.begin();
// These will be used to decode 1 character at a time
unsigned char odd; // char1 and char3
unsigned char even; // char2 and char4
// Take 4 character blocks to turn into 3
while (size >= 3) {
// dec_char1 = (char1 shifted 2 bits to the left) OR ((char2 AND 00110000)
// shifted 4 bits to the right))
odd = key(*data++);
even = key(*data++);
*it++ = (odd << 2) | ((even & 0x30) >> 4);
// dec_char2 = ((char2 AND 00001111) shifted 4 bits left) OR ((char3 AND
// 00111100) shifted 2 bits right))
odd = key(*data++);
*it++ = ((even & 0x0F) << 4) | ((odd & 0x3C) >> 2);
// dec_char3 = ((char3 AND 00000011) shifted 6 bits left) OR (char4)
even = key(*data++);
*it++ = ((odd & 0x03) << 6) | (even);
size -= 3;
}
if (size == 2) {
// d_char1 = (char1 shifted 2 bits to the left) OR ((char2 AND 00110000)
// shifted 4 bits to the right))
odd = key(*data++);
even = key(*data++);
*it++ = (odd << 2) | ((even & 0x30) >> 4);
// d_char2 = ((char2 AND 00001111) shifted 4 bits left) OR ((char3 AND
// 00111100) shifted 2 bits right))
odd = key(*data++);
*it++ = ((even & 0x0F) << 4) | ((odd & 0x3C) >> 2);
} else if (size == 1) {
// d_char1 = (char1 shifted 2 bits to the left) OR ((char2 AND 00110000)
// shifted 4 bits to the right))
odd = key(*data++);
even = key(*data++);
*it++ = (odd << 2) | ((even & 0x30) >> 4);
}
return ret;
}
inline static std::string base64decode(const std::string &data, size_t size) {
return base64decode(data.data(), size);
}
inline static std::string base64decode(const std::string &data) {
return base64decode(data.data(), data.length());
}
inline static std::string normalize_path(const std::string &directoryPath) {
std::string normalizedPath = directoryPath;
std::replace(normalizedPath.begin(), normalizedPath.end(), '\\', '/');
if (!normalizedPath.empty() && normalizedPath.back() != '/')
normalizedPath += '/';
return normalizedPath;
}
inline static void sanitize_filename(std::string &data,
char replacement = '_') {
if (data.length() > 255) data.resize(255);
static const auto toUpper = [](char c) {
return ((c >= 'a') && (c <= 'z')) ? (c - ('a' - 'A')) : c;
};
// Check for special device names. The Windows behavior is really odd here, it
// will consider both AUX and AUX.txt a special device. Thus we search for the
// string (case-insensitive), and then check if the string ends or if is has a
// dangerous follow up character (.:\/)
auto sanitizeSpecialFile = [](std::string &source, unsigned ofs,
const char *pattern, bool includeNumber,
char replacement_) {
unsigned i = ofs;
size_t len = source.length();
const char *p = pattern;
while (*p) {
if (i >= len) return;
if (toUpper(source[i]) != *p) return;
++i;
++p;
}
if (includeNumber) {
if ((i >= len) || (source[i] < '1') || (source[i] > '9')) return;
++i;
}
if ((i >= len) || (source[i] == '.') || (source[i] == ':') ||
(source[i] == '/') || (source[i] == '\\')) {
source.erase(ofs + 1, (i - ofs) - 1);
source[ofs] = replacement_;
}
};
bool checkForSpecialEntries = true;
for (unsigned i = 0; i < data.length(); ++i) {
// Recognize directory traversals and the special devices
// CON/PRN/AUX/NULL/COM[1-]/LPT[1-9]
if (checkForSpecialEntries) {
checkForSpecialEntries = false;
switch (toUpper(data[i])) {
case 'A': sanitizeSpecialFile(data, i, "AUX", false, replacement); break;
case 'C':
sanitizeSpecialFile(data, i, "CON", false, replacement);
sanitizeSpecialFile(data, i, "COM", true, replacement);
break;
case 'L': sanitizeSpecialFile(data, i, "LPT", true, replacement); break;
case 'N': sanitizeSpecialFile(data, i, "NUL", false, replacement); break;
case 'P': sanitizeSpecialFile(data, i, "PRN", false, replacement); break;
case '.': sanitizeSpecialFile(data, i, "..", false, replacement); break;
}
}
// Sanitize individual characters
unsigned char c = data[i];
if ((c < ' ') || ((c >= 0x80) && (c <= 0x9F)) || (c == '?') || (c == '<') ||
(c == '>') || (c == ':') || (c == '*') || (c == '|') || (c == '\"')) {
data[i] = replacement;
} else if ((c == '/') || (c == '\\')) {
if (CROW_UNLIKELY(i ==
0)) // Prevent Unix Absolute Paths (Windows Absolute
// Paths are prevented with `(c == ':')`)
{
data[i] = replacement;
} else {
checkForSpecialEntries = true;
}
}
}
}
inline static std::string random_alphanum(std::size_t size) {
static const char alphabet[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist(
0, sizeof(alphabet) - 2);
std::string out;
out.reserve(size);
for (std::size_t i = 0; i < size; i++)
out.push_back(alphabet[dist(rng)]);
return out;
}
inline static std::string join_path(std::string path,
const std::string &fname) {
return (std::filesystem::path(path) / fname).string();
}
/**
* @brief Checks two string for equality.
* Always returns false if strings differ in size.
* Defaults to case-insensitive comparison.
*/
inline static bool string_equals(const std::string_view l,
const std::string_view r,
bool case_sensitive = false) {
if (l.length() != r.length()) return false;
for (size_t i = 0; i < l.length(); i++) {
if (case_sensitive) {
if (l[i] != r[i]) return false;
} else {
if (std::toupper(l[i]) != std::toupper(r[i])) return false;
}
}
return true;
}
template <typename T, typename U> inline static T lexical_cast(const U &v) {
std::stringstream stream;
T res;
stream << v;
stream >> res;
return res;
}
template <typename T>
inline static T lexical_cast(const char *v, size_t count) {
std::stringstream stream;
T res;
stream.write(v, count);
stream >> res;
return res;
}
/// Return string view of the given string view with its
/// leading and trailing whitespaces removed.
inline static std::string_view trim(const std::string_view sv) {
const size_t first = sv.find_first_not_of(" \t\n\r\f\v"); // same as isspace
if (std::string_view::npos == first) { return sv.substr(0, 0); }
const size_t last = sv.find_last_not_of(" \t\n\r\f\v");
return sv.substr(first, (last - first + 1));
}
/**
* @brief splits a string based on a separator
*/
inline static std::vector<std::string> split(const std::string &v,
const std::string &separator) {
std::vector<std::string> result;
size_t startPos = 0;
for (size_t foundPos = v.find(separator); foundPos != std::string::npos;
foundPos = v.find(separator, startPos)) {
result.push_back(v.substr(startPos, foundPos - startPos));
startPos = foundPos + separator.size();
}
result.push_back(v.substr(startPos));
return result;
}
/**
* @brief Returns the first occurence that matches between two ranges of
* iterators
* @param first1 begin() iterator of the first range
* @param last1 end() iterator of the first range
* @param first2 begin() iterator of the second range
* @param last2 end() iterator of the second range
* @return first occurence that matches between two ranges of iterators
*/
template <typename Iter1, typename Iter2>
inline static Iter1 find_first_of(Iter1 first1, Iter1 last1, Iter2 first2,
Iter2 last2) {
for (; first1 != last1; ++first1) {
if (std::find(first2, last2, *first1) != last2) { return first1; }
}
return last1;
}
} // namespace utility
} // namespace crow
// #define CROW_JSON_NO_ERROR_CHECK
// #define CROW_JSON_USE_MAP
#include <string>
#ifdef CROW_JSON_USE_MAP
#include <map>
#else
#include <unordered_map>
#endif
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <memory>
#include <vector>
using std::isinf;
using std::isnan;
namespace crow // NOTE: Already documented in "crow/app.h"
{
namespace mustache {
class template_t;
}
namespace json {
static inline char to_hex(char c) {
c = c & 0xf;
if (c < 10) return '0' + c;
return 'a' + c - 10;
}
inline void escape(const std::string &str, std::string &ret) {
ret.reserve(ret.size() + str.size() + str.size() / 4);
for (auto c : str) {
switch (c) {
case '"': ret += "\\\""; break;
case '\\': ret += "\\\\"; break;
case '\n': ret += "\\n"; break;
case '\b': ret += "\\b"; break;
case '\f': ret += "\\f"; break;
case '\r': ret += "\\r"; break;
case '\t': ret += "\\t"; break;
default:
if (c >= 0 && c < 0x20) {
ret += "\\u00";
ret += to_hex(c / 16);
ret += to_hex(c % 16);
} else
ret += c;
break;
}
}
}
inline std::string escape(const std::string &str) {
std::string ret;
escape(str, ret);
return ret;
}
enum class type : char {
Null,
False,
True,
Number,
String,
List,
Object,
Function
};
inline const char *get_type_str(type t) {
switch (t) {
case type::Number: return "Number";
case type::False: return "False";
case type::True: return "True";
case type::List: return "List";
case type::String: return "String";
case type::Object: return "Object";
case type::Function: return "Function";
default: return "Unknown";
}
}
enum class num_type : char {
Signed_integer,
Unsigned_integer,
Floating_point,
Null,
Double_precision_floating_point
};
class rvalue;
rvalue load(const char *data, size_t size);
namespace detail {
/// A read string implementation with comparison functionality.
struct r_string {
r_string() {}
r_string(char *s, char *e) : s_(s), e_(e) {}
~r_string() {
if (owned_) delete[] s_;
}
r_string(const r_string &r) { *this = r; }
r_string(r_string &&r) { *this = r; }
r_string &operator=(r_string &&r) {
s_ = r.s_;
e_ = r.e_;
owned_ = r.owned_;
if (r.owned_) r.owned_ = 0;
return *this;
}
r_string &operator=(const r_string &r) {
s_ = r.s_;
e_ = r.e_;
owned_ = 0;
return *this;
}
operator std::string() const { return std::string(s_, e_); }
const char *begin() const { return s_; }
const char *end() const { return e_; }
size_t size() const { return end() - begin(); }
using iterator = const char *;
using const_iterator = const char *;
char *s_; ///< Start.
mutable char *e_; ///< End.
uint8_t owned_{0};
friend std::ostream &operator<<(std::ostream &os, const r_string &s) {
os << static_cast<std::string>(s);
return os;
}
private:
void force(char *s, uint32_t length) {
s_ = s;
e_ = s_ + length;
owned_ = 1;
}
friend rvalue crow::json::load(const char *data, size_t size);
friend bool operator==(const r_string &l, const r_string &r);
friend bool operator==(const std::string &l, const r_string &r);
friend bool operator==(const r_string &l, const std::string &r);
template <typename T, typename U>
inline static bool equals(const T &l, const U &r) {
if (l.size() != r.size()) return false;
for (size_t i = 0; i < l.size(); i++) {
if (*(l.begin() + i) != *(r.begin() + i)) return false;
}
return true;
}
};
inline bool operator<(const r_string &l, const r_string &r) {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
inline bool operator<(const r_string &l, const std::string &r) {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
inline bool operator<(const std::string &l, const r_string &r) {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
inline bool operator>(const r_string &l, const r_string &r) {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
inline bool operator>(const r_string &l, const std::string &r) {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
inline bool operator>(const std::string &l, const r_string &r) {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
inline bool operator==(const r_string &l, const r_string &r) {
return r_string::equals(l, r);
}
inline bool operator==(const r_string &l, const std::string &r) {
return r_string::equals(l, r);
}
inline bool operator==(const std::string &l, const r_string &r) {
return r_string::equals(l, r);
}
inline bool operator!=(const r_string &l, const r_string &r) {
return !(l == r);
}
inline bool operator!=(const r_string &l, const std::string &r) {
return !(l == r);
}
inline bool operator!=(const std::string &l, const r_string &r) {
return !(l == r);
}
} // namespace detail
/// JSON read value.
///
/// Value can mean any json value, including a JSON object.
/// Read means this class is used to primarily read strings into a JSON value.
class rvalue {
static const int cached_bit = 2;
static const int error_bit = 4;
public:
rvalue() noexcept : option_{error_bit} {}
rvalue(type t) noexcept : lsize_{}, lremain_{}, t_{t} {}
rvalue(type t, char *s, char *e) noexcept : start_{s}, end_{e}, t_{t} {
determine_num_type();
}
rvalue(const rvalue &r)
: start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_),
option_(r.option_) {
copy_l(r);
}
rvalue(rvalue &&r) noexcept { *this = std::move(r); }
rvalue &operator=(const rvalue &r) {
start_ = r.start_;
end_ = r.end_;
key_ = r.key_;
t_ = r.t_;
nt_ = r.nt_;
option_ = r.option_;
copy_l(r);
return *this;
}
rvalue &operator=(rvalue &&r) noexcept {
start_ = r.start_;
end_ = r.end_;
key_ = std::move(r.key_);
l_ = std::move(r.l_);
lsize_ = r.lsize_;
lremain_ = r.lremain_;
t_ = r.t_;
nt_ = r.nt_;
option_ = r.option_;
return *this;
}
explicit operator bool() const noexcept { return (option_ & error_bit) == 0; }
explicit operator int64_t() const { return i(); }
explicit operator uint64_t() const { return u(); }
explicit operator int() const { return static_cast<int>(i()); }
/// Return any json value (not object or list) as a string.
explicit operator std::string() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() == type::Object || t() == type::List)
throw std::runtime_error("json type container");
#endif
switch (t()) {
case type::String: return std::string(s());
case type::Null: return std::string("null");
case type::True: return std::string("true");
case type::False: return std::string("false");
default: return std::string(start_, end_ - start_);
}
}
/// The type of the JSON value.
type t() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (option_ & error_bit) {
throw std::runtime_error("invalid json object");
}
#endif
return t_;
}
/// The number type of the JSON value.
num_type nt() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (option_ & error_bit) {
throw std::runtime_error("invalid json object");
}
#endif
return nt_;
}
/// The integer value.
int64_t i() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
switch (t()) {
case type::Number:
case type::String:
return utility::lexical_cast<int64_t>(start_, end_ - start_);
default:
const std::string msg =
"expected number, got: " + std::string(get_type_str(t()));
throw std::runtime_error(msg);
}
#endif
return utility::lexical_cast<int64_t>(start_, end_ - start_);
}
/// The unsigned integer value.
uint64_t u() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
switch (t()) {
case type::Number:
case type::String:
return utility::lexical_cast<uint64_t>(start_, end_ - start_);
default:
throw std::runtime_error(std::string("expected number, got: ") +
get_type_str(t()));
}
#endif
return utility::lexical_cast<uint64_t>(start_, end_ - start_);
}
/// The double precision floating-point number value.
double d() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::Number) throw std::runtime_error("value is not number");
#endif
return utility::lexical_cast<double>(start_, end_ - start_);
}
/// The boolean value.
bool b() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::True && t() != type::False)
throw std::runtime_error("value is not boolean");
#endif
return t() == type::True;
}
/// The string value.
detail::r_string s() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::String) throw std::runtime_error("value is not string");
#endif
unescape();
return detail::r_string{start_, end_};
}
/// The list or object value
std::vector<rvalue> lo() const {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::Object && t() != type::List)
throw std::runtime_error("value is not a container");
#endif
std::vector<rvalue> ret;
ret.reserve(lsize_);
for (uint32_t i = 0; i < lsize_; i++) {
ret.emplace_back(l_[i]);
}
return ret;
}
/// Convert escaped string character to their original form ("\\n" -> '\n').
void unescape() const {
if (*(start_ - 1)) {
char *head = start_;
char *tail = start_;
while (head != end_) {
if (*head == '\\') {
switch (*++head) {
case '"': *tail++ = '"'; break;
case '\\': *tail++ = '\\'; break;
case '/': *tail++ = '/'; break;
case 'b': *tail++ = '\b'; break;
case 'f': *tail++ = '\f'; break;
case 'n': *tail++ = '\n'; break;
case 'r': *tail++ = '\r'; break;
case 't': *tail++ = '\t'; break;
case 'u': {
auto from_hex = [](char c) {
if (c >= 'a') return c - 'a' + 10;
if (c >= 'A') return c - 'A' + 10;
return c - '0';
};
unsigned int code = (from_hex(head[1]) << 12) +
(from_hex(head[2]) << 8) +
gitextract_7tv2227u/
├── .gitattributes
├── .github/
│ └── workflows/
│ ├── abidiff.yaml
│ ├── cifuzz.yaml
│ ├── docs.yml
│ ├── release-docker.yml
│ ├── test-32bit.yml
│ ├── test.yaml
│ ├── test_benchmark.yaml
│ ├── test_no_exceptions.yaml
│ ├── test_offline.yaml
│ └── test_proxy.yaml
├── CMakeLists.txt
├── Dockerfile
├── LICENSE
├── README-sse.md
├── README-stream.md
├── README-websocket.md
├── README.md
├── benchmark/
│ ├── Makefile
│ ├── cpp-httplib/
│ │ └── main.cpp
│ └── crow/
│ ├── crow_all.h
│ └── main.cpp
├── cmake/
│ ├── FindBrotli.cmake
│ ├── httplibConfig.cmake.in
│ └── modules.cmake
├── docker/
│ ├── html/
│ │ └── index.html
│ └── main.cc
├── docker-compose.yml
├── docs-src/
│ ├── config.toml
│ └── pages/
│ ├── en/
│ │ ├── cookbook/
│ │ │ └── index.md
│ │ ├── index.md
│ │ ├── llm-app/
│ │ │ └── index.md
│ │ └── tour/
│ │ ├── 01-getting-started.md
│ │ ├── 02-basic-client.md
│ │ ├── 03-basic-server.md
│ │ ├── 04-static-file-server.md
│ │ ├── 05-tls-setup.md
│ │ ├── 06-https-client.md
│ │ ├── 07-https-server.md
│ │ ├── 08-websocket.md
│ │ ├── 09-whats-next.md
│ │ └── index.md
│ └── ja/
│ ├── cookbook/
│ │ └── index.md
│ ├── index.md
│ ├── llm-app/
│ │ └── index.md
│ └── tour/
│ ├── 01-getting-started.md
│ ├── 02-basic-client.md
│ ├── 03-basic-server.md
│ ├── 04-static-file-server.md
│ ├── 05-tls-setup.md
│ ├── 06-https-client.md
│ ├── 07-https-server.md
│ ├── 08-websocket.md
│ ├── 09-whats-next.md
│ └── index.md
├── example/
│ ├── Dockerfile.hello
│ ├── Makefile
│ ├── accept_header.cc
│ ├── benchmark.cc
│ ├── ca-bundle.crt
│ ├── client.cc
│ ├── client.vcxproj
│ ├── example.sln
│ ├── hello.cc
│ ├── one_time_request.cc
│ ├── redirect.cc
│ ├── server.cc
│ ├── server.vcxproj
│ ├── server_and_client.cc
│ ├── simplecli.cc
│ ├── simplesvr.cc
│ ├── ssecli-stream.cc
│ ├── ssecli.cc
│ ├── ssesvr.cc
│ ├── upload.cc
│ ├── uploader.sh
│ └── wsecho.cc
├── generate_module.py
├── httplib.h
├── justfile
├── meson.build
├── meson_options.txt
├── split.py
└── test/
├── CMakeLists.txt
├── Makefile
├── ca-bundle.crt
├── fuzzing/
│ ├── CMakeLists.txt
│ ├── Makefile
│ ├── corpus/
│ │ ├── 1
│ │ ├── 2
│ │ ├── 3
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5372331946541056
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5386708825800704
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5667822731132928
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5886572146327552
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-5942767436562432
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-6007379124158464
│ │ ├── clusterfuzz-testcase-minimized-server_fuzzer-6508706672541696
│ │ └── issue1264
│ ├── server_fuzzer.cc
│ ├── server_fuzzer.dict
│ └── standalone_fuzz_target_runner.cpp
├── gen-certs.sh
├── gtest/
│ ├── include/
│ │ └── gtest/
│ │ ├── gtest-assertion-result.h
│ │ ├── gtest-death-test.h
│ │ ├── gtest-matchers.h
│ │ ├── gtest-message.h
│ │ ├── gtest-param-test.h
│ │ ├── gtest-printers.h
│ │ ├── gtest-spi.h
│ │ ├── gtest-test-part.h
│ │ ├── gtest-typed-test.h
│ │ ├── gtest.h
│ │ ├── gtest_pred_impl.h
│ │ ├── gtest_prod.h
│ │ └── internal/
│ │ ├── custom/
│ │ │ ├── README.md
│ │ │ ├── gtest-port.h
│ │ │ ├── gtest-printers.h
│ │ │ └── gtest.h
│ │ ├── gtest-death-test-internal.h
│ │ ├── gtest-filepath.h
│ │ ├── gtest-internal.h
│ │ ├── gtest-param-util.h
│ │ ├── gtest-port-arch.h
│ │ ├── gtest-port.h
│ │ ├── gtest-string.h
│ │ └── gtest-type-util.h
│ └── src/
│ ├── gtest-all.cc
│ ├── gtest-assertion-result.cc
│ ├── gtest-death-test.cc
│ ├── gtest-filepath.cc
│ ├── gtest-internal-inl.h
│ ├── gtest-matchers.cc
│ ├── gtest-port.cc
│ ├── gtest-printers.cc
│ ├── gtest-test-part.cc
│ ├── gtest-typed-test.cc
│ ├── gtest.cc
│ └── gtest_main.cc
├── include_httplib.cc
├── include_windows_h.cc
├── lsan_suppressions.txt
├── make-shared-library.sh
├── meson.build
├── proxy/
│ ├── Dockerfile
│ ├── basic_passwd
│ ├── basic_squid.conf
│ ├── digest_passwd
│ ├── digest_squid.conf
│ ├── docker-compose.ci.yml
│ └── docker-compose.yml
├── test.cc
├── test.conf
├── test.rootCA.conf
├── test.sln
├── test.vcxproj
├── test_32bit_build.cpp
├── test_benchmark.cc
├── test_proxy.cc
├── test_thread_pool.cc
├── test_websocket_heartbeat.cc
├── www/
│ ├── dir/
│ │ ├── 1MB.txt
│ │ ├── index.html
│ │ ├── meson.build
│ │ ├── test.abcde
│ │ └── test.html
│ ├── empty_file
│ ├── file
│ ├── meson.build
│ └── 日本語Dir/
│ ├── meson.build
│ └── 日本語File.txt
├── www2/
│ └── dir/
│ ├── index.html
│ ├── meson.build
│ └── test.html
└── www3/
└── dir/
├── index.html
├── meson.build
└── test.html
Showing preview only (589K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2029 symbols across 59 files)
FILE: benchmark/cpp-httplib/main.cpp
function main (line 4) | int main() {
FILE: benchmark/crow/crow_all.h
function namespace (line 44) | namespace crow // NOTE: Already documented in "crow/app.h"
function namespace (line 132) | namespace crow {
function namespace (line 175) | namespace sha1 {
function namespace (line 357) | namespace crow {
function qs_decode (line 490) | inline int qs_decode(char *qs) {
function namespace (line 614) | namespace crow {
function namespace (line 1004) | namespace crow {
function raw_socket (line 1063) | struct UnixSocketAdaptor {
function is_open (line 1080) | bool is_open() { return socket_.is_open(); }
function close (line 1082) | void close() {
function shutdown_readwrite (line 1087) | void shutdown_readwrite() {
function shutdown_write (line 1092) | void shutdown_write() {
function shutdown_read (line 1097) | void shutdown_read() {
function raw_socket (line 1108) | struct SSLAdaptor {
function is_open (line 1126) | bool is_open() { return ssl_socket_ ? raw_socket().is_open() : false; }
function close (line 1128) | void close() {
function shutdown_readwrite (line 1135) | void shutdown_readwrite() {
function shutdown_write (line 1143) | void shutdown_write() {
function shutdown_read (line 1151) | void shutdown_read() {
function namespace (line 1178) | namespace crow {
type state (line 4569) | enum state
type header_states (line 4646) | enum header_states
type http_host_state (line 4677) | enum http_host_state
function parse_url_char (line 4739) | inline enum state
function http_parser_execute (line 4888) | inline size_t http_parser_execute (http_parser *parser,
function http_parser_init (line 6184) | inline void
type http_errno (line 6196) | enum http_errno
type http_errno (line 6212) | enum http_errno
function http_body_is_final (line 6227) | inline int
function http_parser_set_max_header_size (line 6233) | inline void
function namespace (line 6288) | namespace crow {
function namespace (line 6522) | namespace crow {
function namespace (line 7732) | namespace crow {
function namespace (line 8023) | namespace crow {
function clear (line 8157) | void clear() {
function redirect (line 8169) | void redirect(const std::string &location) {
function redirect_perm (line 8178) | void redirect_perm(const std::string &location) {
function moved (line 8187) | void moved(const std::string &location) {
function moved_perm (line 8196) | void moved_perm(const std::string &location) {
function write (line 8201) | void write(const std::string &body_part) { body += body_part; }
function end (line 8205) | void end() {
function end (line 8222) | void end(const std::string &body_part) {
function is_alive (line 8229) | bool is_alive() { return is_alive_helper_ && is_alive_helper_(); }
function is_static_type (line 8232) | bool is_static_type() { return file_info.path.size(); }
type static_file_info (line 8239) | struct static_file_info {
function completed_ (line 8410) | bool completed_{}
function namespace (line 8420) | namespace crow {
function std (line 8487) | const std::string &name() { return key_; }
function set_cookie (line 8572) | struct context {
function before_handle (line 8597) | void before_handle(request &req, response &res, context &ctx) {
function namespace (line 8736) | namespace session {
function remove (line 8795) | struct ExpirationTracker {
type CachedSession (line 8841) | struct CachedSession {
function exists (line 8866) | struct context {
function contains (line 8904) | bool contains(const std::string &key) {
function remove (line 8921) | void remove(const std::string &key) {
function refresh_expiration (line 8951) | void refresh_expiration() {
function check_node (line 8959) | void check_node() {
function store_id (line 9059) | void store_id(CookieParser::context &cookies, const std::string &session...
function save (line 9079) | struct InMemoryStore {
function contains (line 9093) | bool contains(const std::string &key) { return entries.count(key) > 0; }
type middleware_call_criteria_dynamic (line 9490) | struct middleware_call_criteria_dynamic
type middleware_call_criteria_dynamic (line 9507) | struct middleware_call_criteria_dynamic
function namespace (line 9527) | namespace crow {
function namespace (line 9597) | namespace crow {
function start (line 9651) | void start() {
function handle_url (line 9665) | void handle_url() {
function handle_header (line 9677) | void handle_header() {
function handle (line 9696) | void handle() {
function complete_request (line 9770) | void complete_request() {
function do_write_static (line 9832) | void do_write_static() {
function namespace (line 10087) | namespace crow // NOTE: Already documented in "crow/app.h"
function set_tick_function (line 10148) | void set_tick_function(std::chrono::milliseconds d, std::function<void()...
function on_tick (line 10153) | void on_tick() {
function run (line 10163) | void run() {
function stop (line 10259) | void stop() {
function namespace (line 10390) | namespace crow // NOTE: Already documented in "crow/app.h"
type SendMessageType (line 11061) | struct SendMessageType {
function send_data_impl (line 11069) | void send_data_impl(SendMessageType *s) {
function SendMessageType (line 11077) | SendMessageType event_arg{std::move(msg), this, opcode};
function WebSocketReadState (line 11114) | WebSocketReadState state_{WebSocketReadState::MiniHeader};
function handle (line 13252) | void handle(request &req, response &res,
function handle_full (line 13259) | void handle_full(request &req, response &res) {
function websocket_max_payload (line 13288) | uint64_t websocket_max_payload() { return max_payload_; }
function address_is_bound (line 13323) | void address_is_bound() { is_bound_ = true; }
function stream_threshold (line 13402) | size_t &stream_threshold() { return res_stream_threshold_; }
function add_blueprint (line 13446) | void add_blueprint() {
function add_static_dir (line 13474) | void add_static_dir() {
function validate (line 13489) | void validate() { router_.validate(); }
function else (line 13721) | else if (ssl_server_) {
function fwd (line 13732) | auto fwd = std::forward_as_tuple((ts)...);
function set_static_routes_added (line 13744) | void set_static_routes_added() { static_routes_added_ = true; }
function are_static_routes_added (line 13746) | bool are_static_routes_added() { return static_routes_added_; }
function server_started_ (line 13782) | bool server_started_{false};
FILE: benchmark/crow/main.cpp
class CustomLogger (line 3) | class CustomLogger : public crow::ILogHandler {
method log (line 5) | void log(const std::string &, crow::LogLevel) {}
function main (line 8) | int main() {
FILE: docker/main.cc
function signal_handler (line 26) | void signal_handler(int signal) {
function get_time_format (line 33) | std::string get_time_format() {
function get_error_time_format (line 42) | std::string get_error_time_format() {
function nginx_access_logger (line 54) | void nginx_access_logger(const Request &req, const Response &res) {
function nginx_error_logger (line 76) | void nginx_error_logger(const Error &err, const Request *req) {
function print_usage (line 98) | void print_usage(const char *program_name) {
type ServerConfig (line 129) | struct ServerConfig {
type ParseResult (line 137) | enum class ParseResult { SUCCESS, HELP_REQUESTED, VERSION_REQUESTED, ERR...
function ParseResult (line 139) | ParseResult parse_command_line(int argc, char *argv[], ServerConfig &con...
function setup_server (line 210) | bool setup_server(Server &svr, const ServerConfig &config) {
function main (line 269) | int main(int argc, char *argv[]) {
FILE: example/accept_header.cc
function main (line 4) | int main() {
FILE: example/benchmark.cc
type StopWatch (line 7) | struct StopWatch {
method StopWatch (line 8) | StopWatch(const string &label) : label_(label) {
function main (line 21) | int main(void) {
FILE: example/client.cc
function main (line 15) | int main(void) {
FILE: example/hello.cc
function main (line 11) | int main(void) {
FILE: example/one_time_request.cc
function one_time_request_server (line 9) | void one_time_request_server(const char *label) {
function send_request (line 26) | void send_request(const char *label) {
function main (line 39) | int main(void) {
FILE: example/redirect.cc
function main (line 15) | int main(void) {
FILE: example/server.cc
function dump_headers (line 17) | std::string dump_headers(const Headers &headers) {
function log (line 30) | std::string log(const Request &req, const Response &res) {
function main (line 67) | int main(void) {
FILE: example/server_and_client.cc
function dump_headers (line 14) | std::string dump_headers(const Headers &headers) {
function logger (line 27) | void logger(const Request &req, const Response &res) {
function main (line 64) | int main(void) {
FILE: example/simplecli.cc
function main (line 13) | int main(void) {
FILE: example/simplesvr.cc
function string (line 18) | string dump_headers(const Headers &headers) {
function string (line 30) | string dump_multipart_formdata(const MultipartFormData &form) {
function string (line 71) | string log(const Request &req, const Response &res) {
function main (line 104) | int main(int argc, const char **argv) {
FILE: example/ssecli-stream.cc
type SSEEvent (line 29) | struct SSEEvent {
method clear (line 34) | void clear() {
function parse_sse_line (line 43) | bool parse_sse_line(const std::string &line, SSEEvent &event, int &retry...
function main (line 92) | int main(void) {
FILE: example/ssecli.cc
function signal_handler (line 18) | void signal_handler(int) {
function main (line 22) | int main(void) {
FILE: example/ssesvr.cc
class EventDispatcher (line 13) | class EventDispatcher {
method EventDispatcher (line 15) | EventDispatcher() {}
method wait_event (line 17) | bool wait_event(DataSink *sink) {
method send_event (line 31) | void send_event(const string &message) {
function main (line 68) | int main(void) {
FILE: example/upload.cc
function main (line 32) | int main(void) {
FILE: example/wsecho.cc
function main (line 105) | int main(void) {
FILE: generate_module.py
function main (line 10) | def main() -> None:
FILE: httplib.h
function namespace (line 503) | namespace httplib {
function from_chars_result (line 679) | inline from_chars_result<double> from_chars(const char *first, const cha...
function parse_port (line 692) | inline bool parse_port(const char *s, size_t len, int &port) {
function parse_port (line 700) | inline bool parse_port(const std::string &s, int &port) {
type SSLVerifierResponse (line 706) | enum SSLVerifierResponse {
type StatusCode (line 715) | enum StatusCode {
function T (line 815) | T *any_cast(const any *a) noexcept {
function class (line 824) | class bad_any_cast : public std::bad_cast {
function namespace (line 829) | namespace detail {
function class (line 858) | class any {
function reset (line 885) | void reset() noexcept { storage_.reset(); }
function T (line 897) | T *any_cast(const any *a) noexcept {
function throw (line 908) | throw bad_any_cast{}
function throw (line 920) | throw bad_any_cast{}
function throw (line 932) | throw bad_any_cast{}
type Response (line 941) | struct Response
type FormData (line 944) | struct FormData {
type FormField (line 952) | struct FormField {
type MultipartFormData (line 961) | struct MultipartFormData {
type UploadFormData (line 978) | struct UploadFormData {
function class (line 986) | class DataSink {
type FormDataProvider (line 1027) | struct FormDataProvider {
function FormDataProvider (line 1035) | inline FormDataProvider
function ContentProvider (line 1069) | ContentProvider provider = [filepath](size_t offset, size_t length,
function class (line 1097) | class ContentReader {
function const (line 1111) | bool operator()(ContentReceiver receiver) const {
function namespace (line 1124) | namespace tls {
function enqueue (line 9957) | inline bool ThreadPool::enqueue(std::function<void()> fn) {
function shutdown (line 9978) | inline void ThreadPool::shutdown() {
function namespace (line 10076) | namespace detail {
function is_peer_alive (line 10129) | inline bool SocketStream::is_peer_alive() const {
function write (line 10195) | inline ssize_t SocketStream::write(const char *ptr, size_t size) {
function get_remote_ip_and_port (line 10206) | inline void SocketStream::get_remote_ip_and_port(std::string &ip,
function get_local_ip_and_port (line 10211) | inline void SocketStream::get_local_ip_and_port(std::string &ip,
function time_t (line 10218) | inline time_t SocketStream::duration() const {
function read (line 10236) | inline ssize_t BufferStream::read(char *ptr, size_t size) {
function write (line 10246) | inline ssize_t BufferStream::write(const char *ptr, size_t size) {
function get_remote_ip_and_port (line 10251) | inline void BufferStream::get_remote_ip_and_port(std::string & /*ip*/,
function get_local_ip_and_port (line 10254) | inline void BufferStream::get_local_ip_and_port(std::string & /*ip*/,
function PathParamsMatcher (line 10263) | inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern)
function match (line 10312) | inline bool PathParamsMatcher::match(Request &request) const {
function match (line 10355) | inline bool RegexMatcher::match(Request &request) const {
function std (line 10361) | inline std::string prepare_host_string(const std::string &host) {
function std (line 10373) | inline std::string make_host_and_port_string(const std::string &host, in...
function std (line 10388) | inline std::string
function is_readable (line 10442) | inline bool SSLSocketStream::is_readable() const {
function is_peer_alive (line 10464) | inline bool SSLSocketStream::is_peer_alive() const {
function check_if_not_modified (line 11348) | inline bool Server::check_if_not_modified(const Request &req, Response &...
function check_if_range (line 11389) | inline bool Server::check_if_range(Request &req, const std::string &etag,
function socket_t (line 11423) | inline socket_t
function bind_internal (line 11443) | inline int Server::bind_internal(const std::string &host, int port,
function listen_internal (line 11473) | inline bool Server::listen_internal() {
function read (line 12647) | inline ssize_t ClientImpl::StreamHandle::read(char *buf, size_t len) {
function read_with_decompression (line 12671) | inline ssize_t ClientImpl::StreamHandle::read_with_decompression(char *buf,
function parse_trailers_if_needed (line 12720) | inline void ClientImpl::StreamHandle::parse_trailers_if_needed() {
function namespace (line 12739) | namespace detail {
function transfer_socket_ownership_to_handle (line 12799) | inline void
function handle_request (line 12809) | inline bool ClientImpl::handle_request(Stream &strm, Request &req,
function redirect (line 12889) | inline bool ClientImpl::redirect(Request &req, Response &res, Error &err...
function create_redirect_client (line 12938) | inline bool ClientImpl::create_redirect_client(
function ContentProviderWithoutLength (line 13593) | inline ContentProviderWithoutLength ClientImpl::get_multipart_content_pr...
function process_socket (line 13637) | inline bool ClientImpl::process_socket(
function Result (line 13648) | inline Result ClientImpl::Get(const std::string &path,
function Result (line 13653) | inline Result ClientImpl::Get(const std::string &path, const Params &par...
function Result (line 13662) | inline Result ClientImpl::Get(const std::string &path, const Headers &he...
function Result (line 13676) | inline Result ClientImpl::Get(const std::string &path,
function Result (line 13683) | inline Result ClientImpl::Get(const std::string &path, const Headers &he...
function Result (line 13690) | inline Result ClientImpl::Get(const std::string &path,
function Result (line 13698) | inline Result ClientImpl::Get(const std::string &path, const Headers &he...
function Result (line 13720) | inline Result ClientImpl::Get(const std::string &path, const Params &par...
function Result (line 13728) | inline Result ClientImpl::Get(const std::string &path, const Params &par...
function Result (line 13743) | inline Result ClientImpl::Head(const std::string &path) {
function Result (line 13747) | inline Result ClientImpl::Head(const std::string &path,
function Result (line 13760) | inline Result ClientImpl::Post(const std::string &path) {
function Result (line 13764) | inline Result ClientImpl::Post(const std::string &path,
function Result (line 13769) | inline Result ClientImpl::Post(const std::string &path, const char *body,
function Result (line 13776) | inline Result ClientImpl::Post(const std::string &path, const std::strin...
function Result (line 13782) | inline Result ClientImpl::Post(const std::string &path, const Params &pa...
function Result (line 13786) | inline Result ClientImpl::Post(const std::string &path, size_t content_l...
function Result (line 13794) | inline Result ClientImpl::Post(const std::string &path, size_t content_l...
function Result (line 13803) | inline Result ClientImpl::Post(const std::string &path,
function Result (line 13811) | inline Result ClientImpl::Post(const std::string &path,
function Result (line 13820) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13826) | inline Result ClientImpl::Post(const std::string &path,
function Result (line 13832) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13844) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13860) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13869) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13878) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13888) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13900) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13909) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13919) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13932) | inline Result ClientImpl::Post(const std::string &path, const Headers &h...
function Result (line 13958) | inline Result ClientImpl::Put(const std::string &path) {
function Result (line 13962) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 13966) | inline Result ClientImpl::Put(const std::string &path, const char *body,
function Result (line 13973) | inline Result ClientImpl::Put(const std::string &path, const std::string...
function Result (line 13979) | inline Result ClientImpl::Put(const std::string &path, const Params &par...
function Result (line 13983) | inline Result ClientImpl::Put(const std::string &path, size_t content_le...
function Result (line 13991) | inline Result ClientImpl::Put(const std::string &path, size_t content_le...
function Result (line 14000) | inline Result ClientImpl::Put(const std::string &path,
function Result (line 14008) | inline Result ClientImpl::Put(const std::string &path,
function Result (line 14017) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14023) | inline Result ClientImpl::Put(const std::string &path,
function Result (line 14029) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14041) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14057) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14066) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14075) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14085) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14097) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14106) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14116) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14129) | inline Result ClientImpl::Put(const std::string &path, const Headers &he...
function Result (line 14155) | inline Result ClientImpl::Patch(const std::string &path) {
function Result (line 14159) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14164) | inline Result ClientImpl::Patch(const std::string &path, const char *body,
function Result (line 14171) | inline Result ClientImpl::Patch(const std::string &path,
function Result (line 14178) | inline Result ClientImpl::Patch(const std::string &path, const Params &p...
function Result (line 14182) | inline Result ClientImpl::Patch(const std::string &path, size_t content_...
function Result (line 14190) | inline Result ClientImpl::Patch(const std::string &path, size_t content_...
function Result (line 14199) | inline Result ClientImpl::Patch(const std::string &path,
function Result (line 14207) | inline Result ClientImpl::Patch(const std::string &path,
function Result (line 14216) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14222) | inline Result ClientImpl::Patch(const std::string &path,
function Result (line 14228) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14240) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14256) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14265) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14274) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14284) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14296) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14305) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14315) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14328) | inline Result ClientImpl::Patch(const std::string &path, const Headers &...
function Result (line 14354) | inline Result ClientImpl::Delete(const std::string &path,
function Result (line 14359) | inline Result ClientImpl::Delete(const std::string &path,
function Result (line 14365) | inline Result ClientImpl::Delete(const std::string &path, const char *body,
function Result (line 14372) | inline Result ClientImpl::Delete(const std::string &path,
function Result (line 14380) | inline Result ClientImpl::Delete(const std::string &path,
function Result (line 14389) | inline Result ClientImpl::Delete(const std::string &path, const Params &...
function Result (line 14394) | inline Result ClientImpl::Delete(const std::string &path,
function Result (line 14402) | inline Result ClientImpl::Delete(const std::string &path,
function Result (line 14422) | inline Result ClientImpl::Options(const std::string &path) {
function Result (line 14426) | inline Result ClientImpl::Options(const std::string &path,
function stop (line 14439) | inline void ClientImpl::stop() {
function set_connection_timeout (line 14473) | inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) {
function set_read_timeout (line 14478) | inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) {
function set_write_timeout (line 14483) | inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) {
function set_max_timeout (line 14488) | inline void ClientImpl::set_max_timeout(time_t msec) {
function set_basic_auth (line 14492) | inline void ClientImpl::set_basic_auth(const std::string &username,
function set_bearer_token_auth (line 14498) | inline void ClientImpl::set_bearer_token_auth(const std::string &token) {
function set_keep_alive (line 14502) | inline void ClientImpl::set_keep_alive(bool on) { keep_alive_ = on; }
function set_follow_location (line 14504) | inline void ClientImpl::set_follow_location(bool on) { follow_location_ ...
function set_path_encode (line 14506) | inline void ClientImpl::set_path_encode(bool on) { path_encode_ = on; }
function set_hostname_addr_map (line 14508) | inline void
function set_default_headers (line 14513) | inline void ClientImpl::set_default_headers(Headers headers) {
function set_header_writer (line 14517) | inline void ClientImpl::set_header_writer(
function set_address_family (line 14522) | inline void ClientImpl::set_address_family(int family) {
function set_tcp_nodelay (line 14526) | inline void ClientImpl::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; }
function set_ipv6_v6only (line 14528) | inline void ClientImpl::set_ipv6_v6only(bool on) { ipv6_v6only_ = on; }
function set_socket_options (line 14530) | inline void ClientImpl::set_socket_options(SocketOptions socket_options) {
function set_compress (line 14534) | inline void ClientImpl::set_compress(bool on) { compress_ = on; }
function set_decompress (line 14536) | inline void ClientImpl::set_decompress(bool on) { decompress_ = on; }
function set_payload_max_length (line 14538) | inline void ClientImpl::set_payload_max_length(size_t length) {
function set_interface (line 14543) | inline void ClientImpl::set_interface(const std::string &intf) {
function set_proxy (line 14547) | inline void ClientImpl::set_proxy(const std::string &host, int port) {
function set_proxy_basic_auth (line 14552) | inline void ClientImpl::set_proxy_basic_auth(const std::string &username,
function set_proxy_bearer_token_auth (line 14558) | inline void ClientImpl::set_proxy_bearer_token_auth(const std::string &t...
function set_digest_auth (line 14563) | inline void ClientImpl::set_digest_auth(const std::string &username,
function set_ca_cert_path (line 14569) | inline void ClientImpl::set_ca_cert_path(const std::string &ca_cert_file...
function set_proxy_digest_auth (line 14575) | inline void ClientImpl::set_proxy_digest_auth(const std::string &username,
function enable_server_certificate_verification (line 14581) | inline void ClientImpl::enable_server_certificate_verification(bool enab...
function enable_server_hostname_verification (line 14585) | inline void ClientImpl::enable_server_hostname_verification(bool enabled) {
function X509_STORE (line 14592) | inline X509_STORE *ClientImpl::create_ca_cert_store(const char *ca_cert,
function set_server_certificate_verifier (line 14616) | inline void ClientImpl::set_server_certificate_verifier(
function set_logger (line 14622) | inline void ClientImpl::set_logger(Logger logger) {
function set_error_logger (line 14626) | inline void ClientImpl::set_error_logger(ErrorLogger error_logger) {
function ClientConnection (line 14634) | inline ClientConnection::~ClientConnection() {
function Client (line 14650) | inline Client::Client(const std::string &scheme_host_port)
function Client (line 14702) | inline Client::Client(const std::string &host, int port)
function Client (line 14705) | inline Client::Client(const std::string &host, int port,
function Result (line 14717) | inline Result Client::Get(const std::string &path, DownloadProgress prog...
function Result (line 14720) | inline Result Client::Get(const std::string &path, const Headers &headers,
function Result (line 14724) | inline Result Client::Get(const std::string &path,
function Result (line 14729) | inline Result Client::Get(const std::string &path, const Headers &headers,
function Result (line 14735) | inline Result Client::Get(const std::string &path,
function Result (line 14742) | inline Result Client::Get(const std::string &path, const Headers &headers,
function Result (line 14749) | inline Result Client::Get(const std::string &path, const Params ¶ms,
function Result (line 14753) | inline Result Client::Get(const std::string &path, const Params ¶ms,
function Result (line 14760) | inline Result Client::Get(const std::string &path, const Params ¶ms,
function Result (line 14769) | inline Result Client::Head(const std::string &path) { return cli_->Head(...
function Result (line 14770) | inline Result Client::Head(const std::string &path, const Headers &heade...
function Result (line 14774) | inline Result Client::Post(const std::string &path) { return cli_->Post(...
function Result (line 14775) | inline Result Client::Post(const std::string &path, const Headers &heade...
function Result (line 14778) | inline Result Client::Post(const std::string &path, const char *body,
function Result (line 14784) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14791) | inline Result Client::Post(const std::string &path, const std::string &b...
function Result (line 14796) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14802) | inline Result Client::Post(const std::string &path, size_t content_length,
function Result (line 14809) | inline Result Client::Post(const std::string &path, size_t content_length,
function Result (line 14817) | inline Result Client::Post(const std::string &path,
function Result (line 14823) | inline Result Client::Post(const std::string &path,
function Result (line 14831) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14839) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14848) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14855) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14863) | inline Result Client::Post(const std::string &path, const Params ¶ms) {
function Result (line 14866) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14870) | inline Result Client::Post(const std::string &path,
function Result (line 14875) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14880) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14886) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14892) | inline Result Client::Post(const std::string &path, const Headers &headers,
function Result (line 14901) | inline Result Client::Put(const std::string &path) { return cli_->Put(pa...
function Result (line 14902) | inline Result Client::Put(const std::string &path, const Headers &header...
function Result (line 14905) | inline Result Client::Put(const std::string &path, const char *body,
function Result (line 14911) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14917) | inline Result Client::Put(const std::string &path, const std::string &body,
function Result (line 14922) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14928) | inline Result Client::Put(const std::string &path, size_t content_length,
function Result (line 14935) | inline Result Client::Put(const std::string &path, size_t content_length,
function Result (line 14943) | inline Result Client::Put(const std::string &path,
function Result (line 14949) | inline Result Client::Put(const std::string &path,
function Result (line 14957) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14965) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14974) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14981) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14989) | inline Result Client::Put(const std::string &path, const Params ¶ms) {
function Result (line 14992) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 14996) | inline Result Client::Put(const std::string &path,
function Result (line 15001) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 15006) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 15012) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 15018) | inline Result Client::Put(const std::string &path, const Headers &headers,
function Result (line 15027) | inline Result Client::Patch(const std::string &path) {
function Result (line 15030) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15033) | inline Result Client::Patch(const std::string &path, const char *body,
function Result (line 15039) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15046) | inline Result Client::Patch(const std::string &path, const std::string &...
function Result (line 15051) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15057) | inline Result Client::Patch(const std::string &path, size_t content_length,
function Result (line 15064) | inline Result Client::Patch(const std::string &path, size_t content_length,
function Result (line 15072) | inline Result Client::Patch(const std::string &path,
function Result (line 15078) | inline Result Client::Patch(const std::string &path,
function Result (line 15086) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15094) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15103) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15110) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15118) | inline Result Client::Patch(const std::string &path, const Params ¶m...
function Result (line 15121) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15125) | inline Result Client::Patch(const std::string &path,
function Result (line 15130) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15135) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15141) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15147) | inline Result Client::Patch(const std::string &path, const Headers &head...
function Result (line 15156) | inline Result Client::Delete(const std::string &path,
function Result (line 15160) | inline Result Client::Delete(const std::string &path, const Headers &hea...
function Result (line 15164) | inline Result Client::Delete(const std::string &path, const char *body,
function Result (line 15170) | inline Result Client::Delete(const std::string &path, const Headers &hea...
function Result (line 15177) | inline Result Client::Delete(const std::string &path, const std::string ...
function Result (line 15182) | inline Result Client::Delete(const std::string &path, const Headers &hea...
function Result (line 15188) | inline Result Client::Delete(const std::string &path, const Params ¶ms,
function Result (line 15192) | inline Result Client::Delete(const std::string &path, const Headers &hea...
function Result (line 15197) | inline Result Client::Options(const std::string &path) {
function Result (line 15200) | inline Result Client::Options(const std::string &path, const Headers &he...
function send (line 15211) | inline bool Client::send(Request &req, Response &res, Error &error) {
function Result (line 15215) | inline Result Client::send(const Request &req) { return cli_->send(req); }
function stop (line 15217) | inline void Client::stop() { cli_->stop(); }
function set_hostname_addr_map (line 15227) | inline void
function set_default_headers (line 15232) | inline void Client::set_default_headers(Headers headers) {
function set_header_writer (line 15236) | inline void Client::set_header_writer(
function set_address_family (line 15241) | inline void Client::set_address_family(int family) {
function set_tcp_nodelay (line 15245) | inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); }
function set_socket_options (line 15247) | inline void Client::set_socket_options(SocketOptions socket_options) {
function set_connection_timeout (line 15251) | inline void Client::set_connection_timeout(time_t sec, time_t usec) {
function set_read_timeout (line 15255) | inline void Client::set_read_timeout(time_t sec, time_t usec) {
function set_write_timeout (line 15259) | inline void Client::set_write_timeout(time_t sec, time_t usec) {
function set_basic_auth (line 15263) | inline void Client::set_basic_auth(const std::string &username,
function set_bearer_token_auth (line 15267) | inline void Client::set_bearer_token_auth(const std::string &token) {
function set_keep_alive (line 15271) | inline void Client::set_keep_alive(bool on) { cli_->set_keep_alive(on); }
function set_follow_location (line 15272) | inline void Client::set_follow_location(bool on) {
function set_path_encode (line 15276) | inline void Client::set_path_encode(bool on) { cli_->set_path_encode(on); }
function set_url_encode (line 15278) | [[deprecated("Use set_path_encode() instead. "
function set_compress (line 15284) | inline void Client::set_compress(bool on) { cli_->set_compress(on); }
function set_decompress (line 15286) | inline void Client::set_decompress(bool on) { cli_->set_decompress(on); }
function set_payload_max_length (line 15288) | inline void Client::set_payload_max_length(size_t length) {
function set_interface (line 15292) | inline void Client::set_interface(const std::string &intf) {
function set_proxy (line 15296) | inline void Client::set_proxy(const std::string &host, int port) {
function set_proxy_basic_auth (line 15299) | inline void Client::set_proxy_basic_auth(const std::string &username,
function set_proxy_bearer_token_auth (line 15303) | inline void Client::set_proxy_bearer_token_auth(const std::string &token) {
function set_logger (line 15307) | inline void Client::set_logger(Logger logger) {
function set_error_logger (line 15311) | inline void Client::set_error_logger(ErrorLogger error_logger) {
function SSLServer (line 15322) | inline SSLServer::SSLServer(const char *cert_path, const char *private_k...
function SSLServer (line 15354) | inline SSLServer::SSLServer(const PemMemory &pem) {
function SSLServer (line 15375) | inline SSLServer::SSLServer(const tls::ContextSetupCallback &setup_callb...
function SSLServer (line 15386) | inline SSLServer::~SSLServer() {
function process_and_close_socket (line 15392) | inline bool SSLServer::process_and_close_socket(socket_t sock) {
function update_certs_pem (line 15463) | inline bool SSLServer::update_certs_pem(const char *cert_pem,
function SSLClient (line 15479) | inline SSLClient::~SSLClient() {
function shutdown_ssl (line 15489) | inline void SSLClient::shutdown_ssl(Socket &socket, bool shutdown_gracef...
function shutdown_ssl_impl (line 15493) | inline void SSLClient::shutdown_ssl_impl(Socket &socket,
function process_socket (line 15510) | inline bool SSLClient::process_socket(
function create_and_connect_socket (line 15523) | inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &...
function setup_proxy_connection (line 15531) | inline bool SSLClient::setup_proxy_connection(
function connect_with_proxy (line 15551) | inline bool SSLClient::connect_with_proxy(
function ensure_socket_connection (line 15645) | inline bool SSLClient::ensure_socket_connection(Socket &socket, Error &e...
function SSLClient (line 15660) | inline SSLClient::SSLClient(const std::string &host)
function SSLClient (line 15663) | inline SSLClient::SSLClient(const std::string &host, int port)
function SSLClient (line 15666) | inline SSLClient::SSLClient(const std::string &host, int port,
function SSLClient (line 15688) | inline SSLClient::SSLClient(const std::string &host, int port,
function set_ca_cert_store (line 15706) | inline void SSLClient::set_ca_cert_store(tls::ca_store_t ca_cert_store) {
function set_server_certificate_verifier (line 15715) | inline void
function set_session_verifier (line 15721) | inline void SSLClient::set_session_verifier(
function enable_windows_certificate_verification (line 15727) | inline void SSLClient::enable_windows_certificate_verification(bool enab...
function load_ca_cert_store (line 15732) | inline void SSLClient::load_ca_cert_store(const char *ca_cert,
function load_certs (line 15740) | inline bool SSLClient::load_certs() {
function initialize_ssl (line 15766) | inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) {
function set_digest_auth (line 15912) | inline void Client::set_digest_auth(const std::string &username,
function set_proxy_digest_auth (line 15917) | inline void Client::set_proxy_digest_auth(const std::string &username,
function enable_server_certificate_verification (line 15922) | inline void Client::enable_server_certificate_verification(bool enabled) {
function enable_server_hostname_verification (line 15926) | inline void Client::enable_server_hostname_verification(bool enabled) {
function enable_windows_certificate_verification (line 15931) | inline void Client::enable_windows_certificate_verification(bool enabled) {
function set_ca_cert_path (line 15939) | inline void Client::set_ca_cert_path(const std::string &ca_cert_file_path,
function set_ca_cert_store (line 15944) | inline void Client::set_ca_cert_store(tls::ca_store_t ca_cert_store) {
function load_ca_cert_store (line 15952) | inline void Client::load_ca_cert_store(const char *ca_cert, std::size_t ...
function set_server_certificate_verifier (line 15956) | inline void
function set_session_verifier (line 15964) | inline void Client::set_session_verifier(
function namespace (line 15984) | namespace tls {
function PeerCert (line 16167) | inline PeerCert::~PeerCert() {
function check_hostname (line 16181) | inline bool PeerCert::check_hostname(const char *hostname) const {
function validity (line 16191) | inline bool PeerCert::validity(time_t ¬_before, time_t ¬_after) co...
function check_hostname (line 16208) | inline bool VerifyContext::check_hostname(const char *hostname) const {
function validity (line 16218) | inline bool VerifyContext::validity(time_t ¬_before,
function SSL_CTX (line 16253) | inline SSL_CTX *Client::ssl_context() const {
function set_server_certificate_verifier (line 16258) | inline void Client::set_server_certificate_verifier(
function namespace (line 16274) | namespace tls {
function set_ca_cert_store (line 17373) | inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) {
function SSLServer (line 17379) | inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key,
function SSLServer (line 17385) | inline SSLServer::SSLServer(
function SSL_CTX (line 17399) | inline SSL_CTX *SSLServer::ssl_context() const {
function update_certs (line 17403) | inline void SSLServer::update_certs(X509 *cert, EVP_PKEY *private_key,
function SSLClient (line 17410) | inline SSLClient::SSLClient(const std::string &host, int port,
function set_server_certificate_verifier (line 17422) | inline void SSLClient::set_server_certificate_verifier(
function SSL_CTX (line 17432) | inline SSL_CTX *SSLClient::ssl_context() const {
function verify_host (line 17436) | inline bool SSLClient::verify_host(X509 *server_cert) const {
function verify_host_with_subject_alt_name (line 17462) | inline bool
function verify_host_with_common_name (line 17523) | inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) c...
function namespace (line 17551) | namespace tls {
function ctx_t (line 17727) | inline ctx_t create_client_context() {
function ctx_t (line 17771) | inline ctx_t create_server_context() {
function free_context (line 17818) | inline void free_context(ctx_t ctx) {
function set_min_version (line 17822) | inline bool set_min_version(ctx_t ctx, Version version) {
function load_ca_pem (line 17851) | inline bool load_ca_pem(ctx_t ctx, const char *pem, size_t len) {
function load_ca_file (line 17870) | inline bool load_ca_file(ctx_t ctx, const char *file_path) {
function load_ca_dir (line 17884) | inline bool load_ca_dir(ctx_t ctx, const char *dir_path) {
function load_system_certs (line 17898) | inline bool load_system_certs(ctx_t ctx) {
function set_client_cert_pem (line 17937) | inline bool set_client_cert_pem(ctx_t ctx, const char *cert, const char ...
function set_client_cert_file (line 17995) | inline bool set_client_cert_file(ctx_t ctx, const char *cert_path,
function set_verify_client (line 18040) | inline void set_verify_client(ctx_t ctx, bool require) {
function session_t (line 18055) | inline session_t create_session(ctx_t ctx, socket_t sock) {
function free_session (line 18085) | inline void free_session(session_t session) {
function set_sni (line 18089) | inline bool set_sni(session_t session, const char *hostname) {
function set_hostname (line 18103) | inline bool set_hostname(session_t session, const char *hostname) {
function TlsError (line 18108) | inline TlsError connect(session_t session) {
function TlsError (line 18129) | inline TlsError accept(session_t session) {
function connect_nonblocking (line 18143) | inline bool connect_nonblocking(session_t session, socket_t sock,
function accept_nonblocking (line 18183) | inline bool accept_nonblocking(session_t session, socket_t sock,
function read (line 18200) | inline ssize_t read(session_t session, void *buf, size_t len, TlsError &...
function write (line 18226) | inline ssize_t write(session_t session, const void *buf, size_t len,
function pending (line 18253) | inline int pending(const_session_t session) {
function shutdown (line 18260) | inline void shutdown(session_t session, bool graceful) {
function is_peer_closed (line 18279) | inline bool is_peer_closed(session_t session, socket_t sock) {
function cert_t (line 18307) | inline cert_t get_peer_cert(const_session_t session) {
function free_cert (line 18319) | inline void free_cert(cert_t cert) {
function verify_hostname (line 18326) | inline bool verify_hostname(cert_t cert, const char *hostname) {
function hostname_mismatch_code (line 18384) | inline uint64_t hostname_mismatch_code() {
function get_verify_result (line 18388) | inline long get_verify_result(const_session_t session) {
function std (line 18397) | inline std::string get_cert_subject_cn(cert_t cert) {
function std (line 18413) | inline std::string get_cert_issuer_name(cert_t cert) {
function get_cert_sans (line 18424) | inline bool get_cert_sans(cert_t cert, std::vector<SanEntry> &sans) {
function get_cert_validity (line 18498) | inline bool get_cert_validity(cert_t cert, time_t ¬_before,
function std (line 18524) | inline std::string get_cert_serial(cert_t cert) {
function get_cert_der (line 18539) | inline bool get_cert_der(cert_t cert, std::vector<unsigned char> &der) {
function peek_error (line 18562) | inline uint64_t peek_error() {
function get_error (line 18567) | inline uint64_t get_error() {
function std (line 18574) | inline std::string error_string(uint64_t code) {
function ca_store_t (line 18580) | inline ca_store_t create_ca_store(const char *pem, size_t len) {
function free_ca_store (line 18604) | inline void free_ca_store(ca_store_t store) {
function set_ca_store (line 18612) | inline bool set_ca_store(ctx_t ctx, ca_store_t store) {
function get_ca_certs (line 18636) | inline size_t get_ca_certs(ctx_t ctx, std::vector<cert_t> &certs) {
function std (line 18659) | inline std::vector<std::string> get_ca_names(ctx_t ctx) {
function update_server_cert (line 18675) | inline bool update_server_cert(ctx_t ctx, const char *cert_pem,
function update_server_client_ca (line 18726) | inline bool update_server_client_ca(ctx_t ctx, const char *ca_pem) {
function set_verify_callback (line 18748) | inline bool set_verify_callback(ctx_t ctx, VerifyCallback callback) {
function get_verify_error (line 18768) | inline long get_verify_error(const_session_t session) {
function std (line 18775) | inline std::string verify_error_string(long error_code) {
function namespace (line 18801) | namespace tls {
function ctx_t (line 18933) | inline ctx_t create_client_context() {
function ctx_t (line 18957) | inline ctx_t create_server_context() {
function free_context (line 18986) | inline void free_context(ctx_t ctx) {
function set_min_version (line 18990) | inline bool set_min_version(ctx_t ctx, Version version) {
function load_ca_pem (line 19000) | inline bool load_ca_pem(ctx_t ctx, const char *pem, size_t len) {
function load_ca_file (line 19016) | inline bool load_ca_file(ctx_t ctx, const char *file_path) {
function load_ca_dir (line 19029) | inline bool load_ca_dir(ctx_t ctx, const char *dir_path) {
function load_system_certs (line 19042) | inline bool load_system_certs(ctx_t ctx) {
function set_client_cert_pem (line 19084) | inline bool set_client_cert_pem(ctx_t ctx, const char *cert, const char ...
function set_client_cert_file (line 19116) | inline bool set_client_cert_file(ctx_t ctx, const char *cert_path,
function set_verify_client (line 19145) | inline void set_verify_client(ctx_t ctx, bool require) {
function session_t (line 19163) | inline session_t create_session(ctx_t ctx, socket_t sock) {
function free_session (line 19184) | inline void free_session(session_t session) {
function set_sni (line 19188) | inline bool set_sni(session_t session, const char *hostname) {
function set_hostname (line 19207) | inline bool set_hostname(session_t session, const char *hostname) {
function TlsError (line 19212) | inline TlsError connect(session_t session) {
function TlsError (line 19234) | inline TlsError accept(session_t session) {
function connect_nonblocking (line 19259) | inline bool connect_nonblocking(session_t session, socket_t sock,
function accept_nonblocking (line 19301) | inline bool accept_nonblocking(session_t session, socket_t sock,
function read (line 19348) | inline ssize_t read(session_t session, void *buf, size_t len, TlsError &...
function write (line 19374) | inline ssize_t write(session_t session, const void *buf, size_t len,
function pending (line 19404) | inline int pending(const_session_t session) {
function shutdown (line 19411) | inline void shutdown(session_t session, bool graceful) {
function is_peer_closed (line 19432) | inline bool is_peer_closed(session_t session, socket_t sock) {
function cert_t (line 19458) | inline cert_t get_peer_cert(const_session_t session) {
function free_cert (line 19467) | inline void free_cert(cert_t cert) {
function verify_hostname (line 19471) | inline bool verify_hostname(cert_t cert, const char *hostname) {
function hostname_mismatch_code (line 19533) | inline uint64_t hostname_mismatch_code() {
function get_verify_result (line 19537) | inline long get_verify_result(const_session_t session) {
function std (line 19545) | inline std::string get_cert_subject_cn(cert_t cert) {
function std (line 19559) | inline std::string get_cert_issuer_name(cert_t cert) {
function get_cert_sans (line 19574) | inline bool get_cert_sans(cert_t cert, std::vector<SanEntry> &sans) {
function get_cert_validity (line 19658) | inline bool get_cert_validity(cert_t cert, time_t ¬_before,
function std (line 19683) | inline std::string get_cert_serial(cert_t cert) {
function get_cert_der (line 19705) | inline bool get_cert_der(cert_t cert, std::vector<unsigned char> &der) {
function peek_error (line 19732) | inline uint64_t peek_error() {
function get_error (line 19736) | inline uint64_t get_error() {
function std (line 19742) | inline std::string error_string(uint64_t code) {
function ca_store_t (line 19748) | inline ca_store_t create_ca_store(const char *pem, size_t len) {
function free_ca_store (line 19762) | inline void free_ca_store(ca_store_t store) {
function set_ca_store (line 19766) | inline bool set_ca_store(ctx_t ctx, ca_store_t store) {
function get_ca_certs (line 19777) | inline size_t get_ca_certs(ctx_t ctx, std::vector<cert_t> &certs) {
function std (line 19801) | inline std::vector<std::string> get_ca_names(ctx_t ctx) {
function update_server_cert (line 19835) | inline bool update_server_cert(ctx_t ctx, const char *cert_pem,
function update_server_client_ca (line 19866) | inline bool update_server_client_ca(ctx_t ctx, const char *ca_pem) {
function set_verify_callback (line 19881) | inline bool set_verify_callback(ctx_t ctx, VerifyCallback callback) {
function get_verify_error (line 19902) | inline long get_verify_error(const_session_t session) {
function std (line 19909) | inline std::string verify_error_string(long error_code) {
function namespace (line 19921) | namespace ws {
function WebSocketClient (line 20086) | inline WebSocketClient::WebSocketClient(
FILE: split.py
function main (line 12) | def main() -> None:
FILE: test/fuzzing/server_fuzzer.cc
class FuzzedStream (line 5) | class FuzzedStream : public httplib::Stream {
method FuzzedStream (line 7) | FuzzedStream(const uint8_t *data, size_t size)
method read (line 10) | ssize_t read(char *ptr, size_t size) override {
method write (line 17) | ssize_t write(const char *ptr, size_t size) override {
method write (line 22) | ssize_t write(const char *ptr) { return write(ptr, strlen(ptr)); }
method write (line 24) | ssize_t write(const std::string &s) { return write(s.data(), s.size()); }
method is_readable (line 26) | bool is_readable() const override { return true; }
method wait_readable (line 28) | bool wait_readable() const override { return true; }
method wait_writable (line 30) | bool wait_writable() const override { return true; }
method get_remote_ip_and_port (line 32) | void get_remote_ip_and_port(std::string &ip, int &port) const override {
method get_local_ip_and_port (line 37) | void get_local_ip_and_port(std::string &ip, int &port) const override {
method socket_t (line 42) | socket_t socket() const override { return 0; }
method time_t (line 44) | time_t duration() const override { return 0; }
class FuzzableServer (line 53) | class FuzzableServer : public httplib::Server {
method ProcessFuzzedRequest (line 55) | void ProcessFuzzedRequest(FuzzedStream &stream) {
function LLVMFuzzerInitialize (line 68) | int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) {
function LLVMFuzzerTestOneInput (line 96) | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FILE: test/fuzzing/standalone_fuzz_target_runner.cpp
function main (line 19) | int main(int argc, char **argv) {
FILE: test/gtest/include/gtest/gtest-assertion-result.h
function namespace (line 52) | namespace testing {
FILE: test/gtest/include/gtest/gtest-death-test.h
function namespace (line 52) | namespace testing {
FILE: test/gtest/include/gtest/gtest-matchers.h
function namespace (line 64) | namespace testing {
function DescribeImpl (line 383) | void DescribeImpl(const MatcherBase& m, std::ostream* os,
function MatcherDescriberInterface (line 393) | const MatcherDescriberInterface* GetDescriberImpl(
function VTable (line 409) | VTable* GetVTable() {
function Destroy (line 425) | void Destroy() {
function IsInlined (line 432) | constexpr bool IsInlined() {
function M (line 440) | static const M& Get(const MatcherBase& m) {
function Init (line 447) | static void Init(MatcherBase& m, M impl) {
function M (line 456) | static const M& Get(const MatcherBase& m) {
function M (line 470) | static const M& Get(const MatcherBase& m) {
function Init (line 473) | static void Init(MatcherBase& m, M* impl) {
function explicit (line 535) | explicit Matcher(const MatcherInterface<const std::string&>* impl)
function explicit (line 559) | explicit Matcher(const MatcherInterface<std::string>* impl)
function explicit (line 585) | explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
function explicit (line 613) | explicit Matcher(const MatcherInterface<internal::StringView>* impl)
function DescribeTo (line 676) | void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os...
function DescribeNegationTo (line 678) | void DescribeNegationTo(::std::ostream* os) const override {
function MatchAndExplain (line 682) | bool MatchAndExplain(T x, MatchResultListener* listener) const override {
function namespace (line 716) | namespace internal {
function DescribeTo (line 850) | void DescribeTo(::std::ostream* os) const {
function DescribeNegationTo (line 855) | void DescribeNegationTo(::std::ostream* os) const {
function PolymorphicMatcher (line 869) | inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
function PolymorphicMatcher (line 881) | inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
FILE: test/gtest/include/gtest/gtest-message.h
function namespace (line 64) | namespace testing {
function namespace (line 202) | namespace internal {
FILE: test/gtest/include/gtest/gtest-param-test.h
function class (line 157) | class BaseTest : public ::testing::Test {
function namespace (line 184) | namespace testing {
function internal (line 359) | inline internal::ParamGenerator<bool> Bool() { return Values(false, true...
FILE: test/gtest/include/gtest/gtest-printers.h
function namespace (line 117) | namespace testing {
function else (line 165) | struct FunctionPointerPrinter {
function else (line 180) | struct PointerPrinter {
function namespace (line 194) | namespace internal_stream_operator_without_lexical_name_lookup {
type ConvertibleToIntegerPrinter (line 240) | struct ConvertibleToIntegerPrinter {
type ConvertibleToStringViewPrinter (line 253) | struct ConvertibleToStringViewPrinter {
type RawBytesPrinter (line 265) | struct RawBytesPrinter {
type FallbackPrinter (line 277) | struct FallbackPrinter {
function ostream (line 305) | ostream* os) {
function string (line 341) | string Format(const ToPrint* value) {
function string (line 412) | string FormatForComparisonFailureMessage(const T1& value,
function ostream (line 439) | ostream* os) {
function PrintTo (line 450) | inline void PrintTo(char c, ::std::ostream* os) {
function PrintTo (line 458) | inline void PrintTo(bool x, ::std::ostream* os) {
function PrintTo (line 472) | inline void PrintTo(char16_t c, ::std::ostream* os) {
function PrintTo (line 476) | inline void PrintTo(char8_t c, ::std::ostream* os) {
function PrintTo (line 489) | inline void PrintTo(char* s, ::std::ostream* os) {
function PrintTo (line 495) | inline void PrintTo(const signed char* s, ::std::ostream* os) {
function PrintTo (line 498) | inline void PrintTo(signed char* s, ::std::ostream* os) {
function PrintTo (line 501) | inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
function PrintTo (line 504) | inline void PrintTo(unsigned char* s, ::std::ostream* os) {
function PrintTo (line 510) | inline void PrintTo(char8_t* s, ::std::ostream* os) {
function PrintTo (line 516) | inline void PrintTo(char16_t* s, ::std::ostream* os) {
function PrintTo (line 521) | inline void PrintTo(char32_t* s, ::std::ostream* os) {
function PrintTo (line 533) | inline void PrintTo(wchar_t* s, ::std::ostream* os) {
function PrintTo (line 554) | inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
function PrintTo (line 561) | inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
function PrintTo (line 568) | inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
function PrintTo (line 574) | inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
function PrintTo (line 581) | inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
function PrintTo (line 588) | inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
function PrintTo (line 593) | inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullp...
function PrintTo (line 596) | inline void PrintTo(const std::type_info& info, std::ostream* os) {
function ostream (line 651) | ostream* os) {
function Print (line 693) | static void Print(const T& value, ::std::ostream* os) {
function Print (line 864) | static void Print(const T& value, ::std::ostream* os) {
function Print (line 904) | static void Print(const char* str, ::std::ostream* os) {
function Print (line 920) | static void Print(const char8_t* str, ::std::ostream* os) {
function Print (line 936) | static void Print(const char16_t* str, ::std::ostream* os) {
function Print (line 951) | static void Print(const char32_t* str, ::std::ostream* os) {
function Print (line 967) | static void Print(const wchar_t* str, ::std::ostream* os) {
function Print (line 980) | static void Print(wchar_t* str, ::std::ostream* os) {
function ostream (line 986) | ostream* os) {
function ostream (line 995) | ostream* os) {
type std (line 1002) | typedef ::std::vector<::std::string> Strings;
function string (line 1035) | string PrintToString(const T& value) {
FILE: test/gtest/include/gtest/gtest-spi.h
function namespace (line 41) | namespace testing {
FILE: test/gtest/include/gtest/gtest-test-part.h
function namespace (line 46) | namespace testing {
function class (line 132) | class GTEST_API_ TestPartResultArray {
function class (line 153) | class GTEST_API_ TestPartResultReporterInterface {
function namespace (line 160) | namespace internal {
FILE: test/gtest/include/gtest/gtest-typed-test.h
type testing (line 59) | typedef testing::Types<char, int, unsigned int> MyTypes;
type testing (line 160) | typedef testing::Types<char, int, unsigned int> MyTypes;
FILE: test/gtest/include/gtest/gtest.h
function namespace (line 160) | namespace testing {
function class (line 1365) | class EqHelper {
type AssertHelperData (line 1595) | struct AssertHelperData {
function virtual (line 1656) | virtual ~WithParamInterface() {}
function ParamType (line 1660) | static const ParamType& GetParam() {
function class (line 2034) | class GTEST_API_ ScopedTrace {
function StaticAssertTypeEq (line 2120) | bool StaticAssertTypeEq() noexcept {
function class (line 2264) | class FactoryImpl : public internal::TestFactoryBase {
FILE: test/gtest/include/gtest/gtest_pred_impl.h
function namespace (line 43) | namespace testing {
FILE: test/gtest/include/gtest/internal/gtest-death-test-internal.h
function namespace (line 51) | namespace testing {
FILE: test/gtest/include/gtest/internal/gtest-filepath.h
function pathname_ (line 67) | FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
function explicit (line 69) | explicit FilePath(const std::string& pathname) : pathname_(pathname) {
function Set (line 78) | void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
FILE: test/gtest/include/gtest/internal/gtest-internal.h
function namespace (line 96) | namespace proto2 {
function namespace (line 100) | namespace testing {
type typename (line 794) | typedef typename Tests::Head Head;
function AlwaysFalse (line 842) | inline bool AlwaysFalse() { return !AlwaysTrue(); }
function ConstCharPtr (line 847) | struct GTEST_API_ ConstCharPtr {
type TrueWithString (line 855) | struct TrueWithString {
function class (line 868) | class GTEST_API_ Random {
type IsContainer (line 943) | typedef int IsContainer;
type IsNotContainer (line 954) | typedef char IsNotContainer;
function IsContainerTest (line 956) | IsContainerTest(long /* dummy */) {
function ArrayEq (line 1021) | bool ArrayEq(const T& lhs, const U& rhs) {
function ArrayEq (line 1027) | bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {
function CopyArray (line 1061) | void CopyArray(const T& from, U* to) {
function CopyArray (line 1067) | void CopyArray(const T (&from)[N], U (*to)[N]) {
type RelationToSourceReference (line 1085) | struct RelationToSourceReference {}
type RelationToSourceCopy (line 1086) | struct RelationToSourceCopy {}
type Element (line 1101) | typedef Element* iterator;
type Element (line 1102) | typedef const Element* const_iterator;
function InitCopy (line 1137) | void InitCopy(const Element* array, size_t a_size) {
function InitRef (line 1146) | void InitRef(const Element* array, size_t a_size) {
type MakeIndexSequenceImpl (line 1183) | struct MakeIndexSequenceImpl
type FlatTupleConstructTag (line 1215) | struct FlatTupleConstructTag {}
function InstantiateTestCase_P_IsDeprecated (line 1298) | constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
function TypedTestCase_P_IsDeprecated (line 1303) | constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
function TypedTestCaseIsDeprecated (line 1308) | constexpr bool TypedTestCaseIsDeprecated() { return true; }
function RegisterTypedTestCase_P_IsDeprecated (line 1313) | constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
function InstantiateTypedTestCase_P_IsDeprecated (line 1318) | constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
function namespace (line 1323) | namespace std {
function namespace (line 1371) | namespace testing {
FILE: test/gtest/include/gtest/internal/gtest-param-util.h
type PrintToStringParamName (line 68) | struct PrintToStringParamName {
type T (line 128) | typedef const T& reference;
type difference_type (line 129) | typedef ptrdiff_t difference_type;
function impl_ (line 132) | ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
FILE: test/gtest/include/gtest/internal/gtest-port.h
type GTEST_CRITICAL_SECTION (line 357) | typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;
type GTEST_CRITICAL_SECTION (line 362) | typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
function namespace (line 837) | namespace testing {
function To (line 1065) | To ImplicitCast_(To x) {
function To (line 1091) | To DownCast_(From* f) { // so we only accept pointers
function class (line 1169) | class GTEST_API_ AutoHandle {
function class (line 1252) | class ThreadWithParamBase {
function Join (line 1299) | void Join() {
function Run (line 1306) | void Run() override {
function class (line 1347) | class GTEST_API_ Mutex {
function class (line 1400) | class GTestMutexLock {
type GTestMutexLock (line 1413) | typedef GTestMutexLock MutexLock;
function class (line 1417) | class ThreadLocalValueHolderBase {
function class (line 1424) | class ThreadLocalBase {
function class (line 1444) | class GTEST_API_ ThreadLocalRegistry {
function class (line 1456) | class GTEST_API_ ThreadWithParamBase {
function virtual (line 1482) | virtual ~ThreadWithParam() {}
function virtual (line 1488) | virtual ~RunnableImpl() {}
function virtual (line 1489) | virtual void Run() { func_(param_); }
function explicit (line 1534) | explicit ThreadLocal(const T& value)
function T (line 1539) | T* pointer() { return GetOrCreateValue(); }
function T (line 1540) | const T* pointer() const { return GetOrCreateValue(); }
function set (line 1542) | void set(const T& value) { *pointer() = value; }
function explicit (line 1550) | explicit ValueHolder(const T& value) : value_(value) {}
function T (line 1552) | T* pointer() { return &value_; }
function T (line 1560) | T* GetOrCreateValue() const {
function ThreadLocalValueHolderBase (line 1566) | ThreadLocalValueHolderBase* NewValueForCurrentThread() const override {
function class (line 1570) | class ValueHolderFactory {
function class (line 1581) | class DefaultValueHolderFactory : public ValueHolderFactory {
function class (line 1592) | class InstanceValueHolderFactory : public ValueHolderFactory {
function class (line 1616) | class MutexBase {
function class (line 1674) | class Mutex : public MutexBase {
function class (line 1692) | class GTestMutexLock {
type GTestMutexLock (line 1705) | typedef GTestMutexLock MutexLock;
function class (line 1713) | class ThreadLocalValueHolderBase {
function DeleteThreadLocalValue (line 1720) | inline void DeleteThreadLocalValue(void* value_holder) {
function GTEST_API_ (line 1726) | GTEST_API_ ThreadLocal {
function set (line 1746) | void set(const T& value) { *pointer() = value; }
function explicit (line 1753) | explicit ValueHolder(const T& value) : value_(value) {}
function T (line 1755) | T* pointer() { return &value_; }
function pthread_key_t (line 1763) | static pthread_key_t CreateKey() {
function T (line 1772) | T* GetOrCreateValue() const {
function class (line 1785) | class ValueHolderFactory {
function class (line 1796) | class DefaultValueHolderFactory : public ValueHolderFactory {
function class (line 1807) | class InstanceValueHolderFactory : public ValueHolderFactory {
function class (line 1839) | class Mutex {
function class (line 1857) | class GTestMutexLock {
type GTestMutexLock (line 1862) | typedef GTestMutexLock MutexLock;
function GTEST_API_ (line 1865) | GTEST_API_ ThreadLocal {
function IsAlpha (line 1899) | inline bool IsAlpha(char ch) {
function IsAlNum (line 1902) | inline bool IsAlNum(char ch) {
function IsDigit (line 1905) | inline bool IsDigit(char ch) {
function IsLower (line 1908) | inline bool IsLower(char ch) {
function IsSpace (line 1911) | inline bool IsSpace(char ch) {
function IsUpper (line 1914) | inline bool IsUpper(char ch) {
function IsXDigit (line 1917) | inline bool IsXDigit(char ch) {
function IsXDigit (line 1921) | inline bool IsXDigit(char8_t ch) {
function IsXDigit (line 1925) | inline bool IsXDigit(char16_t ch) {
function IsXDigit (line 1929) | inline bool IsXDigit(char32_t ch) {
function IsXDigit (line 1933) | inline bool IsXDigit(wchar_t ch) {
function ToLower (line 1938) | inline char ToLower(char ch) {
function ToUpper (line 1941) | inline char ToUpper(char ch) {
function std (line 1945) | inline std::string StripTrailingSpaces(std::string str) {
function namespace (line 1957) | namespace posix {
function namespace (line 2301) | namespace testing {
function namespace (line 2313) | namespace testing {
function namespace (line 2329) | namespace testing {
function namespace (line 2343) | namespace testing {
function namespace (line 2361) | namespace testing {
function namespace (line 2373) | namespace testing {
function namespace (line 2389) | namespace testing {
function namespace (line 2402) | namespace testing {
FILE: test/gtest/include/gtest/internal/gtest-string.h
function namespace (line 58) | namespace testing {
FILE: test/gtest/include/gtest/internal/gtest-type-util.h
function namespace (line 50) | namespace testing {
FILE: test/gtest/src/gtest-assertion-result.cc
type testing (line 41) | namespace testing {
function AssertionResult (line 59) | AssertionResult AssertionResult::operator!() const {
function AssertionResult (line 66) | AssertionResult AssertionSuccess() { return AssertionResult(true); }
function AssertionResult (line 69) | AssertionResult AssertionFailure() { return AssertionResult(false); }
function AssertionResult (line 73) | AssertionResult AssertionFailure(const Message& message) {
FILE: test/gtest/src/gtest-death-test.cc
type testing (line 88) | namespace testing {
type internal (line 136) | namespace internal {
function InDeathTestChild (line 149) | bool InDeathTestChild() {
function ExitSummary (line 207) | static std::string ExitSummary(int exit_code) {
function ExitedUnsuccessfully (line 233) | bool ExitedUnsuccessfully(int exit_status) {
function DeathTestThreadWarning (line 242) | static std::string DeathTestThreadWarning(size_t thread_count) {
type DeathTestOutcome (line 280) | enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }
function DeathTestAbort (line 287) | static void DeathTestAbort(const std::string& message) {
function GetLastErrnoDescription (line 340) | std::string GetLastErrnoDescription() {
function FailFromInternalError (line 348) | static void FailFromInternalError(int fd) {
class DeathTestImpl (line 400) | class DeathTestImpl : public DeathTest {
method DeathTestImpl (line 402) | DeathTestImpl(const char* a_statement, Matcher<const std::string&>...
method spawned (line 418) | bool spawned() const { return spawned_; }
method set_spawned (line 419) | void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
method status (line 420) | int status() const { return status_; }
method set_status (line 421) | void set_status(int a_status) { status_ = a_status; }
method DeathTestOutcome (line 422) | DeathTestOutcome outcome() const { return outcome_; }
method set_outcome (line 423) | void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outc...
method read_fd (line 424) | int read_fd() const { return read_fd_; }
method set_read_fd (line 425) | void set_read_fd(int fd) { read_fd_ = fd; }
method write_fd (line 426) | int write_fd() const { return write_fd_; }
method set_write_fd (line 427) | void set_write_fd(int fd) { write_fd_ = fd; }
function FormatDeathTestOutput (line 534) | static ::std::string FormatDeathTestOutput(const ::std::string& outp...
class WindowsDeathTest (line 653) | class WindowsDeathTest : public DeathTestImpl {
method WindowsDeathTest (line 655) | WindowsDeathTest(const char* a_statement, Matcher<const std::strin...
class FuchsiaDeathTest (line 813) | class FuchsiaDeathTest : public DeathTestImpl {
method FuchsiaDeathTest (line 815) | FuchsiaDeathTest(const char* a_statement, Matcher<const std::strin...
class Arguments (line 840) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
class ForkingDeathTest (line 1060) | class ForkingDeathTest : public DeathTestImpl {
method set_child_pid (line 1068) | void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
class NoExecDeathTest (line 1096) | class NoExecDeathTest : public ForkingDeathTest {
method NoExecDeathTest (line 1098) | NoExecDeathTest(const char* a_statement, Matcher<const std::string...
class ExecDeathTest (line 1151) | class ExecDeathTest : public ForkingDeathTest {
method ExecDeathTest (line 1153) | ExecDeathTest(const char* a_statement, Matcher<const std::string&>...
method GetArgvsForDeathTestChildProcess (line 1161) | static ::std::vector<std::string> GetArgvsForDeathTestChildProcess...
class Arguments (line 1177) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
type ExecDeathTestArgs (line 1206) | struct ExecDeathTestArgs {
function ExecDeathTestChildMain (line 1217) | static int ExecDeathTestChildMain(void* child_arg) {
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1263) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1271) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function pid_t (line 1288) | static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
type internal (line 201) | namespace internal {
function InDeathTestChild (line 149) | bool InDeathTestChild() {
function ExitSummary (line 207) | static std::string ExitSummary(int exit_code) {
function ExitedUnsuccessfully (line 233) | bool ExitedUnsuccessfully(int exit_status) {
function DeathTestThreadWarning (line 242) | static std::string DeathTestThreadWarning(size_t thread_count) {
type DeathTestOutcome (line 280) | enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }
function DeathTestAbort (line 287) | static void DeathTestAbort(const std::string& message) {
function GetLastErrnoDescription (line 340) | std::string GetLastErrnoDescription() {
function FailFromInternalError (line 348) | static void FailFromInternalError(int fd) {
class DeathTestImpl (line 400) | class DeathTestImpl : public DeathTest {
method DeathTestImpl (line 402) | DeathTestImpl(const char* a_statement, Matcher<const std::string&>...
method spawned (line 418) | bool spawned() const { return spawned_; }
method set_spawned (line 419) | void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
method status (line 420) | int status() const { return status_; }
method set_status (line 421) | void set_status(int a_status) { status_ = a_status; }
method DeathTestOutcome (line 422) | DeathTestOutcome outcome() const { return outcome_; }
method set_outcome (line 423) | void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outc...
method read_fd (line 424) | int read_fd() const { return read_fd_; }
method set_read_fd (line 425) | void set_read_fd(int fd) { read_fd_ = fd; }
method write_fd (line 426) | int write_fd() const { return write_fd_; }
method set_write_fd (line 427) | void set_write_fd(int fd) { write_fd_ = fd; }
function FormatDeathTestOutput (line 534) | static ::std::string FormatDeathTestOutput(const ::std::string& outp...
class WindowsDeathTest (line 653) | class WindowsDeathTest : public DeathTestImpl {
method WindowsDeathTest (line 655) | WindowsDeathTest(const char* a_statement, Matcher<const std::strin...
class FuchsiaDeathTest (line 813) | class FuchsiaDeathTest : public DeathTestImpl {
method FuchsiaDeathTest (line 815) | FuchsiaDeathTest(const char* a_statement, Matcher<const std::strin...
class Arguments (line 840) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
class ForkingDeathTest (line 1060) | class ForkingDeathTest : public DeathTestImpl {
method set_child_pid (line 1068) | void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
class NoExecDeathTest (line 1096) | class NoExecDeathTest : public ForkingDeathTest {
method NoExecDeathTest (line 1098) | NoExecDeathTest(const char* a_statement, Matcher<const std::string...
class ExecDeathTest (line 1151) | class ExecDeathTest : public ForkingDeathTest {
method ExecDeathTest (line 1153) | ExecDeathTest(const char* a_statement, Matcher<const std::string&>...
method GetArgvsForDeathTestChildProcess (line 1161) | static ::std::vector<std::string> GetArgvsForDeathTestChildProcess...
class Arguments (line 1177) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
type ExecDeathTestArgs (line 1206) | struct ExecDeathTestArgs {
function ExecDeathTestChildMain (line 1217) | static int ExecDeathTestChildMain(void* child_arg) {
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1263) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1271) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function pid_t (line 1288) | static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
function GetStatusFileDescriptor (line 1504) | static int GetStatusFileDescriptor(unsigned int parent_process_id,
function InternalRunDeathTestFlag (line 1566) | InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
type testing (line 132) | namespace testing {
type internal (line 136) | namespace internal {
function InDeathTestChild (line 149) | bool InDeathTestChild() {
function ExitSummary (line 207) | static std::string ExitSummary(int exit_code) {
function ExitedUnsuccessfully (line 233) | bool ExitedUnsuccessfully(int exit_status) {
function DeathTestThreadWarning (line 242) | static std::string DeathTestThreadWarning(size_t thread_count) {
type DeathTestOutcome (line 280) | enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }
function DeathTestAbort (line 287) | static void DeathTestAbort(const std::string& message) {
function GetLastErrnoDescription (line 340) | std::string GetLastErrnoDescription() {
function FailFromInternalError (line 348) | static void FailFromInternalError(int fd) {
class DeathTestImpl (line 400) | class DeathTestImpl : public DeathTest {
method DeathTestImpl (line 402) | DeathTestImpl(const char* a_statement, Matcher<const std::string&>...
method spawned (line 418) | bool spawned() const { return spawned_; }
method set_spawned (line 419) | void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
method status (line 420) | int status() const { return status_; }
method set_status (line 421) | void set_status(int a_status) { status_ = a_status; }
method DeathTestOutcome (line 422) | DeathTestOutcome outcome() const { return outcome_; }
method set_outcome (line 423) | void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outc...
method read_fd (line 424) | int read_fd() const { return read_fd_; }
method set_read_fd (line 425) | void set_read_fd(int fd) { read_fd_ = fd; }
method write_fd (line 426) | int write_fd() const { return write_fd_; }
method set_write_fd (line 427) | void set_write_fd(int fd) { write_fd_ = fd; }
function FormatDeathTestOutput (line 534) | static ::std::string FormatDeathTestOutput(const ::std::string& outp...
class WindowsDeathTest (line 653) | class WindowsDeathTest : public DeathTestImpl {
method WindowsDeathTest (line 655) | WindowsDeathTest(const char* a_statement, Matcher<const std::strin...
class FuchsiaDeathTest (line 813) | class FuchsiaDeathTest : public DeathTestImpl {
method FuchsiaDeathTest (line 815) | FuchsiaDeathTest(const char* a_statement, Matcher<const std::strin...
class Arguments (line 840) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
class ForkingDeathTest (line 1060) | class ForkingDeathTest : public DeathTestImpl {
method set_child_pid (line 1068) | void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
class NoExecDeathTest (line 1096) | class NoExecDeathTest : public ForkingDeathTest {
method NoExecDeathTest (line 1098) | NoExecDeathTest(const char* a_statement, Matcher<const std::string...
class ExecDeathTest (line 1151) | class ExecDeathTest : public ForkingDeathTest {
method ExecDeathTest (line 1153) | ExecDeathTest(const char* a_statement, Matcher<const std::string&>...
method GetArgvsForDeathTestChildProcess (line 1161) | static ::std::vector<std::string> GetArgvsForDeathTestChildProcess...
class Arguments (line 1177) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
type ExecDeathTestArgs (line 1206) | struct ExecDeathTestArgs {
function ExecDeathTestChildMain (line 1217) | static int ExecDeathTestChildMain(void* child_arg) {
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1263) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1271) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function pid_t (line 1288) | static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
type internal (line 201) | namespace internal {
function InDeathTestChild (line 149) | bool InDeathTestChild() {
function ExitSummary (line 207) | static std::string ExitSummary(int exit_code) {
function ExitedUnsuccessfully (line 233) | bool ExitedUnsuccessfully(int exit_status) {
function DeathTestThreadWarning (line 242) | static std::string DeathTestThreadWarning(size_t thread_count) {
type DeathTestOutcome (line 280) | enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }
function DeathTestAbort (line 287) | static void DeathTestAbort(const std::string& message) {
function GetLastErrnoDescription (line 340) | std::string GetLastErrnoDescription() {
function FailFromInternalError (line 348) | static void FailFromInternalError(int fd) {
class DeathTestImpl (line 400) | class DeathTestImpl : public DeathTest {
method DeathTestImpl (line 402) | DeathTestImpl(const char* a_statement, Matcher<const std::string&>...
method spawned (line 418) | bool spawned() const { return spawned_; }
method set_spawned (line 419) | void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
method status (line 420) | int status() const { return status_; }
method set_status (line 421) | void set_status(int a_status) { status_ = a_status; }
method DeathTestOutcome (line 422) | DeathTestOutcome outcome() const { return outcome_; }
method set_outcome (line 423) | void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outc...
method read_fd (line 424) | int read_fd() const { return read_fd_; }
method set_read_fd (line 425) | void set_read_fd(int fd) { read_fd_ = fd; }
method write_fd (line 426) | int write_fd() const { return write_fd_; }
method set_write_fd (line 427) | void set_write_fd(int fd) { write_fd_ = fd; }
function FormatDeathTestOutput (line 534) | static ::std::string FormatDeathTestOutput(const ::std::string& outp...
class WindowsDeathTest (line 653) | class WindowsDeathTest : public DeathTestImpl {
method WindowsDeathTest (line 655) | WindowsDeathTest(const char* a_statement, Matcher<const std::strin...
class FuchsiaDeathTest (line 813) | class FuchsiaDeathTest : public DeathTestImpl {
method FuchsiaDeathTest (line 815) | FuchsiaDeathTest(const char* a_statement, Matcher<const std::strin...
class Arguments (line 840) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
class ForkingDeathTest (line 1060) | class ForkingDeathTest : public DeathTestImpl {
method set_child_pid (line 1068) | void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
class NoExecDeathTest (line 1096) | class NoExecDeathTest : public ForkingDeathTest {
method NoExecDeathTest (line 1098) | NoExecDeathTest(const char* a_statement, Matcher<const std::string...
class ExecDeathTest (line 1151) | class ExecDeathTest : public ForkingDeathTest {
method ExecDeathTest (line 1153) | ExecDeathTest(const char* a_statement, Matcher<const std::string&>...
method GetArgvsForDeathTestChildProcess (line 1161) | static ::std::vector<std::string> GetArgvsForDeathTestChildProcess...
class Arguments (line 1177) | class Arguments {
method Arguments (line 842) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 850) | void AddArgument(const char* argument) {
method AddArguments (line 855) | void AddArguments(const ::std::vector<Str>& arguments) {
method size (line 863) | int size() { return static_cast<int>(args_.size()) - 1; }
method Arguments (line 1179) | Arguments() { args_.push_back(nullptr); }
method AddArgument (line 1187) | void AddArgument(const char* argument) {
method AddArguments (line 1192) | void AddArguments(const ::std::vector<Str>& arguments) {
type ExecDeathTestArgs (line 1206) | struct ExecDeathTestArgs {
function ExecDeathTestChildMain (line 1217) | static int ExecDeathTestChildMain(void* child_arg) {
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1263) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ (line 1271) | GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
function pid_t (line 1288) | static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
function GetStatusFileDescriptor (line 1504) | static int GetStatusFileDescriptor(unsigned int parent_process_id,
function InternalRunDeathTestFlag (line 1566) | InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
FILE: test/gtest/src/gtest-filepath.cc
type testing (line 60) | namespace testing {
type internal (line 61) | namespace internal {
function IsPathSeparator (line 87) | static bool IsPathSeparator(char c) {
function FilePath (line 96) | FilePath FilePath::GetCurrentDir() {
function FilePath (line 123) | FilePath FilePath::RemoveExtension(const char* extension) const {
function FilePath (line 154) | FilePath FilePath::RemoveDirectoryName() const {
function FilePath (line 165) | FilePath FilePath::RemoveFileName() const {
function FilePath (line 182) | FilePath FilePath::MakeFileName(const FilePath& directory,
function FilePath (line 197) | FilePath FilePath::ConcatPaths(const FilePath& directory,
function FilePath (line 279) | FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
function FilePath (line 342) | FilePath FilePath::RemoveTrailingPathSeparator() const {
FILE: test/gtest/src/gtest-internal-inl.h
function namespace (line 74) | namespace testing {
FILE: test/gtest/src/gtest-matchers.cc
type testing (line 42) | namespace testing {
FILE: test/gtest/src/gtest-port.cc
type testing (line 90) | namespace testing {
type internal (line 91) | namespace internal {
function T (line 97) | T ReadProcFileField(const std::string& filename, int field) {
function GetThreadCount (line 110) | size_t GetThreadCount() {
function GetThreadCount (line 118) | size_t GetThreadCount() {
function GetThreadCount (line 153) | size_t GetThreadCount() {
function GetThreadCount (line 176) | size_t GetThreadCount() {
function GetThreadCount (line 213) | size_t GetThreadCount() {
function GetThreadCount (line 231) | size_t GetThreadCount() {
function GetThreadCount (line 244) | size_t GetThreadCount() {
function GetThreadCount (line 259) | size_t GetThreadCount() {
class MemoryIsNotDeallocated (line 351) | class MemoryIsNotDeallocated {
method MemoryIsNotDeallocated (line 353) | MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
method MemoryIsNotDeallocated (line 368) | MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete;
method MemoryIsNotDeallocated (line 369) | MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) =...
class ThreadWithParamSupport (line 422) | class ThreadWithParamSupport : public ThreadWithParamBase {
method HANDLE (line 424) | static HANDLE CreateThread(Runnable* runnable,
type ThreadMainParam (line 444) | struct ThreadMainParam {
method ThreadMainParam (line 445) | ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
method DWORD (line 452) | static DWORD WINAPI ThreadMain(void* ptr) {
method ThreadWithParamSupport (line 464) | ThreadWithParamSupport(const ThreadWithParamSupport&) = delete;
method ThreadWithParamSupport (line 465) | ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) =...
class ThreadLocalRegistryImpl (line 486) | class ThreadLocalRegistryImpl {
method ThreadLocalValueHolderBase (line 490) | static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
method OnThreadLocalDestroyed (line 523) | static void OnThreadLocalDestroyed(
method OnThreadExit (line 550) | static void OnThreadExit(DWORD thread_id) {
method StartWatcherThreadFor (line 588) | static void StartWatcherThreadFor(DWORD thread_id) {
method DWORD (line 615) | static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
method ThreadIdToThreadLocals (line 626) | static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
function ThreadLocalValueHolderBase (line 645) | ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentTh...
function IsInSet (line 725) | bool IsInSet(char ch, const char* str) {
function IsAsciiDigit (line 732) | bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
function IsAsciiPunct (line 733) | bool IsAsciiPunct(char ch) {
function IsRepeat (line 736) | bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
function IsAsciiWhiteSpace (line 737) | bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
function IsAsciiWordChar (line 738) | bool IsAsciiWordChar(char ch) {
function IsValidEscape (line 744) | bool IsValidEscape(char c) {
function AtomMatchesChar (line 750) | bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
function FormatRegexSyntaxError (line 783) | static std::string FormatRegexSyntaxError(const char* regex, int ind...
function ValidateRegex (line 791) | bool ValidateRegex(const char* regex) {
function MatchRepetitionAndRegexAtHead (line 851) | bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,
function MatchRegexAtHead (line 875) | bool MatchRegexAtHead(const char* regex, const char* str) {
function MatchRegexAnywhere (line 909) | bool MatchRegexAnywhere(const char* regex, const char* str) {
function FormatFileLocation (line 979) | GTEST_API_ ::std::string FormatFileLocation(const char* file, int li...
function FormatCompilerIndependentFileLocation (line 997) | GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const...
class CapturedStream (line 1034) | class CapturedStream {
method CapturedStream (line 1037) | explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
method GetCapturedString (line 1117) | std::string GetCapturedString() {
method CapturedStream (line 1142) | CapturedStream(const CapturedStream&) = delete;
method CapturedStream (line 1143) | CapturedStream& operator=(const CapturedStream&) = delete;
function CaptureStream (line 1152) | static void CaptureStream(int fd, const char* stream_name,
function GetCapturedStream (line 1162) | static std::string GetCapturedStream(CapturedStream** captured_strea...
function CaptureStdout (line 1181) | void CaptureStdout() {
function CaptureStderr (line 1186) | void CaptureStderr() {
function GetCapturedStdout (line 1191) | std::string GetCapturedStdout() {
function GetCapturedStderr (line 1196) | std::string GetCapturedStderr() {
function GetFileSize (line 1202) | size_t GetFileSize(FILE* file) {
function ReadEntireFile (line 1207) | std::string ReadEntireFile(FILE* file) {
function GetInjectableArgvs (line 1234) | std::vector<std::string> GetInjectableArgvs() {
function SetInjectableArgvs (line 1241) | void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
function SetInjectableArgvs (line 1246) | void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
function ClearInjectableArgvs (line 1251) | void ClearInjectableArgvs() {
type posix (line 1258) | namespace posix {
function Abort (line 1259) | void Abort() {
function FlagToEnvVar (line 1269) | static std::string FlagToEnvVar(const char* flag) {
function ParseInt32 (line 1284) | bool ParseInt32(const Message& src_text, const char* str, int32_t* v...
function BoolFromGTestEnv (line 1326) | bool BoolFromGTestEnv(const char* flag, bool default_value) {
function Int32FromGTestEnv (line 1340) | int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) {
function OutputFlagAlsoCheckEnvVar (line 1372) | std::string OutputFlagAlsoCheckEnvVar() {
FILE: test/gtest/src/gtest-printers.cc
type testing (line 57) | namespace testing {
function GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ (line 64) | GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
function PrintBytesInObjectToImpl (line 87) | void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t c...
function ToChar32 (line 114) | char32_t ToChar32(CharType in) {
type internal (line 121) | namespace internal {
function PrintBytesInObjectTo (line 128) | void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
type CharFormat (line 138) | enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }
function IsPrintableAscii (line 143) | inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= ...
function CharFormat (line 149) | static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
function CharFormat (line 198) | static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {
function CharFormat (line 229) | static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
function CharFormat (line 234) | static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) {
function CharFormat (line 239) | static CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) {
function CharFormat (line 243) | static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
function PrintCharAndCodeTo (line 251) | void PrintCharAndCodeTo(Char c, ostream* os) {
function PrintTo (line 274) | void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCode...
function PrintTo (line 275) | void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo...
function PrintTo (line 279) | void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); }
function PrintTo (line 282) | void PrintTo(char32_t c, ::std::ostream* os) {
function PrintTo (line 289) | void PrintTo(__uint128_t v, ::std::ostream* os) {
function PrintTo (line 322) | void PrintTo(__int128_t v, ::std::ostream* os) {
function GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ (line 337) | GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDR...
function GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ (line 366) | GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDR...
function UniversalPrintArray (line 392) | void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
function UniversalPrintArray (line 399) | void UniversalPrintArray(const char8_t* begin, size_t len, ostream* ...
function UniversalPrintArray (line 406) | void UniversalPrintArray(const char16_t* begin, size_t len, ostream*...
function UniversalPrintArray (line 412) | void UniversalPrintArray(const char32_t* begin, size_t len, ostream*...
function UniversalPrintArray (line 418) | void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* ...
function PrintCStringTo (line 426) | void PrintCStringTo(const Char* s, ostream* os) {
function PrintTo (line 437) | void PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); }
function PrintTo (line 440) | void PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); }
function PrintTo (line 443) | void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); }
function PrintTo (line 445) | void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); }
function PrintTo (line 455) | void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
function ContainsUnprintableControlCodes (line 460) | bool ContainsUnprintableControlCodes(const char* str, size_t length) {
function IsUTF8TrailByte (line 479) | bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xb...
function IsValidUTF8 (line 481) | bool IsValidUTF8(const char* str, size_t length) {
function ConditionalPrintAsText (line 514) | void ConditionalPrintAsText(const char* str, size_t length, ostream*...
function PrintStringTo (line 523) | void PrintStringTo(const ::std::string& s, ostream* os) {
function PrintU8StringTo (line 532) | void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
function PrintU16StringTo (line 537) | void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
function PrintU32StringTo (line 541) | void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
function PrintWideStringTo (line 546) | void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
FILE: test/gtest/src/gtest-test-part.cc
type testing (line 38) | namespace testing {
function TestPartResult (line 69) | const TestPartResult& TestPartResultArray::GetTestPartResult(int index...
type internal (line 83) | namespace internal {
FILE: test/gtest/src/gtest-typed-test.cc
type testing (line 34) | namespace testing {
type internal (line 35) | namespace internal {
function SplitIntoTestNames (line 44) | static std::vector<std::string> SplitIntoTestNames(const char* src) {
FILE: test/gtest/src/gtest.cc
type testing (line 146) | namespace testing {
type internal (line 179) | namespace internal {
function FILE (line 190) | static FILE* OpenFileForWriting(const std::string& output_file) {
function GTestIsInitialized (line 397) | static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
function SumOverTestSuiteList (line 402) | static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_...
function TestSuitePassed (line 412) | static bool TestSuitePassed(const TestSuite* test_suite) {
function TestSuiteFailed (line 417) | static bool TestSuiteFailed(const TestSuite* test_suite) {
function ShouldRunTestSuite (line 423) | static bool ShouldRunTestSuite(const TestSuite* test_suite) {
class FailureTest (line 455) | class FailureTest : public Test {
method FailureTest (line 457) | explicit FailureTest(const CodeLocation& loc, std::string error_me...
method TestBody (line 463) | void TestBody() override {
function InsertSyntheticTestCase (line 491) | void InsertSyntheticTestCase(const std::string& name, CodeLocation l...
function RegisterTypeParameterizedTestSuite (line 535) | void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
function RegisterTypeParameterizedTestSuiteInstantiation (line 541) | void RegisterTypeParameterizedTestSuiteInstantiation(const char* cas...
function GetArgvs (line 602) | ::std::vector<std::string> GetArgvs() {
function FilePath (line 615) | FilePath GetCurrentExecutableName() {
function PatternMatchesString (line 677) | static bool PatternMatchesString(const std::string& name_str,
function IsGlobPattern (line 726) | bool IsGlobPattern(const std::string& pattern) {
class UnitTestFilter (line 731) | class UnitTestFilter {
method UnitTestFilter (line 733) | UnitTestFilter() = default;
method UnitTestFilter (line 736) | explicit UnitTestFilter(const std::string& filter) {
method MatchesName (line 754) | bool MatchesName(const std::string& name) const {
class PositiveAndNegativeUnitTestFilter (line 769) | class PositiveAndNegativeUnitTestFilter {
method PositiveAndNegativeUnitTestFilter (line 776) | explicit PositiveAndNegativeUnitTestFilter(const std::string& filt...
method MatchesTest (line 806) | bool MatchesTest(const std::string& test_suite_name,
method MatchesName (line 813) | bool MatchesName(const std::string& name) const {
function TypeId (line 927) | TypeId GetTestTypeId() { return GetTypeId<Test>(); }
function AssertionResult (line 936) | static AssertionResult HasOneFailure(const char* /* results_expr */,
function TestPartResultReporterInterface (line 1008) | TestPartResultReporterInterface*
function TestPartResultReporterInterface (line 1022) | TestPartResultReporterInterface*
class Timer (line 1114) | class Timer {
method Timer (line 1116) | Timer() : start_(std::chrono::steady_clock::now()) {}
method TimeInMillis (line 1119) | TimeInMillis Elapsed() {
function TimeInMillis (line 1132) | TimeInMillis GetTimeInMillis() {
function LPCWSTR (line 1148) | LPCWSTR String::AnsiToUtf16(const char* ansi) {
function StreamWideCharsToMessage (line 1194) | static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len...
function SplitString (line 1209) | void SplitString(const ::std::string& str, char delimiter,
type edit_distance (line 1265) | namespace edit_distance {
function CalculateOptimalEdits (line 1266) | std::vector<EditType> CalculateOptimalEdits(const std::vector<size...
class InternalStrings (line 1326) | class InternalStrings {
method GetId (line 1328) | size_t GetId(const std::string& str) {
function CalculateOptimalEdits (line 1342) | std::vector<EditType> CalculateOptimalEdits(
class Hunk (line 1364) | class Hunk {
method Hunk (line 1366) | Hunk(size_t left_start, size_t right_start)
method PushLine (line 1373) | void PushLine(char edit, const char* line) {
method PrintTo (line 1391) | void PrintTo(std::ostream* os) {
method has_edits (line 1401) | bool has_edits() const { return adds_ || removes_; }
method FlushEdits (line 1404) | void FlushEdits() {
method PrintHeader (line 1413) | void PrintHeader(std::ostream* ss) const {
function CreateUnifiedDiff (line 1441) | std::string CreateUnifiedDiff(const std::vector<std::string>& left,
function SplitEscapedString (line 1511) | std::vector<std::string> SplitEscapedString(const std::string& str) {
function AssertionResult (line 1551) | AssertionResult EqFailure(const char* lhs_expression,
function GetBoolAssertionFailureMessage (line 1583) | std::string GetBoolAssertionFailureMessage(
function AssertionResult (line 1596) | AssertionResult DoubleNearPredFormat(const char* expr1, const char* ...
function AssertionResult (line 1637) | AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
function AssertionResult (line 1687) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 1699) | AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
function AssertionResult (line 1711) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function AssertionResult (line 1724) | AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
function AssertionResult (line 1850) | AssertionResult HRESULTFailureHelper(const char* expr, const char* e...
function AssertionResult (line 1890) | AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NO...
function AssertionResult (line 1897) | AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NO...
function ChopLowBits (line 1935) | inline uint32_t ChopLowBits(uint32_t* bits, int n) {
function CodePointToUtf8 (line 1947) | std::string CodePointToUtf8(uint32_t code_point) {
function IsUtf16SurrogatePair (line 1982) | inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
function CreateCodePointFromUtf16SurrogatePair (line 1988) | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
function WideStringToUtf8 (line 2014) | std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
function AssertionResult (line 2059) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 2071) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function StringStreamToString (line 2174) | std::string StringStreamToString(::std::stringstream* ss) {
function AppendUserMessage (line 2193) | std::string AppendUserMessage(const std::string& gtest_msg,
function ReportFailureInUnknownLocation (line 2447) | void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
function FormatCxxExceptionMessage (line 2549) | static std::string FormatCxxExceptionMessage(const char* description,
function Result (line 2580) | Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::...
function Result (line 2607) | Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*me...
function TestInfo (line 2749) | TestInfo* MakeAndRegisterTestInfo(
function ReportInvalidTestSuiteType (line 2761) | void ReportInvalidTestSuiteType(const char* test_suite_name,
type GTestColor (line 3132) | enum class GTestColor { kDefault, kRed, kGreen, kYellow }
function PrintTestPartResultToString (line 3136) | static std::string PrintTestPartResultToString(
function PrintTestPartResult (line 3148) | static void PrintTestPartResult(const TestPartResult& test_part_resu...
function WORD (line 3170) | static WORD GetColorAttribute(GTestColor color) {
function GetBitOffset (line 3183) | static int GetBitOffset(WORD color_mask) {
function WORD (line 3194) | static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
function ShouldUseColor (line 3234) | bool ShouldUseColor(bool stdout_is_tty) {
function ColoredPrintf (line 3277) | static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
function PrintFullTestCommentIfPresent (line 3325) | static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
class PrettyUnitTestResultPrinter (line 3344) | class PrettyUnitTestResultPrinter : public TestEventListener {
method PrettyUnitTestResultPrinter (line 3346) | PrettyUnitTestResultPrinter() {}
method PrintTestName (line 3347) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3352) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnEnvironmentsSetUpEnd (line 3355) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnEnvironmentsTearDownEnd (line 3374) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3376) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class BriefUnitTestResultPrinter (line 3652) | class BriefUnitTestResultPrinter : public TestEventListener {
method BriefUnitTestResultPrinter (line 3654) | BriefUnitTestResultPrinter() {}
method PrintTestName (line 3655) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3660) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnTestIterationStart (line 3661) | void OnTestIterationStart(const UnitTest& /*unit_test*/,
method OnEnvironmentsSetUpStart (line 3663) | void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) overr...
method OnEnvironmentsSetUpEnd (line 3664) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnTestCaseStart (line 3666) | void OnTestCaseStart(const TestCase& /*test_case*/) override {}
method OnTestSuiteStart (line 3668) | void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
method OnTestStart (line 3671) | void OnTestStart(const TestInfo& /*test_info*/) override {}
method OnTestDisabled (line 3672) | void OnTestDisabled(const TestInfo& /*test_info*/) override {}
method OnTestCaseEnd (line 3677) | void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
method OnTestSuiteEnd (line 3679) | void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
method OnEnvironmentsTearDownStart (line 3682) | void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) ov...
method OnEnvironmentsTearDownEnd (line 3683) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3685) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class TestEventRepeater (line 3757) | class TestEventRepeater : public TestEventListener {
method TestEventRepeater (line 3759) | TestEventRepeater() : forwarding_enabled_(true) {}
method forwarding_enabled (line 3766) | bool forwarding_enabled() const { return forwarding_enabled_; }
method set_forwarding_enabled (line 3767) | void set_forwarding_enabled(bool enable) { forwarding_enabled_ = e...
method TestEventRepeater (line 3799) | TestEventRepeater(const TestEventRepeater&) = delete;
method TestEventRepeater (line 3800) | TestEventRepeater& operator=(const TestEventRepeater&) = delete;
function TestEventListener (line 3811) | TestEventListener* TestEventRepeater::Release(TestEventListener* lis...
class XmlUnitTestResultPrinter (line 3888) | class XmlUnitTestResultPrinter : public EmptyTestEventListener {
method IsNormalizableWhitespace (line 3902) | static bool IsNormalizableWhitespace(unsigned char c) {
method IsValidXmlCharacter (line 3908) | static bool IsValidXmlCharacter(unsigned char c) {
method EscapeXmlAttribute (line 3922) | static std::string EscapeXmlAttribute(const std::string& str) {
method EscapeXmlText (line 3927) | static std::string EscapeXmlText(const char* str) {
method XmlUnitTestResultPrinter (line 3978) | XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;
method XmlUnitTestResultPrinter (line 3979) | XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter...
function FormatTimeInMillisAsSeconds (line 4094) | std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
function PortableLocaltime (line 4100) | static bool PortableLocaltime(time_t seconds, struct tm* out) {
function FormatEpochTimeInMillisAsIso8601 (line 4121) | std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
class JsonUnitTestResultPrinter (line 4436) | class JsonUnitTestResultPrinter : public EmptyTestEventListener {
method JsonUnitTestResultPrinter (line 4492) | JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;
method JsonUnitTestResultPrinter (line 4493) | JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrint...
function FormatTimeInMillisAsDuration (line 4558) | static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
function FormatEpochTimeInMillisAsRFC3339 (line 4566) | static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
function Indent (line 4579) | static inline std::string Indent(size_t width) {
function GTEST_LOCK_EXCLUDED_ (line 4949) | GTEST_LOCK_EXCLUDED_(mutex_) {
function GTEST_LOCK_EXCLUDED_ (line 4998) | GTEST_LOCK_EXCLUDED_(mutex_) {
class ScopedPrematureExitFile (line 5012) | class ScopedPrematureExitFile {
method ScopedPrematureExitFile (line 5014) | explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
method ScopedPrematureExitFile (line 5044) | ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
method ScopedPrematureExitFile (line 5045) | ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&)...
class TestSuiteNameIs (line 5673) | class TestSuiteNameIs {
method TestSuiteNameIs (line 5676) | explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
function TestSuite (line 5700) | TestSuite* UnitTestImpl::GetTestSuite(
function SetUpEnvironment (line 5736) | static void SetUpEnvironment(Environment* env) { env->SetUp(); }
function TearDownEnvironment (line 5737) | static void TearDownEnvironment(Environment* env) { env->TearDown(); }
function WriteToShardStatusFileIfNeeded (line 5947) | void WriteToShardStatusFileIfNeeded() {
function ShouldShard (line 5969) | bool ShouldShard(const char* total_shards_env, const char* shard_ind...
function Int32FromEnvOrDie (line 6013) | int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {
function ShouldRunTestOnShard (line 6031) | bool ShouldRunTestOnShard(int total_shards, int shard_index, int tes...
function PrintOnOneLine (line 6101) | static void PrintOnOneLine(const char* str, int max_length) {
function OsStackTraceGetterInterface (line 6188) | OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
function TestResult (line 6201) | TestResult* UnitTestImpl::current_test_result() {
function GTEST_NO_INLINE_ (line 6247) | GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
class ClassUniqueToAlwaysTrue (line 6257) | class ClassUniqueToAlwaysTrue {}
function IsTrue (line 6260) | bool IsTrue(bool condition) { return condition; }
function AlwaysTrue (line 6262) | bool AlwaysTrue() {
function SkipPrefix (line 6274) | bool SkipPrefix(const char* prefix, const char** pstr) {
function ParseFlag (line 6326) | static bool ParseFlag(const char* str, const char* flag_name, bool* ...
function ParseFlag (line 6342) | bool ParseFlag(const char* str, const char* flag_name, int32_t* valu...
function ParseFlag (line 6359) | static bool ParseFlag(const char* str, const char* flag_name, String...
function HasGoogleTestFlagPrefix (line 6377) | static bool HasGoogleTestFlagPrefix(const char* str) {
function PrintColorEncoded (line 6394) | static void PrintColorEncoded(const char* str) {
function ParseGoogleTestFlag (line 6524) | static bool ParseGoogleTestFlag(const char* const arg) {
function LoadFlagsFromFile (line 6559) | static void LoadFlagsFromFile(const std::string& path) {
function ParseGoogleTestFlagsOnlyImpl (line 6580) | void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
function ParseGoogleTestFlagsOnly (line 6631) | void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
function ParseGoogleTestFlagsOnly (line 6665) | void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
function InitGoogleTestImpl (line 6674) | void InitGoogleTestImpl(int* argc, CharType** argv) {
function GetDefaultFailFast (line 219) | static bool GetDefaultFailFast() {
type internal (line 373) | namespace internal {
function FILE (line 190) | static FILE* OpenFileForWriting(const std::string& output_file) {
function GTestIsInitialized (line 397) | static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
function SumOverTestSuiteList (line 402) | static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_...
function TestSuitePassed (line 412) | static bool TestSuitePassed(const TestSuite* test_suite) {
function TestSuiteFailed (line 417) | static bool TestSuiteFailed(const TestSuite* test_suite) {
function ShouldRunTestSuite (line 423) | static bool ShouldRunTestSuite(const TestSuite* test_suite) {
class FailureTest (line 455) | class FailureTest : public Test {
method FailureTest (line 457) | explicit FailureTest(const CodeLocation& loc, std::string error_me...
method TestBody (line 463) | void TestBody() override {
function InsertSyntheticTestCase (line 491) | void InsertSyntheticTestCase(const std::string& name, CodeLocation l...
function RegisterTypeParameterizedTestSuite (line 535) | void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
function RegisterTypeParameterizedTestSuiteInstantiation (line 541) | void RegisterTypeParameterizedTestSuiteInstantiation(const char* cas...
function GetArgvs (line 602) | ::std::vector<std::string> GetArgvs() {
function FilePath (line 615) | FilePath GetCurrentExecutableName() {
function PatternMatchesString (line 677) | static bool PatternMatchesString(const std::string& name_str,
function IsGlobPattern (line 726) | bool IsGlobPattern(const std::string& pattern) {
class UnitTestFilter (line 731) | class UnitTestFilter {
method UnitTestFilter (line 733) | UnitTestFilter() = default;
method UnitTestFilter (line 736) | explicit UnitTestFilter(const std::string& filter) {
method MatchesName (line 754) | bool MatchesName(const std::string& name) const {
class PositiveAndNegativeUnitTestFilter (line 769) | class PositiveAndNegativeUnitTestFilter {
method PositiveAndNegativeUnitTestFilter (line 776) | explicit PositiveAndNegativeUnitTestFilter(const std::string& filt...
method MatchesTest (line 806) | bool MatchesTest(const std::string& test_suite_name,
method MatchesName (line 813) | bool MatchesName(const std::string& name) const {
function TypeId (line 927) | TypeId GetTestTypeId() { return GetTypeId<Test>(); }
function AssertionResult (line 936) | static AssertionResult HasOneFailure(const char* /* results_expr */,
function TestPartResultReporterInterface (line 1008) | TestPartResultReporterInterface*
function TestPartResultReporterInterface (line 1022) | TestPartResultReporterInterface*
class Timer (line 1114) | class Timer {
method Timer (line 1116) | Timer() : start_(std::chrono::steady_clock::now()) {}
method TimeInMillis (line 1119) | TimeInMillis Elapsed() {
function TimeInMillis (line 1132) | TimeInMillis GetTimeInMillis() {
function LPCWSTR (line 1148) | LPCWSTR String::AnsiToUtf16(const char* ansi) {
function StreamWideCharsToMessage (line 1194) | static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len...
function SplitString (line 1209) | void SplitString(const ::std::string& str, char delimiter,
type edit_distance (line 1265) | namespace edit_distance {
function CalculateOptimalEdits (line 1266) | std::vector<EditType> CalculateOptimalEdits(const std::vector<size...
class InternalStrings (line 1326) | class InternalStrings {
method GetId (line 1328) | size_t GetId(const std::string& str) {
function CalculateOptimalEdits (line 1342) | std::vector<EditType> CalculateOptimalEdits(
class Hunk (line 1364) | class Hunk {
method Hunk (line 1366) | Hunk(size_t left_start, size_t right_start)
method PushLine (line 1373) | void PushLine(char edit, const char* line) {
method PrintTo (line 1391) | void PrintTo(std::ostream* os) {
method has_edits (line 1401) | bool has_edits() const { return adds_ || removes_; }
method FlushEdits (line 1404) | void FlushEdits() {
method PrintHeader (line 1413) | void PrintHeader(std::ostream* ss) const {
function CreateUnifiedDiff (line 1441) | std::string CreateUnifiedDiff(const std::vector<std::string>& left,
function SplitEscapedString (line 1511) | std::vector<std::string> SplitEscapedString(const std::string& str) {
function AssertionResult (line 1551) | AssertionResult EqFailure(const char* lhs_expression,
function GetBoolAssertionFailureMessage (line 1583) | std::string GetBoolAssertionFailureMessage(
function AssertionResult (line 1596) | AssertionResult DoubleNearPredFormat(const char* expr1, const char* ...
function AssertionResult (line 1637) | AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
function AssertionResult (line 1687) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 1699) | AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
function AssertionResult (line 1711) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function AssertionResult (line 1724) | AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
function AssertionResult (line 1850) | AssertionResult HRESULTFailureHelper(const char* expr, const char* e...
function AssertionResult (line 1890) | AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NO...
function AssertionResult (line 1897) | AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NO...
function ChopLowBits (line 1935) | inline uint32_t ChopLowBits(uint32_t* bits, int n) {
function CodePointToUtf8 (line 1947) | std::string CodePointToUtf8(uint32_t code_point) {
function IsUtf16SurrogatePair (line 1982) | inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
function CreateCodePointFromUtf16SurrogatePair (line 1988) | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
function WideStringToUtf8 (line 2014) | std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
function AssertionResult (line 2059) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 2071) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function StringStreamToString (line 2174) | std::string StringStreamToString(::std::stringstream* ss) {
function AppendUserMessage (line 2193) | std::string AppendUserMessage(const std::string& gtest_msg,
function ReportFailureInUnknownLocation (line 2447) | void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
function FormatCxxExceptionMessage (line 2549) | static std::string FormatCxxExceptionMessage(const char* description,
function Result (line 2580) | Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::...
function Result (line 2607) | Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*me...
function TestInfo (line 2749) | TestInfo* MakeAndRegisterTestInfo(
function ReportInvalidTestSuiteType (line 2761) | void ReportInvalidTestSuiteType(const char* test_suite_name,
type GTestColor (line 3132) | enum class GTestColor { kDefault, kRed, kGreen, kYellow }
function PrintTestPartResultToString (line 3136) | static std::string PrintTestPartResultToString(
function PrintTestPartResult (line 3148) | static void PrintTestPartResult(const TestPartResult& test_part_resu...
function WORD (line 3170) | static WORD GetColorAttribute(GTestColor color) {
function GetBitOffset (line 3183) | static int GetBitOffset(WORD color_mask) {
function WORD (line 3194) | static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
function ShouldUseColor (line 3234) | bool ShouldUseColor(bool stdout_is_tty) {
function ColoredPrintf (line 3277) | static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
function PrintFullTestCommentIfPresent (line 3325) | static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
class PrettyUnitTestResultPrinter (line 3344) | class PrettyUnitTestResultPrinter : public TestEventListener {
method PrettyUnitTestResultPrinter (line 3346) | PrettyUnitTestResultPrinter() {}
method PrintTestName (line 3347) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3352) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnEnvironmentsSetUpEnd (line 3355) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnEnvironmentsTearDownEnd (line 3374) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3376) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class BriefUnitTestResultPrinter (line 3652) | class BriefUnitTestResultPrinter : public TestEventListener {
method BriefUnitTestResultPrinter (line 3654) | BriefUnitTestResultPrinter() {}
method PrintTestName (line 3655) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3660) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnTestIterationStart (line 3661) | void OnTestIterationStart(const UnitTest& /*unit_test*/,
method OnEnvironmentsSetUpStart (line 3663) | void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) overr...
method OnEnvironmentsSetUpEnd (line 3664) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnTestCaseStart (line 3666) | void OnTestCaseStart(const TestCase& /*test_case*/) override {}
method OnTestSuiteStart (line 3668) | void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
method OnTestStart (line 3671) | void OnTestStart(const TestInfo& /*test_info*/) override {}
method OnTestDisabled (line 3672) | void OnTestDisabled(const TestInfo& /*test_info*/) override {}
method OnTestCaseEnd (line 3677) | void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
method OnTestSuiteEnd (line 3679) | void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
method OnEnvironmentsTearDownStart (line 3682) | void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) ov...
method OnEnvironmentsTearDownEnd (line 3683) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3685) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class TestEventRepeater (line 3757) | class TestEventRepeater : public TestEventListener {
method TestEventRepeater (line 3759) | TestEventRepeater() : forwarding_enabled_(true) {}
method forwarding_enabled (line 3766) | bool forwarding_enabled() const { return forwarding_enabled_; }
method set_forwarding_enabled (line 3767) | void set_forwarding_enabled(bool enable) { forwarding_enabled_ = e...
method TestEventRepeater (line 3799) | TestEventRepeater(const TestEventRepeater&) = delete;
method TestEventRepeater (line 3800) | TestEventRepeater& operator=(const TestEventRepeater&) = delete;
function TestEventListener (line 3811) | TestEventListener* TestEventRepeater::Release(TestEventListener* lis...
class XmlUnitTestResultPrinter (line 3888) | class XmlUnitTestResultPrinter : public EmptyTestEventListener {
method IsNormalizableWhitespace (line 3902) | static bool IsNormalizableWhitespace(unsigned char c) {
method IsValidXmlCharacter (line 3908) | static bool IsValidXmlCharacter(unsigned char c) {
method EscapeXmlAttribute (line 3922) | static std::string EscapeXmlAttribute(const std::string& str) {
method EscapeXmlText (line 3927) | static std::string EscapeXmlText(const char* str) {
method XmlUnitTestResultPrinter (line 3978) | XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;
method XmlUnitTestResultPrinter (line 3979) | XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter...
function FormatTimeInMillisAsSeconds (line 4094) | std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
function PortableLocaltime (line 4100) | static bool PortableLocaltime(time_t seconds, struct tm* out) {
function FormatEpochTimeInMillisAsIso8601 (line 4121) | std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
class JsonUnitTestResultPrinter (line 4436) | class JsonUnitTestResultPrinter : public EmptyTestEventListener {
method JsonUnitTestResultPrinter (line 4492) | JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;
method JsonUnitTestResultPrinter (line 4493) | JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrint...
function FormatTimeInMillisAsDuration (line 4558) | static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
function FormatEpochTimeInMillisAsRFC3339 (line 4566) | static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
function Indent (line 4579) | static inline std::string Indent(size_t width) {
function GTEST_LOCK_EXCLUDED_ (line 4949) | GTEST_LOCK_EXCLUDED_(mutex_) {
function GTEST_LOCK_EXCLUDED_ (line 4998) | GTEST_LOCK_EXCLUDED_(mutex_) {
class ScopedPrematureExitFile (line 5012) | class ScopedPrematureExitFile {
method ScopedPrematureExitFile (line 5014) | explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
method ScopedPrematureExitFile (line 5044) | ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
method ScopedPrematureExitFile (line 5045) | ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&)...
class TestSuiteNameIs (line 5673) | class TestSuiteNameIs {
method TestSuiteNameIs (line 5676) | explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
function TestSuite (line 5700) | TestSuite* UnitTestImpl::GetTestSuite(
function SetUpEnvironment (line 5736) | static void SetUpEnvironment(Environment* env) { env->SetUp(); }
function TearDownEnvironment (line 5737) | static void TearDownEnvironment(Environment* env) { env->TearDown(); }
function WriteToShardStatusFileIfNeeded (line 5947) | void WriteToShardStatusFileIfNeeded() {
function ShouldShard (line 5969) | bool ShouldShard(const char* total_shards_env, const char* shard_ind...
function Int32FromEnvOrDie (line 6013) | int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {
function ShouldRunTestOnShard (line 6031) | bool ShouldRunTestOnShard(int total_shards, int shard_index, int tes...
function PrintOnOneLine (line 6101) | static void PrintOnOneLine(const char* str, int max_length) {
function OsStackTraceGetterInterface (line 6188) | OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
function TestResult (line 6201) | TestResult* UnitTestImpl::current_test_result() {
function GTEST_NO_INLINE_ (line 6247) | GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
class ClassUniqueToAlwaysTrue (line 6257) | class ClassUniqueToAlwaysTrue {}
function IsTrue (line 6260) | bool IsTrue(bool condition) { return condition; }
function AlwaysTrue (line 6262) | bool AlwaysTrue() {
function SkipPrefix (line 6274) | bool SkipPrefix(const char* prefix, const char** pstr) {
function ParseFlag (line 6326) | static bool ParseFlag(const char* str, const char* flag_name, bool* ...
function ParseFlag (line 6342) | bool ParseFlag(const char* str, const char* flag_name, int32_t* valu...
function ParseFlag (line 6359) | static bool ParseFlag(const char* str, const char* flag_name, String...
function HasGoogleTestFlagPrefix (line 6377) | static bool HasGoogleTestFlagPrefix(const char* str) {
function PrintColorEncoded (line 6394) | static void PrintColorEncoded(const char* str) {
function ParseGoogleTestFlag (line 6524) | static bool ParseGoogleTestFlag(const char* const arg) {
function LoadFlagsFromFile (line 6559) | static void LoadFlagsFromFile(const std::string& path) {
function ParseGoogleTestFlagsOnlyImpl (line 6580) | void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
function ParseGoogleTestFlagsOnly (line 6631) | void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
function ParseGoogleTestFlagsOnly (line 6665) | void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
function InitGoogleTestImpl (line 6674) | void InitGoogleTestImpl(int* argc, CharType** argv) {
type internal (line 916) | namespace internal {
function FILE (line 190) | static FILE* OpenFileForWriting(const std::string& output_file) {
function GTestIsInitialized (line 397) | static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
function SumOverTestSuiteList (line 402) | static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_...
function TestSuitePassed (line 412) | static bool TestSuitePassed(const TestSuite* test_suite) {
function TestSuiteFailed (line 417) | static bool TestSuiteFailed(const TestSuite* test_suite) {
function ShouldRunTestSuite (line 423) | static bool ShouldRunTestSuite(const TestSuite* test_suite) {
class FailureTest (line 455) | class FailureTest : public Test {
method FailureTest (line 457) | explicit FailureTest(const CodeLocation& loc, std::string error_me...
method TestBody (line 463) | void TestBody() override {
function InsertSyntheticTestCase (line 491) | void InsertSyntheticTestCase(const std::string& name, CodeLocation l...
function RegisterTypeParameterizedTestSuite (line 535) | void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
function RegisterTypeParameterizedTestSuiteInstantiation (line 541) | void RegisterTypeParameterizedTestSuiteInstantiation(const char* cas...
function GetArgvs (line 602) | ::std::vector<std::string> GetArgvs() {
function FilePath (line 615) | FilePath GetCurrentExecutableName() {
function PatternMatchesString (line 677) | static bool PatternMatchesString(const std::string& name_str,
function IsGlobPattern (line 726) | bool IsGlobPattern(const std::string& pattern) {
class UnitTestFilter (line 731) | class UnitTestFilter {
method UnitTestFilter (line 733) | UnitTestFilter() = default;
method UnitTestFilter (line 736) | explicit UnitTestFilter(const std::string& filter) {
method MatchesName (line 754) | bool MatchesName(const std::string& name) const {
class PositiveAndNegativeUnitTestFilter (line 769) | class PositiveAndNegativeUnitTestFilter {
method PositiveAndNegativeUnitTestFilter (line 776) | explicit PositiveAndNegativeUnitTestFilter(const std::string& filt...
method MatchesTest (line 806) | bool MatchesTest(const std::string& test_suite_name,
method MatchesName (line 813) | bool MatchesName(const std::string& name) const {
function TypeId (line 927) | TypeId GetTestTypeId() { return GetTypeId<Test>(); }
function AssertionResult (line 936) | static AssertionResult HasOneFailure(const char* /* results_expr */,
function TestPartResultReporterInterface (line 1008) | TestPartResultReporterInterface*
function TestPartResultReporterInterface (line 1022) | TestPartResultReporterInterface*
class Timer (line 1114) | class Timer {
method Timer (line 1116) | Timer() : start_(std::chrono::steady_clock::now()) {}
method TimeInMillis (line 1119) | TimeInMillis Elapsed() {
function TimeInMillis (line 1132) | TimeInMillis GetTimeInMillis() {
function LPCWSTR (line 1148) | LPCWSTR String::AnsiToUtf16(const char* ansi) {
function StreamWideCharsToMessage (line 1194) | static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len...
function SplitString (line 1209) | void SplitString(const ::std::string& str, char delimiter,
type edit_distance (line 1265) | namespace edit_distance {
function CalculateOptimalEdits (line 1266) | std::vector<EditType> CalculateOptimalEdits(const std::vector<size...
class InternalStrings (line 1326) | class InternalStrings {
method GetId (line 1328) | size_t GetId(const std::string& str) {
function CalculateOptimalEdits (line 1342) | std::vector<EditType> CalculateOptimalEdits(
class Hunk (line 1364) | class Hunk {
method Hunk (line 1366) | Hunk(size_t left_start, size_t right_start)
method PushLine (line 1373) | void PushLine(char edit, const char* line) {
method PrintTo (line 1391) | void PrintTo(std::ostream* os) {
method has_edits (line 1401) | bool has_edits() const { return adds_ || removes_; }
method FlushEdits (line 1404) | void FlushEdits() {
method PrintHeader (line 1413) | void PrintHeader(std::ostream* ss) const {
function CreateUnifiedDiff (line 1441) | std::string CreateUnifiedDiff(const std::vector<std::string>& left,
function SplitEscapedString (line 1511) | std::vector<std::string> SplitEscapedString(const std::string& str) {
function AssertionResult (line 1551) | AssertionResult EqFailure(const char* lhs_expression,
function GetBoolAssertionFailureMessage (line 1583) | std::string GetBoolAssertionFailureMessage(
function AssertionResult (line 1596) | AssertionResult DoubleNearPredFormat(const char* expr1, const char* ...
function AssertionResult (line 1637) | AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
function AssertionResult (line 1687) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 1699) | AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
function AssertionResult (line 1711) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function AssertionResult (line 1724) | AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
function AssertionResult (line 1850) | AssertionResult HRESULTFailureHelper(const char* expr, const char* e...
function AssertionResult (line 1890) | AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NO...
function AssertionResult (line 1897) | AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NO...
function ChopLowBits (line 1935) | inline uint32_t ChopLowBits(uint32_t* bits, int n) {
function CodePointToUtf8 (line 1947) | std::string CodePointToUtf8(uint32_t code_point) {
function IsUtf16SurrogatePair (line 1982) | inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
function CreateCodePointFromUtf16SurrogatePair (line 1988) | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
function WideStringToUtf8 (line 2014) | std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
function AssertionResult (line 2059) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 2071) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function StringStreamToString (line 2174) | std::string StringStreamToString(::std::stringstream* ss) {
function AppendUserMessage (line 2193) | std::string AppendUserMessage(const std::string& gtest_msg,
function ReportFailureInUnknownLocation (line 2447) | void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
function FormatCxxExceptionMessage (line 2549) | static std::string FormatCxxExceptionMessage(const char* description,
function Result (line 2580) | Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::...
function Result (line 2607) | Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*me...
function TestInfo (line 2749) | TestInfo* MakeAndRegisterTestInfo(
function ReportInvalidTestSuiteType (line 2761) | void ReportInvalidTestSuiteType(const char* test_suite_name,
type GTestColor (line 3132) | enum class GTestColor { kDefault, kRed, kGreen, kYellow }
function PrintTestPartResultToString (line 3136) | static std::string PrintTestPartResultToString(
function PrintTestPartResult (line 3148) | static void PrintTestPartResult(const TestPartResult& test_part_resu...
function WORD (line 3170) | static WORD GetColorAttribute(GTestColor color) {
function GetBitOffset (line 3183) | static int GetBitOffset(WORD color_mask) {
function WORD (line 3194) | static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
function ShouldUseColor (line 3234) | bool ShouldUseColor(bool stdout_is_tty) {
function ColoredPrintf (line 3277) | static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
function PrintFullTestCommentIfPresent (line 3325) | static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
class PrettyUnitTestResultPrinter (line 3344) | class PrettyUnitTestResultPrinter : public TestEventListener {
method PrettyUnitTestResultPrinter (line 3346) | PrettyUnitTestResultPrinter() {}
method PrintTestName (line 3347) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3352) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnEnvironmentsSetUpEnd (line 3355) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnEnvironmentsTearDownEnd (line 3374) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3376) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class BriefUnitTestResultPrinter (line 3652) | class BriefUnitTestResultPrinter : public TestEventListener {
method BriefUnitTestResultPrinter (line 3654) | BriefUnitTestResultPrinter() {}
method PrintTestName (line 3655) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3660) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnTestIterationStart (line 3661) | void OnTestIterationStart(const UnitTest& /*unit_test*/,
method OnEnvironmentsSetUpStart (line 3663) | void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) overr...
method OnEnvironmentsSetUpEnd (line 3664) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnTestCaseStart (line 3666) | void OnTestCaseStart(const TestCase& /*test_case*/) override {}
method OnTestSuiteStart (line 3668) | void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
method OnTestStart (line 3671) | void OnTestStart(const TestInfo& /*test_info*/) override {}
method OnTestDisabled (line 3672) | void OnTestDisabled(const TestInfo& /*test_info*/) override {}
method OnTestCaseEnd (line 3677) | void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
method OnTestSuiteEnd (line 3679) | void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
method OnEnvironmentsTearDownStart (line 3682) | void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) ov...
method OnEnvironmentsTearDownEnd (line 3683) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3685) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class TestEventRepeater (line 3757) | class TestEventRepeater : public TestEventListener {
method TestEventRepeater (line 3759) | TestEventRepeater() : forwarding_enabled_(true) {}
method forwarding_enabled (line 3766) | bool forwarding_enabled() const { return forwarding_enabled_; }
method set_forwarding_enabled (line 3767) | void set_forwarding_enabled(bool enable) { forwarding_enabled_ = e...
method TestEventRepeater (line 3799) | TestEventRepeater(const TestEventRepeater&) = delete;
method TestEventRepeater (line 3800) | TestEventRepeater& operator=(const TestEventRepeater&) = delete;
function TestEventListener (line 3811) | TestEventListener* TestEventRepeater::Release(TestEventListener* lis...
class XmlUnitTestResultPrinter (line 3888) | class XmlUnitTestResultPrinter : public EmptyTestEventListener {
method IsNormalizableWhitespace (line 3902) | static bool IsNormalizableWhitespace(unsigned char c) {
method IsValidXmlCharacter (line 3908) | static bool IsValidXmlCharacter(unsigned char c) {
method EscapeXmlAttribute (line 3922) | static std::string EscapeXmlAttribute(const std::string& str) {
method EscapeXmlText (line 3927) | static std::string EscapeXmlText(const char* str) {
method XmlUnitTestResultPrinter (line 3978) | XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;
method XmlUnitTestResultPrinter (line 3979) | XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter...
function FormatTimeInMillisAsSeconds (line 4094) | std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
function PortableLocaltime (line 4100) | static bool PortableLocaltime(time_t seconds, struct tm* out) {
function FormatEpochTimeInMillisAsIso8601 (line 4121) | std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
class JsonUnitTestResultPrinter (line 4436) | class JsonUnitTestResultPrinter : public EmptyTestEventListener {
method JsonUnitTestResultPrinter (line 4492) | JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;
method JsonUnitTestResultPrinter (line 4493) | JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrint...
function FormatTimeInMillisAsDuration (line 4558) | static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
function FormatEpochTimeInMillisAsRFC3339 (line 4566) | static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
function Indent (line 4579) | static inline std::string Indent(size_t width) {
function GTEST_LOCK_EXCLUDED_ (line 4949) | GTEST_LOCK_EXCLUDED_(mutex_) {
function GTEST_LOCK_EXCLUDED_ (line 4998) | GTEST_LOCK_EXCLUDED_(mutex_) {
class ScopedPrematureExitFile (line 5012) | class ScopedPrematureExitFile {
method ScopedPrematureExitFile (line 5014) | explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
method ScopedPrematureExitFile (line 5044) | ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
method ScopedPrematureExitFile (line 5045) | ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&)...
class TestSuiteNameIs (line 5673) | class TestSuiteNameIs {
method TestSuiteNameIs (line 5676) | explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
function TestSuite (line 5700) | TestSuite* UnitTestImpl::GetTestSuite(
function SetUpEnvironment (line 5736) | static void SetUpEnvironment(Environment* env) { env->SetUp(); }
function TearDownEnvironment (line 5737) | static void TearDownEnvironment(Environment* env) { env->TearDown(); }
function WriteToShardStatusFileIfNeeded (line 5947) | void WriteToShardStatusFileIfNeeded() {
function ShouldShard (line 5969) | bool ShouldShard(const char* total_shards_env, const char* shard_ind...
function Int32FromEnvOrDie (line 6013) | int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {
function ShouldRunTestOnShard (line 6031) | bool ShouldRunTestOnShard(int total_shards, int shard_index, int tes...
function PrintOnOneLine (line 6101) | static void PrintOnOneLine(const char* str, int max_length) {
function OsStackTraceGetterInterface (line 6188) | OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
function TestResult (line 6201) | TestResult* UnitTestImpl::current_test_result() {
function GTEST_NO_INLINE_ (line 6247) | GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
class ClassUniqueToAlwaysTrue (line 6257) | class ClassUniqueToAlwaysTrue {}
function IsTrue (line 6260) | bool IsTrue(bool condition) { return condition; }
function AlwaysTrue (line 6262) | bool AlwaysTrue() {
function SkipPrefix (line 6274) | bool SkipPrefix(const char* prefix, const char** pstr) {
function ParseFlag (line 6326) | static bool ParseFlag(const char* str, const char* flag_name, bool* ...
function ParseFlag (line 6342) | bool ParseFlag(const char* str, const char* flag_name, int32_t* valu...
function ParseFlag (line 6359) | static bool ParseFlag(const char* str, const char* flag_name, String...
function HasGoogleTestFlagPrefix (line 6377) | static bool HasGoogleTestFlagPrefix(const char* str) {
function PrintColorEncoded (line 6394) | static void PrintColorEncoded(const char* str) {
function ParseGoogleTestFlag (line 6524) | static bool ParseGoogleTestFlag(const char* const arg) {
function LoadFlagsFromFile (line 6559) | static void LoadFlagsFromFile(const std::string& path) {
function ParseGoogleTestFlagsOnlyImpl (line 6580) | void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
function ParseGoogleTestFlagsOnly (line 6631) | void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
function ParseGoogleTestFlagsOnly (line 6665) | void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
function InitGoogleTestImpl (line 6674) | void InitGoogleTestImpl(int* argc, CharType** argv) {
function Message (line 1241) | Message& Message::operator<<(const wchar_t* wide_c_str) {
function Message (line 1244) | Message& Message::operator<<(wchar_t* wide_c_str) {
function Message (line 1251) | Message& Message::operator<<(const ::std::wstring& wstr) {
type internal (line 1263) | namespace internal {
function FILE (line 190) | static FILE* OpenFileForWriting(const std::string& output_file) {
function GTestIsInitialized (line 397) | static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
function SumOverTestSuiteList (line 402) | static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_...
function TestSuitePassed (line 412) | static bool TestSuitePassed(const TestSuite* test_suite) {
function TestSuiteFailed (line 417) | static bool TestSuiteFailed(const TestSuite* test_suite) {
function ShouldRunTestSuite (line 423) | static bool ShouldRunTestSuite(const TestSuite* test_suite) {
class FailureTest (line 455) | class FailureTest : public Test {
method FailureTest (line 457) | explicit FailureTest(const CodeLocation& loc, std::string error_me...
method TestBody (line 463) | void TestBody() override {
function InsertSyntheticTestCase (line 491) | void InsertSyntheticTestCase(const std::string& name, CodeLocation l...
function RegisterTypeParameterizedTestSuite (line 535) | void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
function RegisterTypeParameterizedTestSuiteInstantiation (line 541) | void RegisterTypeParameterizedTestSuiteInstantiation(const char* cas...
function GetArgvs (line 602) | ::std::vector<std::string> GetArgvs() {
function FilePath (line 615) | FilePath GetCurrentExecutableName() {
function PatternMatchesString (line 677) | static bool PatternMatchesString(const std::string& name_str,
function IsGlobPattern (line 726) | bool IsGlobPattern(const std::string& pattern) {
class UnitTestFilter (line 731) | class UnitTestFilter {
method UnitTestFilter (line 733) | UnitTestFilter() = default;
method UnitTestFilter (line 736) | explicit UnitTestFilter(const std::string& filter) {
method MatchesName (line 754) | bool MatchesName(const std::string& name) const {
class PositiveAndNegativeUnitTestFilter (line 769) | class PositiveAndNegativeUnitTestFilter {
method PositiveAndNegativeUnitTestFilter (line 776) | explicit PositiveAndNegativeUnitTestFilter(const std::string& filt...
method MatchesTest (line 806) | bool MatchesTest(const std::string& test_suite_name,
method MatchesName (line 813) | bool MatchesName(const std::string& name) const {
function TypeId (line 927) | TypeId GetTestTypeId() { return GetTypeId<Test>(); }
function AssertionResult (line 936) | static AssertionResult HasOneFailure(const char* /* results_expr */,
function TestPartResultReporterInterface (line 1008) | TestPartResultReporterInterface*
function TestPartResultReporterInterface (line 1022) | TestPartResultReporterInterface*
class Timer (line 1114) | class Timer {
method Timer (line 1116) | Timer() : start_(std::chrono::steady_clock::now()) {}
method TimeInMillis (line 1119) | TimeInMillis Elapsed() {
function TimeInMillis (line 1132) | TimeInMillis GetTimeInMillis() {
function LPCWSTR (line 1148) | LPCWSTR String::AnsiToUtf16(const char* ansi) {
function StreamWideCharsToMessage (line 1194) | static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len...
function SplitString (line 1209) | void SplitString(const ::std::string& str, char delimiter,
type edit_distance (line 1265) | namespace edit_distance {
function CalculateOptimalEdits (line 1266) | std::vector<EditType> CalculateOptimalEdits(const std::vector<size...
class InternalStrings (line 1326) | class InternalStrings {
method GetId (line 1328) | size_t GetId(const std::string& str) {
function CalculateOptimalEdits (line 1342) | std::vector<EditType> CalculateOptimalEdits(
class Hunk (line 1364) | class Hunk {
method Hunk (line 1366) | Hunk(size_t left_start, size_t right_start)
method PushLine (line 1373) | void PushLine(char edit, const char* line) {
method PrintTo (line 1391) | void PrintTo(std::ostream* os) {
method has_edits (line 1401) | bool has_edits() const { return adds_ || removes_; }
method FlushEdits (line 1404) | void FlushEdits() {
method PrintHeader (line 1413) | void PrintHeader(std::ostream* ss) const {
function CreateUnifiedDiff (line 1441) | std::string CreateUnifiedDiff(const std::vector<std::string>& left,
function SplitEscapedString (line 1511) | std::vector<std::string> SplitEscapedString(const std::string& str) {
function AssertionResult (line 1551) | AssertionResult EqFailure(const char* lhs_expression,
function GetBoolAssertionFailureMessage (line 1583) | std::string GetBoolAssertionFailureMessage(
function AssertionResult (line 1596) | AssertionResult DoubleNearPredFormat(const char* expr1, const char* ...
function AssertionResult (line 1637) | AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
function AssertionResult (line 1687) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 1699) | AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
function AssertionResult (line 1711) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function AssertionResult (line 1724) | AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
function AssertionResult (line 1850) | AssertionResult HRESULTFailureHelper(const char* expr, const char* e...
function AssertionResult (line 1890) | AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NO...
function AssertionResult (line 1897) | AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NO...
function ChopLowBits (line 1935) | inline uint32_t ChopLowBits(uint32_t* bits, int n) {
function CodePointToUtf8 (line 1947) | std::string CodePointToUtf8(uint32_t code_point) {
function IsUtf16SurrogatePair (line 1982) | inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
function CreateCodePointFromUtf16SurrogatePair (line 1988) | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
function WideStringToUtf8 (line 2014) | std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
function AssertionResult (line 2059) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 2071) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function StringStreamToString (line 2174) | std::string StringStreamToString(::std::stringstream* ss) {
function AppendUserMessage (line 2193) | std::string AppendUserMessage(const std::string& gtest_msg,
function ReportFailureInUnknownLocation (line 2447) | void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
function FormatCxxExceptionMessage (line 2549) | static std::string FormatCxxExceptionMessage(const char* description,
function Result (line 2580) | Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::...
function Result (line 2607) | Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*me...
function TestInfo (line 2749) | TestInfo* MakeAndRegisterTestInfo(
function ReportInvalidTestSuiteType (line 2761) | void ReportInvalidTestSuiteType(const char* test_suite_name,
type GTestColor (line 3132) | enum class GTestColor { kDefault, kRed, kGreen, kYellow }
function PrintTestPartResultToString (line 3136) | static std::string PrintTestPartResultToString(
function PrintTestPartResult (line 3148) | static void PrintTestPartResult(const TestPartResult& test_part_resu...
function WORD (line 3170) | static WORD GetColorAttribute(GTestColor color) {
function GetBitOffset (line 3183) | static int GetBitOffset(WORD color_mask) {
function WORD (line 3194) | static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
function ShouldUseColor (line 3234) | bool ShouldUseColor(bool stdout_is_tty) {
function ColoredPrintf (line 3277) | static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
function PrintFullTestCommentIfPresent (line 3325) | static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
class PrettyUnitTestResultPrinter (line 3344) | class PrettyUnitTestResultPrinter : public TestEventListener {
method PrettyUnitTestResultPrinter (line 3346) | PrettyUnitTestResultPrinter() {}
method PrintTestName (line 3347) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3352) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnEnvironmentsSetUpEnd (line 3355) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnEnvironmentsTearDownEnd (line 3374) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3376) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class BriefUnitTestResultPrinter (line 3652) | class BriefUnitTestResultPrinter : public TestEventListener {
method BriefUnitTestResultPrinter (line 3654) | BriefUnitTestResultPrinter() {}
method PrintTestName (line 3655) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3660) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnTestIterationStart (line 3661) | void OnTestIterationStart(const UnitTest& /*unit_test*/,
method OnEnvironmentsSetUpStart (line 3663) | void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) overr...
method OnEnvironmentsSetUpEnd (line 3664) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnTestCaseStart (line 3666) | void OnTestCaseStart(const TestCase& /*test_case*/) override {}
method OnTestSuiteStart (line 3668) | void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
method OnTestStart (line 3671) | void OnTestStart(const TestInfo& /*test_info*/) override {}
method OnTestDisabled (line 3672) | void OnTestDisabled(const TestInfo& /*test_info*/) override {}
method OnTestCaseEnd (line 3677) | void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
method OnTestSuiteEnd (line 3679) | void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
method OnEnvironmentsTearDownStart (line 3682) | void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) ov...
method OnEnvironmentsTearDownEnd (line 3683) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3685) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class TestEventRepeater (line 3757) | class TestEventRepeater : public TestEventListener {
method TestEventRepeater (line 3759) | TestEventRepeater() : forwarding_enabled_(true) {}
method forwarding_enabled (line 3766) | bool forwarding_enabled() const { return forwarding_enabled_; }
method set_forwarding_enabled (line 3767) | void set_forwarding_enabled(bool enable) { forwarding_enabled_ = e...
method TestEventRepeater (line 3799) | TestEventRepeater(const TestEventRepeater&) = delete;
method TestEventRepeater (line 3800) | TestEventRepeater& operator=(const TestEventRepeater&) = delete;
function TestEventListener (line 3811) | TestEventListener* TestEventRepeater::Release(TestEventListener* lis...
class XmlUnitTestResultPrinter (line 3888) | class XmlUnitTestResultPrinter : public EmptyTestEventListener {
method IsNormalizableWhitespace (line 3902) | static bool IsNormalizableWhitespace(unsigned char c) {
method IsValidXmlCharacter (line 3908) | static bool IsValidXmlCharacter(unsigned char c) {
method EscapeXmlAttribute (line 3922) | static std::string EscapeXmlAttribute(const std::string& str) {
method EscapeXmlText (line 3927) | static std::string EscapeXmlText(const char* str) {
method XmlUnitTestResultPrinter (line 3978) | XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;
method XmlUnitTestResultPrinter (line 3979) | XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter...
function FormatTimeInMillisAsSeconds (line 4094) | std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
function PortableLocaltime (line 4100) | static bool PortableLocaltime(time_t seconds, struct tm* out) {
function FormatEpochTimeInMillisAsIso8601 (line 4121) | std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
class JsonUnitTestResultPrinter (line 4436) | class JsonUnitTestResultPrinter : public EmptyTestEventListener {
method JsonUnitTestResultPrinter (line 4492) | JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;
method JsonUnitTestResultPrinter (line 4493) | JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrint...
function FormatTimeInMillisAsDuration (line 4558) | static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
function FormatEpochTimeInMillisAsRFC3339 (line 4566) | static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
function Indent (line 4579) | static inline std::string Indent(size_t width) {
function GTEST_LOCK_EXCLUDED_ (line 4949) | GTEST_LOCK_EXCLUDED_(mutex_) {
function GTEST_LOCK_EXCLUDED_ (line 4998) | GTEST_LOCK_EXCLUDED_(mutex_) {
class ScopedPrematureExitFile (line 5012) | class ScopedPrematureExitFile {
method ScopedPrematureExitFile (line 5014) | explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
method ScopedPrematureExitFile (line 5044) | ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
method ScopedPrematureExitFile (line 5045) | ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&)...
class TestSuiteNameIs (line 5673) | class TestSuiteNameIs {
method TestSuiteNameIs (line 5676) | explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
function TestSuite (line 5700) | TestSuite* UnitTestImpl::GetTestSuite(
function SetUpEnvironment (line 5736) | static void SetUpEnvironment(Environment* env) { env->SetUp(); }
function TearDownEnvironment (line 5737) | static void TearDownEnvironment(Environment* env) { env->TearDown(); }
function WriteToShardStatusFileIfNeeded (line 5947) | void WriteToShardStatusFileIfNeeded() {
function ShouldShard (line 5969) | bool ShouldShard(const char* total_shards_env, const char* shard_ind...
function Int32FromEnvOrDie (line 6013) | int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {
function ShouldRunTestOnShard (line 6031) | bool ShouldRunTestOnShard(int total_shards, int shard_index, int tes...
function PrintOnOneLine (line 6101) | static void PrintOnOneLine(const char* str, int max_length) {
function OsStackTraceGetterInterface (line 6188) | OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
function TestResult (line 6201) | TestResult* UnitTestImpl::current_test_result() {
function GTEST_NO_INLINE_ (line 6247) | GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
class ClassUniqueToAlwaysTrue (line 6257) | class ClassUniqueToAlwaysTrue {}
function IsTrue (line 6260) | bool IsTrue(bool condition) { return condition; }
function AlwaysTrue (line 6262) | bool AlwaysTrue() {
function SkipPrefix (line 6274) | bool SkipPrefix(const char* prefix, const char** pstr) {
function ParseFlag (line 6326) | static bool ParseFlag(const char* str, const char* flag_name, bool* ...
function ParseFlag (line 6342) | bool ParseFlag(const char* str, const char* flag_name, int32_t* valu...
function ParseFlag (line 6359) | static bool ParseFlag(const char* str, const char* flag_name, String...
function HasGoogleTestFlagPrefix (line 6377) | static bool HasGoogleTestFlagPrefix(const char* str) {
function PrintColorEncoded (line 6394) | static void PrintColorEncoded(const char* str) {
function ParseGoogleTestFlag (line 6524) | static bool ParseGoogleTestFlag(const char* const arg) {
function LoadFlagsFromFile (line 6559) | static void LoadFlagsFromFile(const std::string& path) {
function ParseGoogleTestFlagsOnlyImpl (line 6580) | void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
function ParseGoogleTestFlagsOnly (line 6631) | void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
function ParseGoogleTestFlagsOnly (line 6665) | void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
function InitGoogleTestImpl (line 6674) | void InitGoogleTestImpl(int* argc, CharType** argv) {
function AssertionResult (line 1672) | AssertionResult FloatLE(const char* expr1, const char* expr2, float val1,
function AssertionResult (line 1679) | AssertionResult DoubleLE(const char* expr1, const char* expr2, double ...
type internal (line 1684) | namespace internal {
function FILE (line 190) | static FILE* OpenFileForWriting(const std::string& output_file) {
function GTestIsInitialized (line 397) | static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
function SumOverTestSuiteList (line 402) | static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_...
function TestSuitePassed (line 412) | static bool TestSuitePassed(const TestSuite* test_suite) {
function TestSuiteFailed (line 417) | static bool TestSuiteFailed(const TestSuite* test_suite) {
function ShouldRunTestSuite (line 423) | static bool ShouldRunTestSuite(const TestSuite* test_suite) {
class FailureTest (line 455) | class FailureTest : public Test {
method FailureTest (line 457) | explicit FailureTest(const CodeLocation& loc, std::string error_me...
method TestBody (line 463) | void TestBody() override {
function InsertSyntheticTestCase (line 491) | void InsertSyntheticTestCase(const std::string& name, CodeLocation l...
function RegisterTypeParameterizedTestSuite (line 535) | void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
function RegisterTypeParameterizedTestSuiteInstantiation (line 541) | void RegisterTypeParameterizedTestSuiteInstantiation(const char* cas...
function GetArgvs (line 602) | ::std::vector<std::string> GetArgvs() {
function FilePath (line 615) | FilePath GetCurrentExecutableName() {
function PatternMatchesString (line 677) | static bool PatternMatchesString(const std::string& name_str,
function IsGlobPattern (line 726) | bool IsGlobPattern(const std::string& pattern) {
class UnitTestFilter (line 731) | class UnitTestFilter {
method UnitTestFilter (line 733) | UnitTestFilter() = default;
method UnitTestFilter (line 736) | explicit UnitTestFilter(const std::string& filter) {
method MatchesName (line 754) | bool MatchesName(const std::string& name) const {
class PositiveAndNegativeUnitTestFilter (line 769) | class PositiveAndNegativeUnitTestFilter {
method PositiveAndNegativeUnitTestFilter (line 776) | explicit PositiveAndNegativeUnitTestFilter(const std::string& filt...
method MatchesTest (line 806) | bool MatchesTest(const std::string& test_suite_name,
method MatchesName (line 813) | bool MatchesName(const std::string& name) const {
function TypeId (line 927) | TypeId GetTestTypeId() { return GetTypeId<Test>(); }
function AssertionResult (line 936) | static AssertionResult HasOneFailure(const char* /* results_expr */,
function TestPartResultReporterInterface (line 1008) | TestPartResultReporterInterface*
function TestPartResultReporterInterface (line 1022) | TestPartResultReporterInterface*
class Timer (line 1114) | class Timer {
method Timer (line 1116) | Timer() : start_(std::chrono::steady_clock::now()) {}
method TimeInMillis (line 1119) | TimeInMillis Elapsed() {
function TimeInMillis (line 1132) | TimeInMillis GetTimeInMillis() {
function LPCWSTR (line 1148) | LPCWSTR String::AnsiToUtf16(const char* ansi) {
function StreamWideCharsToMessage (line 1194) | static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len...
function SplitString (line 1209) | void SplitString(const ::std::string& str, char delimiter,
type edit_distance (line 1265) | namespace edit_distance {
function CalculateOptimalEdits (line 1266) | std::vector<EditType> CalculateOptimalEdits(const std::vector<size...
class InternalStrings (line 1326) | class InternalStrings {
method GetId (line 1328) | size_t GetId(const std::string& str) {
function CalculateOptimalEdits (line 1342) | std::vector<EditType> CalculateOptimalEdits(
class Hunk (line 1364) | class Hunk {
method Hunk (line 1366) | Hunk(size_t left_start, size_t right_start)
method PushLine (line 1373) | void PushLine(char edit, const char* line) {
method PrintTo (line 1391) | void PrintTo(std::ostream* os) {
method has_edits (line 1401) | bool has_edits() const { return adds_ || removes_; }
method FlushEdits (line 1404) | void FlushEdits() {
method PrintHeader (line 1413) | void PrintHeader(std::ostream* ss) const {
function CreateUnifiedDiff (line 1441) | std::string CreateUnifiedDiff(const std::vector<std::string>& left,
function SplitEscapedString (line 1511) | std::vector<std::string> SplitEscapedString(const std::string& str) {
function AssertionResult (line 1551) | AssertionResult EqFailure(const char* lhs_expression,
function GetBoolAssertionFailureMessage (line 1583) | std::string GetBoolAssertionFailureMessage(
function AssertionResult (line 1596) | AssertionResult DoubleNearPredFormat(const char* expr1, const char* ...
function AssertionResult (line 1637) | AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
function AssertionResult (line 1687) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 1699) | AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
function AssertionResult (line 1711) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function AssertionResult (line 1724) | AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
function AssertionResult (line 1850) | AssertionResult HRESULTFailureHelper(const char* expr, const char* e...
function AssertionResult (line 1890) | AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NO...
function AssertionResult (line 1897) | AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NO...
function ChopLowBits (line 1935) | inline uint32_t ChopLowBits(uint32_t* bits, int n) {
function CodePointToUtf8 (line 1947) | std::string CodePointToUtf8(uint32_t code_point) {
function IsUtf16SurrogatePair (line 1982) | inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
function CreateCodePointFromUtf16SurrogatePair (line 1988) | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
function WideStringToUtf8 (line 2014) | std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
function AssertionResult (line 2059) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 2071) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function StringStreamToString (line 2174) | std::string StringStreamToString(::std::stringstream* ss) {
function AppendUserMessage (line 2193) | std::string AppendUserMessage(const std::string& gtest_msg,
function ReportFailureInUnknownLocation (line 2447) | void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
function FormatCxxExceptionMessage (line 2549) | static std::string FormatCxxExceptionMessage(const char* description,
function Result (line 2580) | Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::...
function Result (line 2607) | Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*me...
function TestInfo (line 2749) | TestInfo* MakeAndRegisterTestInfo(
function ReportInvalidTestSuiteType (line 2761) | void ReportInvalidTestSuiteType(const char* test_suite_name,
type GTestColor (line 3132) | enum class GTestColor { kDefault, kRed, kGreen, kYellow }
function PrintTestPartResultToString (line 3136) | static std::string PrintTestPartResultToString(
function PrintTestPartResult (line 3148) | static void PrintTestPartResult(const TestPartResult& test_part_resu...
function WORD (line 3170) | static WORD GetColorAttribute(GTestColor color) {
function GetBitOffset (line 3183) | static int GetBitOffset(WORD color_mask) {
function WORD (line 3194) | static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
function ShouldUseColor (line 3234) | bool ShouldUseColor(bool stdout_is_tty) {
function ColoredPrintf (line 3277) | static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
function PrintFullTestCommentIfPresent (line 3325) | static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
class PrettyUnitTestResultPrinter (line 3344) | class PrettyUnitTestResultPrinter : public TestEventListener {
method PrettyUnitTestResultPrinter (line 3346) | PrettyUnitTestResultPrinter() {}
method PrintTestName (line 3347) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3352) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnEnvironmentsSetUpEnd (line 3355) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnEnvironmentsTearDownEnd (line 3374) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3376) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class BriefUnitTestResultPrinter (line 3652) | class BriefUnitTestResultPrinter : public TestEventListener {
method BriefUnitTestResultPrinter (line 3654) | BriefUnitTestResultPrinter() {}
method PrintTestName (line 3655) | static void PrintTestName(const char* test_suite, const char* test) {
method OnTestProgramStart (line 3660) | void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
method OnTestIterationStart (line 3661) | void OnTestIterationStart(const UnitTest& /*unit_test*/,
method OnEnvironmentsSetUpStart (line 3663) | void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) overr...
method OnEnvironmentsSetUpEnd (line 3664) | void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) overrid...
method OnTestCaseStart (line 3666) | void OnTestCaseStart(const TestCase& /*test_case*/) override {}
method OnTestSuiteStart (line 3668) | void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
method OnTestStart (line 3671) | void OnTestStart(const TestInfo& /*test_info*/) override {}
method OnTestDisabled (line 3672) | void OnTestDisabled(const TestInfo& /*test_info*/) override {}
method OnTestCaseEnd (line 3677) | void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
method OnTestSuiteEnd (line 3679) | void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
method OnEnvironmentsTearDownStart (line 3682) | void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) ov...
method OnEnvironmentsTearDownEnd (line 3683) | void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) over...
method OnTestProgramEnd (line 3685) | void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
class TestEventRepeater (line 3757) | class TestEventRepeater : public TestEventListener {
method TestEventRepeater (line 3759) | TestEventRepeater() : forwarding_enabled_(true) {}
method forwarding_enabled (line 3766) | bool forwarding_enabled() const { return forwarding_enabled_; }
method set_forwarding_enabled (line 3767) | void set_forwarding_enabled(bool enable) { forwarding_enabled_ = e...
method TestEventRepeater (line 3799) | TestEventRepeater(const TestEventRepeater&) = delete;
method TestEventRepeater (line 3800) | TestEventRepeater& operator=(const TestEventRepeater&) = delete;
function TestEventListener (line 3811) | TestEventListener* TestEventRepeater::Release(TestEventListener* lis...
class XmlUnitTestResultPrinter (line 3888) | class XmlUnitTestResultPrinter : public EmptyTestEventListener {
method IsNormalizableWhitespace (line 3902) | static bool IsNormalizableWhitespace(unsigned char c) {
method IsValidXmlCharacter (line 3908) | static bool IsValidXmlCharacter(unsigned char c) {
method EscapeXmlAttribute (line 3922) | static std::string EscapeXmlAttribute(const std::string& str) {
method EscapeXmlText (line 3927) | static std::string EscapeXmlText(const char* str) {
method XmlUnitTestResultPrinter (line 3978) | XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;
method XmlUnitTestResultPrinter (line 3979) | XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter...
function FormatTimeInMillisAsSeconds (line 4094) | std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
function PortableLocaltime (line 4100) | static bool PortableLocaltime(time_t seconds, struct tm* out) {
function FormatEpochTimeInMillisAsIso8601 (line 4121) | std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
class JsonUnitTestResultPrinter (line 4436) | class JsonUnitTestResultPrinter : public EmptyTestEventListener {
method JsonUnitTestResultPrinter (line 4492) | JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;
method JsonUnitTestResultPrinter (line 4493) | JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrint...
function FormatTimeInMillisAsDuration (line 4558) | static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
function FormatEpochTimeInMillisAsRFC3339 (line 4566) | static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
function Indent (line 4579) | static inline std::string Indent(size_t width) {
function GTEST_LOCK_EXCLUDED_ (line 4949) | GTEST_LOCK_EXCLUDED_(mutex_) {
function GTEST_LOCK_EXCLUDED_ (line 4998) | GTEST_LOCK_EXCLUDED_(mutex_) {
class ScopedPrematureExitFile (line 5012) | class ScopedPrematureExitFile {
method ScopedPrematureExitFile (line 5014) | explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
method ScopedPrematureExitFile (line 5044) | ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
method ScopedPrematureExitFile (line 5045) | ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&)...
class TestSuiteNameIs (line 5673) | class TestSuiteNameIs {
method TestSuiteNameIs (line 5676) | explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
function TestSuite (line 5700) | TestSuite* UnitTestImpl::GetTestSuite(
function SetUpEnvironment (line 5736) | static void SetUpEnvironment(Environment* env) { env->SetUp(); }
function TearDownEnvironment (line 5737) | static void TearDownEnvironment(Environment* env) { env->TearDown(); }
function WriteToShardStatusFileIfNeeded (line 5947) | void WriteToShardStatusFileIfNeeded() {
function ShouldShard (line 5969) | bool ShouldShard(const char* total_shards_env, const char* shard_ind...
function Int32FromEnvOrDie (line 6013) | int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {
function ShouldRunTestOnShard (line 6031) | bool ShouldRunTestOnShard(int total_shards, int shard_index, int tes...
function PrintOnOneLine (line 6101) | static void PrintOnOneLine(const char* str, int max_length) {
function OsStackTraceGetterInterface (line 6188) | OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
function TestResult (line 6201) | TestResult* UnitTestImpl::current_test_result() {
function GTEST_NO_INLINE_ (line 6247) | GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
class ClassUniqueToAlwaysTrue (line 6257) | class ClassUniqueToAlwaysTrue {}
function IsTrue (line 6260) | bool IsTrue(bool condition) { return condition; }
function AlwaysTrue (line 6262) | bool AlwaysTrue() {
function SkipPrefix (line 6274) | bool SkipPrefix(const char* prefix, const char** pstr) {
function ParseFlag (line 6326) | static bool ParseFlag(const char* str, const char* flag_name, bool* ...
function ParseFlag (line 6342) | bool ParseFlag(const char* str, const char* flag_name, int32_t* valu...
function ParseFlag (line 6359) | static bool ParseFlag(const char* str, const char* flag_name, String...
function HasGoogleTestFlagPrefix (line 6377) | static bool HasGoogleTestFlagPrefix(const char* str) {
function PrintColorEncoded (line 6394) | static void PrintColorEncoded(const char* str) {
function ParseGoogleTestFlag (line 6524) | static bool ParseGoogleTestFlag(const char* const arg) {
function LoadFlagsFromFile (line 6559) | static void LoadFlagsFromFile(const std::string& path) {
function ParseGoogleTestFlagsOnlyImpl (line 6580) | void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
function ParseGoogleTestFlagsOnly (line 6631) | void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
function ParseGoogleTestFlagsOnly (line 6665) | void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
function InitGoogleTestImpl (line 6674) | void InitGoogleTestImpl(int* argc, CharType** argv) {
function IsSubstringPred (line 1746) | bool IsSubstringPred(const char* needle, const char* haystack) {
function IsSubstringPred (line 1752) | bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
function IsSubstringPred (line 1760) | bool IsSubstringPred(const StringType& needle, const StringType& hayst...
function AssertionResult (line 1769) | AssertionResult IsSubstringImpl(bool expected_to_be_substring,
function AssertionResult (line 1793) | AssertionResult IsSubstring(const char* needle_expr, const char* hayst...
function AssertionResult (line 1798) | AssertionResult IsSubstring(const char* needle_expr, const char* hayst...
function AssertionResult (line 1803) | AssertionResult IsNotSubstring(const char* needle_expr,
function AssertionResult (line 1809) | AssertionResult IsNotSubstring(const char* needle_expr,
function AssertionResult (line 1815) | AssertionResult IsSubstring(const char* needle_expr, const char* hayst...
function AssertionResult (line 1821) | AssertionResult IsNotSubstring(const char* needle_expr,
function AssertionResult (line 1829) | AssertionResult IsSubstring(const char* needle_expr, const char* hayst...
function AssertionResult (line 1835) | AssertionResult IsNotSubstring(const char* needle_expr,
type internal (line 1843) | namespace internal {
function FILE (line 190) | static FILE* OpenFileForWriting(const std::string& output_file) {
function GTestIsInitialized (line 397) | static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
function SumOverTestSuiteList (line 402) | static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_...
function TestSuitePassed (line 412) | static bool TestSuitePassed(const TestSuite* test_suite) {
function TestSuiteFailed (line 417) | static bool TestSuiteFailed(const TestSuite* test_suite) {
function ShouldRunTestSuite (line 423) | static bool ShouldRunTestSuite(const TestSuite* test_suite) {
class FailureTest (line 455) | class FailureTest : public Test {
method FailureTest (line 457) | explicit FailureTest(const CodeLocation& loc, std::string error_me...
method TestBody (line 463) | void TestBody() override {
function InsertSyntheticTestCase (line 491) | void InsertSyntheticTestCase(const std::string& name, CodeLocation l...
function RegisterTypeParameterizedTestSuite (line 535) | void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
function RegisterTypeParameterizedTestSuiteInstantiation (line 541) | void RegisterTypeParameterizedTestSuiteInstantiation(const char* cas...
function GetArgvs (line 602) | ::std::vector<std::string> GetArgvs() {
function FilePath (line 615) | FilePath GetCurrentExecutableName() {
function PatternMatchesString (line 677) | static bool PatternMatchesString(const std::string& name_str,
function IsGlobPattern (line 726) | bool IsGlobPattern(const std::string& pattern) {
class UnitTestFilter (line 731) | class UnitTestFilter {
method UnitTestFilter (line 733) | UnitTestFilter() = default;
method UnitTestFilter (line 736) | explicit UnitTestFilter(const std::string& filter) {
method MatchesName (line 754) | bool MatchesName(const std::string& name) const {
class PositiveAndNegativeUnitTestFilter (line 769) | class PositiveAndNegativeUnitTestFilter {
method PositiveAndNegativeUnitTestFilter (line 776) | explicit PositiveAndNegativeUnitTestFilter(const std::string& filt...
method MatchesTest (line 806) | bool MatchesTest(const std::string& test_suite_name,
method MatchesName (line 813) | bool MatchesName(const std::string& name) const {
function TypeId (line 927) | TypeId GetTestTypeId() { return GetTypeId<Test>(); }
function AssertionResult (line 936) | static AssertionResult HasOneFailure(const char* /* results_expr */,
function TestPartResultReporterInterface (line 1008) | TestPartResultReporterInterface*
function TestPartResultReporterInterface (line 1022) | TestPartResultReporterInterface*
class Timer (line 1114) | class Timer {
method Timer (line 1116) | Timer() : start_(std::chrono::steady_clock::now()) {}
method TimeInMillis (line 1119) | TimeInMillis Elapsed() {
function TimeInMillis (line 1132) | TimeInMillis GetTimeInMillis() {
function LPCWSTR (line 1148) | LPCWSTR String::AnsiToUtf16(const char* ansi) {
function StreamWideCharsToMessage (line 1194) | static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len...
function SplitString (line 1209) | void SplitString(const ::std::string& str, char delimiter,
type edit_distance (line 1265) | namespace edit_distance {
function CalculateOptimalEdits (line 1266) | std::vector<EditType> CalculateOptimalEdits(const std::vector<size...
class InternalStrings (line 1326) | class InternalStrings {
method GetId (line 1328) | size_t GetId(const std::string& str) {
function CalculateOptimalEdits (line 1342) | std::vector<EditType> CalculateOptimalEdits(
class Hunk (line 1364) | class Hunk {
method Hunk (line 1366) | Hunk(size_t left_start, size_t right_start)
method PushLine (line 1373) | void PushLine(char edit, const char* line) {
method PrintTo (line 1391) | void PrintTo(std::ostream* os) {
method has_edits (line 1401) | bool has_edits() const { return adds_ || removes_; }
method FlushEdits (line 1404) | void FlushEdits() {
method PrintHeader (line 1413) | void PrintHeader(std::ostream* ss) const {
function CreateUnifiedDiff (line 1441) | std::string CreateUnifiedDiff(const std::vector<std::string>& left,
function SplitEscapedString (line 1511) | std::vector<std::string> SplitEscapedString(const std::string& str) {
function AssertionResult (line 1551) | AssertionResult EqFailure(const char* lhs_expression,
function GetBoolAssertionFailureMessage (line 1583) | std::string GetBoolAssertionFailureMessage(
function AssertionResult (line 1596) | AssertionResult DoubleNearPredFormat(const char* expr1, const char* ...
function AssertionResult (line 1637) | AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
function AssertionResult (line 1687) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 1699) | AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
function AssertionResult (line 1711) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function AssertionResult (line 1724) | AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
function AssertionResult (line 1850) | AssertionResult HRESULTFailureHelper(const char* expr, const char* e...
function AssertionResult (line 1890) | AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NO...
function AssertionResult (line 1897) | AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NO...
function ChopLowBits (line 1935) | inline uint32_t ChopLowBits(uint32_t* bits, int n) {
function CodePointToUtf8 (line 1947) | std::string CodePointToUtf8(uint32_t code_point) {
function IsUtf16SurrogatePair (line 1982) | inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
function CreateCodePointFromUtf16SurrogatePair (line 1988) | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
function WideStringToUtf8 (line 2014) | std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
function AssertionResult (line 2059) | AssertionResult CmpHelperSTREQ(const char* lhs_expression,
function AssertionResult (line 2071) | AssertionResult CmpHelperSTRNE(const char* s1_expression,
function StringStreamToString (line 2174) | std::string StringStreamToString(::std::strings
Condensed preview — 178 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,392K chars).
[
{
"path": ".gitattributes",
"chars": 66,
"preview": "/test/www*/dir/*.html text eol=lf\n/test/www*/dir/*.txt text eol=lf"
},
{
"path": ".github/workflows/abidiff.yaml",
"chars": 1676,
"preview": "# SPDX-FileCopyrightText: 2025 Andrea Pappacoda <andrea@pappacoda.it>\n# SPDX-License-Identifier: MIT\n\nname: abidiff\n\non:"
},
{
"path": ".github/workflows/cifuzz.yaml",
"chars": 817,
"preview": "name: CIFuzz\n\non: [pull_request]\n\nconcurrency:\n group: ${{ github.workflow }}-${{ github.ref || github.run_id }}\n canc"
},
{
"path": ".github/workflows/docs.yml",
"chars": 808,
"preview": "name: docs\non:\n push:\n branches: [master]\n paths:\n - 'docs-src/**'\npermissions:\n contents: read\n pages: wr"
},
{
"path": ".github/workflows/release-docker.yml",
"chars": 1577,
"preview": "name: Release Docker Image\n\non:\n release:\n types: [published]\n workflow_dispatch:\n\njobs:\n build-and-push:\n runs"
},
{
"path": ".github/workflows/test-32bit.yml",
"chars": 1055,
"preview": "name: 32-bit Build Test\n\non:\n push:\n branches: [master]\n pull_request:\n branches: [master]\n workflow_dispatch:\n"
},
{
"path": ".github/workflows/test.yaml",
"chars": 9817,
"preview": "name: test\n\non:\n push:\n pull_request:\n workflow_dispatch:\n inputs:\n gtest_filter:\n description: 'Googl"
},
{
"path": ".github/workflows/test_benchmark.yaml",
"chars": 3171,
"preview": "name: benchmark\n\non:\n push:\n pull_request:\n workflow_dispatch:\n\nconcurrency:\n group: ${{ github.workflow }}-${{ gith"
},
{
"path": ".github/workflows/test_no_exceptions.yaml",
"chars": 736,
"preview": "name: No Exceptions Test\n\non: [push, pull_request]\n\njobs:\n test-no-exceptions:\n runs-on: ubuntu-latest\n if: githu"
},
{
"path": ".github/workflows/test_offline.yaml",
"chars": 2052,
"preview": "name: test_offline\n\non:\n push:\n pull_request:\n workflow_dispatch:\n inputs:\n test_linux:\n description: "
},
{
"path": ".github/workflows/test_proxy.yaml",
"chars": 1212,
"preview": "name: Proxy Test\n\non: [push, pull_request]\n\njobs:\n test-proxy:\n runs-on: ubuntu-latest\n if: github.event_name != "
},
{
"path": "CMakeLists.txt",
"chars": 20162,
"preview": "#[[\n\tBuild options:\n\t* Standard BUILD_SHARED_LIBS is supported and sets HTTPLIB_SHARED default value.\n\t* HTTPLIB_USE_OPE"
},
{
"path": "Dockerfile",
"chars": 372,
"preview": "FROM yhirose4dockerhub/ubuntu-builder AS builder\nWORKDIR /build\nCOPY httplib.h .\nCOPY docker/main.cc .\nRUN g++ -std=c++2"
},
{
"path": "LICENSE",
"chars": 1075,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2017 yhirose\n\nPermission is hereby granted, free of charge, to any person obtaining"
},
{
"path": "README-sse.md",
"chars": 3745,
"preview": "# SSEClient - Server-Sent Events Client\n\nA simple, EventSource-like SSE client for C++11.\n\n## Features\n\n- **Auto-reconne"
},
{
"path": "README-stream.md",
"chars": 10143,
"preview": "# cpp-httplib Streaming API\n\nThis document describes the streaming extensions for cpp-httplib, providing an iterator-sty"
},
{
"path": "README-websocket.md",
"chars": 11970,
"preview": "# WebSocket - RFC 6455 WebSocket Support\n\nA simple, blocking WebSocket implementation for C++11.\n\n> [!IMPORTANT]\n> This "
},
{
"path": "README.md",
"chars": 46314,
"preview": "# cpp-httplib\n\n[](https://github.com/yhirose/cpp-htt"
},
{
"path": "benchmark/Makefile",
"chars": 1126,
"preview": "CXXFLAGS = -O2 -I..\n\nCPPHTTPLIB_CXXFLAGS = -std=c++11\nCROW_CXXFLAGS = -std=c++17\n\nCPPHTTPLIB_FLAGS = -DCPPHTTPLIB_THREAD"
},
{
"path": "benchmark/cpp-httplib/main.cpp",
"chars": 218,
"preview": "#include \"httplib.h\"\nusing namespace httplib;\n\nint main() {\n Server svr;\n\n svr.Get(\"/\", [](const Request &, Response &"
},
{
"path": "benchmark/crow/crow_all.h",
"chars": 444423,
"preview": "// SPDX-License-Identifier: BSD-3-Clause AND ISC AND MIT\n/*BSD 3-Clause License\n\nCopyright (c) 2014-2017, ipkn\n "
},
{
"path": "benchmark/crow/main.cpp",
"chars": 332,
"preview": "#include \"crow_all.h\"\n\nclass CustomLogger : public crow::ILogHandler {\npublic:\n void log(const std::string &, crow::Log"
},
{
"path": "cmake/FindBrotli.cmake",
"chars": 6561,
"preview": "# A simple FindBrotli package for Cmake's find_package function.\n# Note: This find package doesn't have version support,"
},
{
"path": "cmake/httplibConfig.cmake.in",
"chars": 4556,
"preview": "# Generates a macro to auto-configure everything\n@PACKAGE_INIT@\n\n# Setting these here so they're accessible after instal"
},
{
"path": "cmake/modules.cmake",
"chars": 447,
"preview": "# This file contains C++20 module support requiring CMake 3.28+\n# Included conditionally to prevent parse errors on olde"
},
{
"path": "docker/html/index.html",
"chars": 599,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to cpp-httplib!</title>\n<style>\nhtml { color-scheme: light dark; }\nbody { w"
},
{
"path": "docker/main.cc",
"chars": 10773,
"preview": "//\n// main.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <atomic>\n#includ"
},
{
"path": "docker-compose.yml",
"chars": 101,
"preview": "services:\n http:\n build: .\n ports:\n - \"8080:80\"\n volumes:\n - ./docker/html:/html\n"
},
{
"path": "docs-src/config.toml",
"chars": 1875,
"preview": "[system]\ntheme = \"monotone\"\nlangs = [\"en\", \"ja\"]\n\n[site]\ntitle = \"cpp-httplib\"\nversion = \"0.38.0\"\nhostname = \"https://yh"
},
{
"path": "docs-src/pages/en/cookbook/index.md",
"chars": 3281,
"preview": "---\ntitle: \"Cookbook\"\norder: 0\nstatus: \"draft\"\n---\n\nA collection of recipes that answer \"How do I...?\" questions. Each r"
},
{
"path": "docs-src/pages/en/index.md",
"chars": 1601,
"preview": "---\ntitle: \"cpp-httplib\"\norder: 0\n---\n\n[cpp-httplib](https://github.com/yhirose/cpp-httplib) is an HTTP/HTTPS library fo"
},
{
"path": "docs-src/pages/en/llm-app/index.md",
"chars": 1464,
"preview": "---\ntitle: \"Building a Desktop LLM App with cpp-httplib\"\norder: 0\nstatus: \"draft\"\n---\n\nBuild an LLM-powered translation "
},
{
"path": "docs-src/pages/en/tour/01-getting-started.md",
"chars": 2133,
"preview": "---\ntitle: \"Getting Started\"\norder: 1\n---\n\nAll you need to get started with cpp-httplib is `httplib.h` and a C++ compile"
},
{
"path": "docs-src/pages/en/tour/02-basic-client.md",
"chars": 7127,
"preview": "---\ntitle: \"Basic Client\"\norder: 2\n---\n\ncpp-httplib isn't just for servers -- it also comes with a full HTTP client. Let"
},
{
"path": "docs-src/pages/en/tour/03-basic-server.md",
"chars": 8063,
"preview": "---\ntitle: \"Basic Server\"\norder: 3\n---\n\nIn the previous chapter, you sent requests from a client to a test server. Now l"
},
{
"path": "docs-src/pages/en/tour/04-static-file-server.md",
"chars": 3941,
"preview": "---\ntitle: \"Static File Server\"\norder: 4\n---\n\ncpp-httplib can serve static files too — HTML, CSS, images, you name it. N"
},
{
"path": "docs-src/pages/en/tour/05-tls-setup.md",
"chars": 2849,
"preview": "---\ntitle: \"TLS Setup\"\norder: 5\n---\n\nSo far we've been using plain HTTP, but in the real world, HTTPS is the norm. To us"
},
{
"path": "docs-src/pages/en/tour/06-https-client.md",
"chars": 3549,
"preview": "---\ntitle: \"HTTPS Client\"\norder: 6\n---\n\nIn the previous chapter, you set up OpenSSL. Now let's put it to use with an HTT"
},
{
"path": "docs-src/pages/en/tour/07-https-server.md",
"chars": 3681,
"preview": "---\ntitle: \"HTTPS Server\"\norder: 7\n---\n\nIn the previous chapter, you used an HTTPS client. Now let's set up your own HTT"
},
{
"path": "docs-src/pages/en/tour/08-websocket.md",
"chars": 3726,
"preview": "---\ntitle: \"WebSocket\"\norder: 8\n---\n\ncpp-httplib supports WebSocket as well. Unlike HTTP request/response, WebSocket let"
},
{
"path": "docs-src/pages/en/tour/09-whats-next.md",
"chars": 6577,
"preview": "---\ntitle: \"What's Next\"\norder: 9\n---\n\nGreat job finishing the Tour! You now have a solid grasp of the cpp-httplib basic"
},
{
"path": "docs-src/pages/en/tour/index.md",
"chars": 865,
"preview": "---\ntitle: \"A Tour of cpp-httplib\"\norder: 0\n---\n\nThis is a step-by-step tutorial that walks you through the basics of cp"
},
{
"path": "docs-src/pages/ja/cookbook/index.md",
"chars": 2367,
"preview": "---\ntitle: \"Cookbook\"\norder: 0\nstatus: \"draft\"\n---\n\n「〇〇をするには?」という問いに答えるレシピ集です。各レシピは独立しているので、必要なページだけ読めます。\n\n## クライアント\n\n##"
},
{
"path": "docs-src/pages/ja/index.md",
"chars": 970,
"preview": "---\ntitle: \"cpp-httplib\"\norder: 0\n---\n\n[cpp-httplib](https://github.com/yhirose/cpp-httplib)は、C++用のHTTP/HTTPSライブラリです。[`h"
},
{
"path": "docs-src/pages/ja/llm-app/index.md",
"chars": 989,
"preview": "---\ntitle: \"Building a Desktop LLM App with cpp-httplib\"\norder: 0\nstatus: \"draft\"\n---\n\nllama.cpp を組み込んだ LLM 翻訳デスクトップアプリを"
},
{
"path": "docs-src/pages/ja/tour/01-getting-started.md",
"chars": 1663,
"preview": "---\ntitle: \"Getting Started\"\norder: 1\n---\n\ncpp-httplibを始めるのに必要なのは、`httplib.h`とC++コンパイラーだけです。ファイルをダウンロードして、Hello Worldサーバ"
},
{
"path": "docs-src/pages/ja/tour/02-basic-client.md",
"chars": 5927,
"preview": "---\ntitle: \"Basic Client\"\norder: 2\n---\n\ncpp-httplibはサーバーだけでなく、HTTPクライアント機能も備えています。`httplib::Client` を使って、GETやPOSTリクエストを送"
},
{
"path": "docs-src/pages/ja/tour/03-basic-server.md",
"chars": 6670,
"preview": "---\ntitle: \"Basic Server\"\norder: 3\n---\n\n前章ではクライアントからリクエストを送りました。そのとき、テスト用サーバーを用意しましたね。この章では、あのサーバーの仕組みをひとつずつ紐解いていきます。\n\n#"
},
{
"path": "docs-src/pages/ja/tour/04-static-file-server.md",
"chars": 3005,
"preview": "---\ntitle: \"Static File Server\"\norder: 4\n---\n\ncpp-httplibは、HTMLやCSS、画像ファイルなどの静的ファイルも配信できます。面倒な設定は要りません。`set_mount_point("
},
{
"path": "docs-src/pages/ja/tour/05-tls-setup.md",
"chars": 2321,
"preview": "---\ntitle: \"TLS Setup\"\norder: 5\n---\n\nここまではHTTP(平文)でやってきましたが、実際のWebではHTTPS(暗号化通信)が当たり前ですよね。cpp-httplibでHTTPSを使うには、TLSライブラ"
},
{
"path": "docs-src/pages/ja/tour/06-https-client.md",
"chars": 2626,
"preview": "---\ntitle: \"HTTPS Client\"\norder: 6\n---\n\n前章でOpenSSLのセットアップが済んだので、さっそくHTTPSクライアントを使ってみましょう。2章で使った `httplib::Client` がそのまま使"
},
{
"path": "docs-src/pages/ja/tour/07-https-server.md",
"chars": 2565,
"preview": "---\ntitle: \"HTTPS Server\"\norder: 7\n---\n\n前章ではHTTPSクライアントを使いました。今度は自分でHTTPSサーバーを立ててみましょう。3章の `httplib::Server` を `httplib:"
},
{
"path": "docs-src/pages/ja/tour/08-websocket.md",
"chars": 3009,
"preview": "---\ntitle: \"WebSocket\"\norder: 8\n---\n\ncpp-httplibはWebSocketにも対応しています。HTTPのリクエスト/レスポンスと違い、WebSocketはサーバーとクライアントが双方向にメッセージを"
},
{
"path": "docs-src/pages/ja/tour/09-whats-next.md",
"chars": 5457,
"preview": "---\ntitle: \"What's Next\"\norder: 9\n---\n\nTourお疲れさまでした! cpp-httplibの基本はひと通り押さえましたね。でも、まだまだ便利な機能があります。Tourで取り上げなかった機能をカテゴリー別"
},
{
"path": "docs-src/pages/ja/tour/index.md",
"chars": 630,
"preview": "---\ntitle: \"A Tour of cpp-httplib\"\norder: 0\n---\n\ncpp-httplibの基本を、順番に学んでいくチュートリアルです。各章は前の章の内容を踏まえて進む構成なので、1章から順に読んでください。\n"
},
{
"path": "example/Dockerfile.hello",
"chars": 330,
"preview": "FROM alpine as builder\nWORKDIR /src/example\nRUN apk add g++ make openssl-dev zlib-dev brotli-dev\nCOPY ./httplib.h /src\nC"
},
{
"path": "example/Makefile",
"chars": 3088,
"preview": "#CXX = clang++\nCXXFLAGS = -O2 -std=c++11 -I.. -Wall -Wextra -pthread\n\nPREFIX ?= $(shell brew --prefix)\n\nOPENSSL_DIR = $("
},
{
"path": "example/accept_header.cc",
"chars": 5815,
"preview": "#include \"httplib.h\"\n#include <iostream>\n\nint main() {\n using namespace httplib;\n \n // Example usage of parse_a"
},
{
"path": "example/benchmark.cc",
"chars": 800,
"preview": "#include <chrono>\n#include <httplib.h>\n#include <iostream>\n\nusing namespace std;\n\nstruct StopWatch {\n StopWatch(const s"
},
{
"path": "example/ca-bundle.crt",
"chars": 219592,
"preview": "##\n## Bundle of CA Root Certificates\n##\n## Certificate data from Mozilla as of: Tue Jan 22 14:14:40 2019 GMT\n##\n## This "
},
{
"path": "example/client.cc",
"chars": 967,
"preview": "//\n// client.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <httplib.h>\n#i"
},
{
"path": "example/client.vcxproj",
"chars": 8686,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro"
},
{
"path": "example/example.sln",
"chars": 2427,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nVisualStudioVersion = 15.0.27703.204"
},
{
"path": "example/hello.cc",
"chars": 328,
"preview": "//\n// hello.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <httplib.h>\nusi"
},
{
"path": "example/one_time_request.cc",
"chars": 1331,
"preview": "#include <httplib.h>\n#include <iostream>\n\nusing namespace httplib;\n\nconst char *HOST = \"localhost\";\nconst int PORT = 123"
},
{
"path": "example/redirect.cc",
"chars": 1336,
"preview": "//\n// redirect.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <httplib.h>\n"
},
{
"path": "example/server.cc",
"chars": 2729,
"preview": "//\n// sample.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <chrono>\n#incl"
},
{
"path": "example/server.vcxproj",
"chars": 8125,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro"
},
{
"path": "example/server_and_client.cc",
"chars": 2015,
"preview": "//\n// server_and_client.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <ht"
},
{
"path": "example/simplecli.cc",
"chars": 583,
"preview": "//\n// simplecli.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <httplib.h>"
},
{
"path": "example/simplesvr.cc",
"chars": 3513,
"preview": "//\n// simplesvr.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <cstdio>\n#i"
},
{
"path": "example/ssecli-stream.cc",
"chars": 8417,
"preview": "//\n// ssecli-stream.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n// SSE (Server-S"
},
{
"path": "example/ssecli.cc",
"chars": 1291,
"preview": "//\n// ssecli.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <httplib.h>\n\n#"
},
{
"path": "example/ssesvr.cc",
"chars": 2464,
"preview": "#include <atomic>\n#include <chrono>\n#include <condition_variable>\n#include <httplib.h>\n#include <iostream>\n#include <mut"
},
{
"path": "example/upload.cc",
"chars": 1480,
"preview": "//\n// upload.cc\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#include <fstream>\n#inc"
},
{
"path": "example/uploader.sh",
"chars": 143,
"preview": "#/usr/bin/env bash\nfor i in {1..1000000}\ndo\n echo \"#### $i ####\"\n curl -X POST -F image_file=@$1 http://localhost:1234"
},
{
"path": "example/wsecho.cc",
"chars": 3697,
"preview": "#include <httplib.h>\n#include <iostream>\n\nusing namespace httplib;\n\nconst auto html = R\"HTML(\n<!DOCTYPE html>\n<html lang"
},
{
"path": "generate_module.py",
"chars": 2527,
"preview": "#!/usr/bin/env python3\n\n\"\"\"This script generates httplib.cppm module file from httplib.h.\"\"\"\n\nimport os\nimport sys\nfrom "
},
{
"path": "httplib.h",
"chars": 681848,
"preview": "//\n// httplib.h\n//\n// Copyright (c) 2026 Yuji Hirose. All rights reserved.\n// MIT License\n//\n\n#ifndef CPPHTTPLIB_HTTP"
},
{
"path": "justfile",
"chars": 1489,
"preview": "set shell := [\"bash\", \"-c\"]\n\ndefault: list\n\nlist:\n @just --list --unsorted\n\nopenssl:\n @(cd test && LSAN_OPTIONS=su"
},
{
"path": "meson.build",
"chars": 4981,
"preview": "# SPDX-FileCopyrightText: 2021 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\nproject(\n 'cpp-httplib',\n 'cpp',\n l"
},
{
"path": "meson_options.txt",
"chars": 1816,
"preview": "# SPDX-FileCopyrightText: 2021 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\noption('tls', type: 'feature', des"
},
{
"path": "split.py",
"chars": 2481,
"preview": "#!/usr/bin/env python3\n\n\"\"\"This script splits httplib.h into .h and .cc parts.\"\"\"\n\nimport os\nimport sys\nfrom argparse im"
},
{
"path": "test/CMakeLists.txt",
"chars": 4519,
"preview": "find_package(GTest)\n\nif(GTest_FOUND)\n if(NOT TARGET GTest::gtest_main AND TARGET GTest::Main)\n # CMake <3.20\n "
},
{
"path": "test/Makefile",
"chars": 10737,
"preview": "CXX = clang++\nCXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion -Wshadow $(EXTRA_CXXFLAGS) -DCPPHTTP"
},
{
"path": "test/ca-bundle.crt",
"chars": 219592,
"preview": "##\n## Bundle of CA Root Certificates\n##\n## Certificate data from Mozilla as of: Tue Jan 22 14:14:40 2019 GMT\n##\n## This "
},
{
"path": "test/fuzzing/CMakeLists.txt",
"chars": 273,
"preview": "file(GLOB HTTPLIB_CORPUS corpus/*)\nadd_executable(httplib-test-fuzz\n server_fuzzer.cc\n standalone_fuzz_target_runn"
},
{
"path": "test/fuzzing/Makefile",
"chars": 1274,
"preview": "\n#CXX = clang++\n# Do not add default sanitizer flags here as OSS-fuzz adds its own sanitizer flags.\nCXXFLAGS += -ggdb -O"
},
{
"path": "test/fuzzing/corpus/1",
"chars": 32,
"preview": "PUT /search/sample?a=12 HTTP/1.1"
},
{
"path": "test/fuzzing/corpus/2",
"chars": 159,
"preview": "GET /hello.htm HTTP/1.1\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)\nAccept-Language: en-us\nAccept-Encodin"
},
{
"path": "test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6508706672541696",
"chars": 878898,
"preview": "PUT { HTTP/1.0\r\nContent-Type:multipart/form-databoundary=m\r\nRange:bytes=-\r\n\r\n--m\r\nC\u001d\nc\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r"
},
{
"path": "test/fuzzing/server_fuzzer.cc",
"chars": 3102,
"preview": "#include <cstdint>\n\n#include <httplib.h>\n\nclass FuzzedStream : public httplib::Stream {\npublic:\n FuzzedStream(const uin"
},
{
"path": "test/fuzzing/server_fuzzer.dict",
"chars": 2906,
"preview": "# Sources: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields\n\n# misc\n\"HTTP/1.1\"\n\n# verbs\n\"CONNECT\"\n\"DELETE\"\n\"GET\""
},
{
"path": "test/fuzzing/standalone_fuzz_target_runner.cpp",
"chars": 1390,
"preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n\n/"
},
{
"path": "test/gen-certs.sh",
"chars": 1279,
"preview": "#!/usr/bin/env bash\nif [[ $(openssl version) =~ 3\\.[2-9]\\.[0-9]+ ]]; then\n\tOPENSSL_X509_FLAG='-x509v1'\nelse\n\tOPENSSL_X50"
},
{
"path": "test/gtest/include/gtest/gtest-assertion-result.h",
"chars": 8502,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-death-test.h",
"chars": 14886,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-matchers.h",
"chars": 33615,
"preview": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-message.h",
"chars": 8109,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-param-test.h",
"chars": 22870,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-printers.h",
"chars": 36609,
"preview": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-spi.h",
"chars": 12824,
"preview": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-test-part.h",
"chars": 7111,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest-typed-test.h",
"chars": 15921,
"preview": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or w"
},
{
"path": "test/gtest/include/gtest/gtest.h",
"chars": 89715,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest_pred_impl.h",
"chars": 12783,
"preview": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/gtest_prod.h",
"chars": 2502,
"preview": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/custom/README.md",
"chars": 1269,
"preview": "# Customization Points\n\nThe custom directory is an injection point for custom user configurations.\n\n## Header `gtest.h`\n"
},
{
"path": "test/gtest/include/gtest/internal/custom/gtest-port.h",
"chars": 1873,
"preview": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/custom/gtest-printers.h",
"chars": 2094,
"preview": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/custom/gtest.h",
"chars": 1858,
"preview": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-death-test-internal.h",
"chars": 13916,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-filepath.h",
"chars": 9817,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-internal.h",
"chars": 63795,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-param-util.h",
"chars": 35639,
"preview": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or w"
},
{
"path": "test/gtest/include/gtest/internal/gtest-port-arch.h",
"chars": 4127,
"preview": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-port.h",
"chars": 87637,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-string.h",
"chars": 7301,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/include/gtest/internal/gtest-type-util.h",
"chars": 6247,
"preview": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or w"
},
{
"path": "test/gtest/src/gtest-all.cc",
"chars": 2201,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-assertion-result.cc",
"chars": 3021,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-death-test.cc",
"chars": 63129,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-filepath.cc",
"chars": 14054,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-internal-inl.h",
"chars": 47662,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-matchers.cc",
"chars": 3724,
"preview": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-port.cc",
"chars": 47857,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-printers.cc",
"chars": 18478,
"preview": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-test-part.cc",
"chars": 4024,
"preview": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest-typed-test.cc",
"chars": 3768,
"preview": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or w"
},
{
"path": "test/gtest/src/gtest.cc",
"chars": 255540,
"preview": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/gtest/src/gtest_main.cc",
"chars": 1967,
"preview": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "test/include_httplib.cc",
"chars": 212,
"preview": "// The sole purpose of this file is to include httplib.h in a separate\n// compilation unit, thus verifying that inline k"
},
{
"path": "test/include_windows_h.cc",
"chars": 128,
"preview": "// Test if including windows.h conflicts with httplib.h\n\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\n#include <htt"
},
{
"path": "test/lsan_suppressions.txt",
"chars": 165,
"preview": "# OpenSSL 3.x internal caches (provider, cipher, keymgmt) are allocated\n# lazily and intentionally kept until process ex"
},
{
"path": "test/make-shared-library.sh",
"chars": 464,
"preview": "#!/usr/bin/env bash\nif [ \"$#\" -ne 1 ]; then\n echo \"Usage: $0 build_dir\"\n exit 1\nfi\n\nBUILD_DIR=$1\n\n# Make the build"
},
{
"path": "test/meson.build",
"chars": 4440,
"preview": "# SPDX-FileCopyrightText: 2021 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\ngtest_dep = dependency('gtest', main: "
},
{
"path": "test/proxy/Dockerfile",
"chars": 233,
"preview": "FROM alpine:latest\n\nARG auth=\"basic\"\nARG port=\"3128\"\n\nRUN apk update && apk add --no-cache squid\n\nCOPY ./${auth}_squid.c"
},
{
"path": "test/proxy/basic_passwd",
"chars": 44,
"preview": "hello:$apr1$O6S28OBL$8dr3ixl4Mohf97hgsYvLy/\n"
},
{
"path": "test/proxy/basic_squid.conf",
"chars": 2757,
"preview": "#\n# Recommended minimum configuration:\n#\n\n# Example rule allowing access from your local networks.\n# Adapt to list your "
},
{
"path": "test/proxy/digest_passwd",
"chars": 12,
"preview": "hello:world\n"
},
{
"path": "test/proxy/digest_squid.conf",
"chars": 2760,
"preview": "#\n# Recommended minimum configuration:\n#\n\n# Example rule allowing access from your local networks.\n# Adapt to list your "
},
{
"path": "test/proxy/docker-compose.ci.yml",
"chars": 164,
"preview": "services:\n squid_basic:\n extra_hosts:\n - \"host.docker.internal:host-gateway\"\n\n squid_digest:\n extra_hosts:\n"
},
{
"path": "test/proxy/docker-compose.yml",
"chars": 314,
"preview": "services:\n squid_basic:\n image: squid_basic\n restart: always\n ports:\n - \"3128:3128\"\n build:\n cont"
},
{
"path": "test/test.cc",
"chars": 536464,
"preview": "// NOTE: This file should be saved as UTF-8 w/ BOM\n#include <httplib.h>\n#include <signal.h>\n\n#ifndef _WIN32\n#include <a"
},
{
"path": "test/test.conf",
"chars": 590,
"preview": "[req]\ndefault_bits = 2048\ndistinguished_name = req_distinguished_name\nattributes = req_attribu"
},
{
"path": "test/test.rootCA.conf",
"chars": 556,
"preview": "[req]\ndefault_bits = 2048\ndistinguished_name = req_distinguished_name\nattributes = req_attribu"
},
{
"path": "test/test.sln",
"chars": 1341,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Express 2013 for Windows Desktop\r\nVisual"
},
{
"path": "test/test.vcxproj",
"chars": 8941,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.micro"
},
{
"path": "test/test_32bit_build.cpp",
"chars": 143,
"preview": "#include \"../httplib.h\"\n\nint main() {\n httplib::Server svr;\n httplib::Client cli(\"localhost\", 8080);\n (void)svr;\n (v"
},
{
"path": "test/test_benchmark.cc",
"chars": 2137,
"preview": "#include <httplib.h>\n\n#include <gtest/gtest.h>\n\n#include <algorithm>\n#include <chrono>\n#include <sstream>\n#include <thre"
},
{
"path": "test/test_proxy.cc",
"chars": 9865,
"preview": "#include <chrono>\n#include <future>\n#include <gtest/gtest.h>\n#include <httplib.h>\n\nusing namespace std;\nusing namespace "
},
{
"path": "test/test_thread_pool.cc",
"chars": 5626,
"preview": "// ThreadPool unit tests\n// Set a short idle timeout for faster shrink tests\n#define CPPHTTPLIB_THREAD_POOL_IDLE_TIMEOUT"
},
{
"path": "test/test_websocket_heartbeat.cc",
"chars": 4642,
"preview": "// Standalone test for WebSocket automatic heartbeat.\n// Compiled with a 1-second ping interval so we can verify heartbe"
},
{
"path": "test/www/dir/1MB.txt",
"chars": 1048576,
"preview": "925483597445888762967287363578995741188602469855415739384949486422802496293955068829707452719842026105167520599960968983"
},
{
"path": "test/www/dir/index.html",
"chars": 104,
"preview": "<html>\n<head>\n</head>\n<body>\n <a href=\"/dir/test.html\">Test</a>\n <a href=\"/hi\">hi</a>\n</body>\n</html>\n"
},
{
"path": "test/www/dir/meson.build",
"chars": 362,
"preview": "# SPDX-FileCopyrightText: 2021 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\nconfigure_file(input: 'index.html', ou"
},
{
"path": "test/www/dir/test.abcde",
"chars": 5,
"preview": "abcde"
},
{
"path": "test/www/dir/test.html",
"chars": 9,
"preview": "test.html"
},
{
"path": "test/www/empty_file",
"chars": 0,
"preview": ""
},
{
"path": "test/www/file",
"chars": 5,
"preview": "file\n"
},
{
"path": "test/www/meson.build",
"chars": 253,
"preview": "# SPDX-FileCopyrightText: 2024 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\nconfigure_file(input: 'empty_file', ou"
},
{
"path": "test/www/日本語Dir/meson.build",
"chars": 152,
"preview": "# SPDX-FileCopyrightText: 2025 Andrea Pappacoda\n# SPDX-License-Identifier: MIT\n\nconfigure_file(input: '日本語File.txt', out"
},
{
"path": "test/www/日本語Dir/日本語File.txt",
"chars": 8,
"preview": "日本語コンテンツ"
},
{
"path": "test/www2/dir/index.html",
"chars": 104,
"preview": "<html>\n<head>\n</head>\n<body>\n <a href=\"/dir/test.html\">Test</a>\n <a href=\"/hi\">hi</a>\n</body>\n</html>\n"
},
{
"path": "test/www2/dir/meson.build",
"chars": 222,
"preview": "# SPDX-FileCopyrightText: 2021 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\nconfigure_file(input: 'index.html', ou"
},
{
"path": "test/www2/dir/test.html",
"chars": 9,
"preview": "test.html"
},
{
"path": "test/www3/dir/index.html",
"chars": 104,
"preview": "<html>\n<head>\n</head>\n<body>\n <a href=\"/dir/test.html\">Test</a>\n <a href=\"/hi\">hi</a>\n</body>\n</html>\n"
},
{
"path": "test/www3/dir/meson.build",
"chars": 222,
"preview": "# SPDX-FileCopyrightText: 2021 Andrea Pappacoda\n#\n# SPDX-License-Identifier: MIT\n\nconfigure_file(input: 'index.html', ou"
},
{
"path": "test/www3/dir/test.html",
"chars": 9,
"preview": "test.html"
}
]
// ... and 9 more files (download for full content)
About this extraction
This page contains the full source code of the yhirose/cpp-httplib GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 178 files (5.1 MB), approximately 1.4M tokens, and a symbol index with 2029 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.