httpp 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {httpp-0.6.0 → httpp-0.7.0}/.github/workflows/cmake.yml +1 -1
- {httpp-0.6.0 → httpp-0.7.0}/.github/workflows/orchestrator.yml +12 -1
- httpp-0.7.0/.github/workflows/wheels.yml +103 -0
- {httpp-0.6.0 → httpp-0.7.0}/.gitmodules +3 -0
- httpp-0.7.0/CHANGELOG.md +198 -0
- {httpp-0.6.0 → httpp-0.7.0}/CMakeLists.txt +94 -1
- httpp-0.7.0/PKG-INFO +430 -0
- httpp-0.7.0/README.md +404 -0
- httpp-0.7.0/benchmarks/asgi_app.py +21 -0
- httpp-0.7.0/benchmarks/bench.py +99 -0
- httpp-0.7.0/benchmarks/bench_validate.py +67 -0
- httpp-0.7.0/benchmarks/httpp_app.py +50 -0
- httpp-0.7.0/cmake/EmbedFile.cmake +114 -0
- httpp-0.7.0/cmake/httpp_mbedtls_config.h +24 -0
- httpp-0.7.0/cmake/utils/embedded_files.in.hpp +12 -0
- httpp-0.7.0/docs/Architecture.md +404 -0
- httpp-0.7.0/docs/agent.md +381 -0
- httpp-0.7.0/docs/checklist.md +290 -0
- httpp-0.7.0/examples/python/01_hello_server.py +16 -0
- httpp-0.7.0/examples/python/02_path_params.py +23 -0
- httpp-0.7.0/examples/python/03_request_object.py +27 -0
- httpp-0.7.0/examples/python/04_responses.py +44 -0
- httpp-0.7.0/examples/python/05_http_methods.py +48 -0
- httpp-0.7.0/examples/python/06_async_handlers.py +37 -0
- httpp-0.7.0/examples/python/07_serve_directory.py +23 -0
- httpp-0.7.0/examples/python/08_error_handling.py +30 -0
- httpp-0.7.0/examples/python/09_client.py +37 -0
- httpp-0.7.0/examples/python/10_request_builder.py +44 -0
- httpp-0.7.0/examples/python/11_download.py +35 -0
- httpp-0.7.0/examples/python/12_hooks_and_settings.py +81 -0
- httpp-0.7.0/examples/python/13_streaming_and_files.py +84 -0
- httpp-0.7.0/examples/python/14_async_client.py +65 -0
- httpp-0.7.0/examples/python/15_progress_and_url.py +31 -0
- httpp-0.7.0/handoff.md +479 -0
- httpp-0.7.0/include/httpp/client.hpp +299 -0
- httpp-0.7.0/include/httpp/download.hpp +129 -0
- httpp-0.7.0/include/httpp/log.hpp +31 -0
- {httpp-0.6.0 → httpp-0.7.0}/include/httpp/progress.hpp +2 -1
- httpp-0.7.0/include/httpp/server.hpp +192 -0
- httpp-0.7.0/include/httpp/sha256.hpp +24 -0
- httpp-0.7.0/include/httpp/swagger_ui.hpp +30 -0
- {httpp-0.6.0 → httpp-0.7.0}/include/httpp/url.hpp +8 -0
- {httpp-0.6.0 → httpp-0.7.0}/include/httpp.h +2 -1
- {httpp-0.6.0 → httpp-0.7.0}/pyproject.toml +20 -4
- {httpp-0.6.0 → httpp-0.7.0}/src/bindings/python/CMakeLists.txt +13 -2
- httpp-0.7.0/src/bindings/python/_validate_cy.pyx +898 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/bindings/python/httpp/__init__.py +13 -2
- {httpp-0.6.0 → httpp-0.7.0}/src/bindings/python/httpp/__main__.py +34 -0
- httpp-0.7.0/src/bindings/python/httpp/_http.py +130 -0
- httpp-0.7.0/src/bindings/python/httpp/_params.py +448 -0
- httpp-0.7.0/src/bindings/python/httpp/_run.py +167 -0
- httpp-0.7.0/src/bindings/python/httpp/_schema.py +409 -0
- httpp-0.7.0/src/bindings/python/httpp/_validate.py +226 -0
- httpp-0.7.0/src/bindings/python/httpp/errors.py +50 -0
- httpp-0.7.0/src/bindings/python/httpp/models.py +497 -0
- httpp-0.7.0/src/bindings/python/httpp/progress.py +34 -0
- httpp-0.7.0/src/bindings/python/httpp/server.py +900 -0
- httpp-0.7.0/src/bindings/python/httpp_cy.pyx +1562 -0
- httpp-0.7.0/src/core/async_http.cpp +654 -0
- httpp-0.7.0/src/core/async_server.cpp +654 -0
- httpp-0.7.0/src/core/client.cpp +799 -0
- httpp-0.7.0/src/core/download.cpp +608 -0
- httpp-0.7.0/src/core/internal/async_http.hpp +71 -0
- httpp-0.7.0/src/core/internal/async_server.hpp +95 -0
- httpp-0.7.0/src/core/internal/blocking_pool.hpp +73 -0
- httpp-0.7.0/src/core/internal/log.hpp +45 -0
- httpp-0.7.0/src/core/internal/tls_session.hpp +48 -0
- httpp-0.7.0/src/core/internal/worker_pool.hpp +107 -0
- httpp-0.7.0/src/core/log.cpp +107 -0
- httpp-0.7.0/src/core/mbedtls_alt/threading_alt.h +22 -0
- httpp-0.7.0/src/core/mbedtls_threading.cpp +49 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/core/progress.cpp +6 -1
- httpp-0.7.0/src/core/server.cpp +853 -0
- httpp-0.7.0/src/core/sha256.cpp +110 -0
- httpp-0.7.0/src/core/swagger_ui.cpp +97 -0
- httpp-0.7.0/src/core/tls_session.cpp +210 -0
- httpp-0.7.0/src/core/url.cpp +94 -0
- httpp-0.7.0/src/llhttp/LICENSE +22 -0
- httpp-0.7.0/src/llhttp/VENDORED.md +16 -0
- httpp-0.7.0/src/llhttp/include/llhttp.h +925 -0
- httpp-0.7.0/src/llhttp/src/api.c +517 -0
- httpp-0.7.0/src/llhttp/src/http.c +170 -0
- httpp-0.7.0/src/llhttp/src/llhttp.c +10279 -0
- httpp-0.7.0/src/third_party/README.md +68 -0
- httpp-0.7.0/src/third_party/aixlog/LICENSE +21 -0
- httpp-0.7.0/src/third_party/aixlog/aixlog.hpp +1254 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/third_party/cpp-httplib/httplib.h +0 -18
- httpp-0.7.0/src/third_party/swagger-ui/LICENSE +202 -0
- httpp-0.7.0/src/third_party/swagger-ui/NOTICE +2 -0
- httpp-0.7.0/src/third_party/swagger-ui/VENDORED.md +10 -0
- httpp-0.7.0/src/third_party/swagger-ui/swagger-api-icon.svg +1 -0
- httpp-0.7.0/src/third_party/swagger-ui/swagger-ui-bundle.js +2 -0
- httpp-0.7.0/src/third_party/swagger-ui/swagger-ui-bundle.js.LICENSE.txt +131 -0
- httpp-0.7.0/src/third_party/swagger-ui/swagger-ui.css +3 -0
- httpp-0.7.0/tests/cpp/CMakeLists.txt +55 -0
- httpp-0.7.0/tests/cpp/local_server.hpp +30 -0
- httpp-0.7.0/tests/cpp/test_async_http.cpp +317 -0
- httpp-0.7.0/tests/cpp/test_async_https.cpp +262 -0
- httpp-0.7.0/tests/cpp/test_async_pool_proxy.cpp +425 -0
- httpp-0.7.0/tests/cpp/test_async_server.cpp +518 -0
- httpp-0.7.0/tests/cpp/test_certs.hpp +42 -0
- httpp-0.7.0/tests/cpp/test_client_async_engine.cpp +358 -0
- httpp-0.7.0/tests/cpp/test_client_session.cpp +211 -0
- httpp-0.7.0/tests/cpp/test_download.cpp +434 -0
- httpp-0.7.0/tests/cpp/test_log.cpp +133 -0
- httpp-0.7.0/tests/cpp/test_server.cpp +463 -0
- httpp-0.7.0/tests/cpp/test_server_features.cpp +234 -0
- httpp-0.7.0/tests/cpp/test_server_io_routes.cpp +316 -0
- httpp-0.7.0/tests/cpp/test_server_routing.cpp +225 -0
- httpp-0.7.0/tests/cpp/test_sha256.cpp +61 -0
- httpp-0.7.0/tests/cpp/test_swagger_ui.cpp +46 -0
- httpp-0.7.0/tests/cpp/test_swagger_ui_route.cpp +62 -0
- httpp-0.7.0/tests/cpp/tls_test_server.hpp +157 -0
- httpp-0.7.0/tests/python/test_async_engine.py +210 -0
- httpp-0.7.0/tests/python/test_client.py +305 -0
- httpp-0.7.0/tests/python/test_download_progress_url.py +302 -0
- httpp-0.7.0/tests/python/test_embed_file.py +119 -0
- httpp-0.7.0/tests/python/test_examples.py +37 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/python/test_httpp_basic.py +24 -0
- httpp-0.7.0/tests/python/test_httpp_routes.py +452 -0
- httpp-0.7.0/tests/python/test_log.py +100 -0
- httpp-0.7.0/tests/python/test_models_vs_pydantic.py +191 -0
- httpp-0.7.0/tests/python/test_openapi.py +300 -0
- httpp-0.7.0/tests/python/test_params_depends.py +387 -0
- httpp-0.7.0/tests/python/test_run.py +253 -0
- httpp-0.7.0/tests/python/test_server_features.py +887 -0
- httpp-0.7.0/tests/python/test_server_raw_request.py +225 -0
- httpp-0.7.0/tests/python/test_validate_vs_pydantic.py +134 -0
- httpp-0.7.0/tools/fastapi_probes/probe_fastapi_deps_responses.py +62 -0
- httpp-0.7.0/tools/fastapi_probes/probe_fastapi_params.py +68 -0
- httpp-0.7.0/tools/fastapi_probes/probe_pydantic_types.py +49 -0
- httpp-0.6.0/.github/workflows/wheels.yml +0 -72
- httpp-0.6.0/PKG-INFO +0 -186
- httpp-0.6.0/README.md +0 -161
- httpp-0.6.0/include/httpp/client.hpp +0 -124
- httpp-0.6.0/include/httpp/download.hpp +0 -84
- httpp-0.6.0/include/httpp/server.hpp +0 -50
- httpp-0.6.0/src/bindings/python/httpp_cy.pyx +0 -270
- httpp-0.6.0/src/core/client.cpp +0 -207
- httpp-0.6.0/src/core/download.cpp +0 -311
- httpp-0.6.0/src/core/server.cpp +0 -60
- httpp-0.6.0/src/core/url.cpp +0 -45
- httpp-0.6.0/src/third_party/README.md +0 -24
- httpp-0.6.0/tests/cpp/CMakeLists.txt +0 -27
- httpp-0.6.0/tests/cpp/test_download.cpp +0 -120
- httpp-0.6.0/tests/cpp/test_server.cpp +0 -74
- {httpp-0.6.0 → httpp-0.7.0}/.github/workflows/release_template.md +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/.gitignore +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/LICENSE.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/cmake/DynamicVersion.cmake +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/cmake/FindCython.cmake +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/cmake/Optimize.cmake +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/cmake/Startup.cmake +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/cmake/UseCython.cmake +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/cmake/httppConfig.cmake.in +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/docs/index.rst +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/examples/find_httpp_via_python/CMakeLists.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/examples/find_httpp_via_python/main.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/include/httpp/curl.hpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/include/httpp/curl_compat.h +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/include/httpp/export.hpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/requirements-dev.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/core/curl.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/core/curl_compat.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/core/internal/httplib_common.hpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/src/third_party/indicators/indicators.hpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/CMakeLists.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cmake/CMakeLists.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cmake/consumer_project/CMakeLists.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cmake/consumer_project/main.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cmake/run_consumer_test.cmake +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cpp/test_client.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cpp/test_client_request.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cpp/test_curl.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cpp/test_curl_compat.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cpp/test_progress.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/cpp/test_url.cpp +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/python/CMakeLists.txt +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/utest/utest.h +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/tests/utest/utest_main.cxx +0 -0
- {httpp-0.6.0 → httpp-0.7.0}/version.py +0 -0
|
@@ -79,7 +79,7 @@ jobs:
|
|
|
79
79
|
cmake -B build \
|
|
80
80
|
-DHTTPP_BUILD_TESTS=ON \
|
|
81
81
|
-DHTTPP_BUILD_PYTHON=ON \
|
|
82
|
-
-DCMAKE_CXX_FLAGS="--coverage -O0 -g" \
|
|
82
|
+
-DCMAKE_CXX_FLAGS="--coverage -fprofile-update=atomic -O0 -g" \
|
|
83
83
|
-DCMAKE_EXE_LINKER_FLAGS="--coverage"
|
|
84
84
|
|
|
85
85
|
- name: Build and run C++ tests
|
|
@@ -67,8 +67,15 @@ jobs:
|
|
|
67
67
|
path: dist
|
|
68
68
|
merge-multiple: true
|
|
69
69
|
|
|
70
|
+
# Safety net: the publish steps need only flat *.whl / *.tar.gz files in dist/.
|
|
71
|
+
- name: Check dist layout
|
|
72
|
+
run: |
|
|
73
|
+
if find dist -mindepth 1 -type d | grep -q .; then
|
|
74
|
+
echo "::error::unexpected sub-directories in dist/"; find dist; exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
70
77
|
- name: List dist directory
|
|
71
|
-
run:
|
|
78
|
+
run: ls -lh dist
|
|
72
79
|
|
|
73
80
|
- name: create release body
|
|
74
81
|
uses: softprops/action-gh-release@v3
|
|
@@ -87,3 +94,7 @@ jobs:
|
|
|
87
94
|
with:
|
|
88
95
|
password: ${{ secrets.PYPI_PASSWORD }}
|
|
89
96
|
user: ${{ secrets.PYPI_USERNAME }}
|
|
97
|
+
packages-dir: dist
|
|
98
|
+
skip-existing: true
|
|
99
|
+
# attestations need Trusted Publishing; they are ignored when a password is used
|
|
100
|
+
attestations: false
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
name: python build wheels
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
workflow_call:
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
FORCE_COLOR: 3
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: wheels-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build_sdist:
|
|
18
|
+
name: Build SDist
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
|
+
with:
|
|
23
|
+
submodules: false
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v6
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.11"
|
|
28
|
+
cache: "pip"
|
|
29
|
+
|
|
30
|
+
- name: Build SDist
|
|
31
|
+
run: pipx run build --sdist
|
|
32
|
+
|
|
33
|
+
- name: Check metadata
|
|
34
|
+
run: pipx run twine check dist/*
|
|
35
|
+
|
|
36
|
+
- uses: actions/upload-artifact@v7
|
|
37
|
+
with:
|
|
38
|
+
name: wheelhouse-sdist
|
|
39
|
+
path: dist/*.tar.gz
|
|
40
|
+
overwrite: true
|
|
41
|
+
|
|
42
|
+
build_wheels:
|
|
43
|
+
name: Wheels on ${{ matrix.os }}
|
|
44
|
+
runs-on: ${{ matrix.os }}
|
|
45
|
+
# A hung test used to keep this job running for the default 6 hours.
|
|
46
|
+
timeout-minutes: 90
|
|
47
|
+
strategy:
|
|
48
|
+
fail-fast: true
|
|
49
|
+
matrix:
|
|
50
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
51
|
+
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@v6
|
|
54
|
+
with:
|
|
55
|
+
submodules: recursive
|
|
56
|
+
|
|
57
|
+
- name: Build wheels
|
|
58
|
+
uses: pypa/cibuildwheel@v4.3.1
|
|
59
|
+
env:
|
|
60
|
+
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
|
61
|
+
CIBW_ARCHS_MACOS: universal2
|
|
62
|
+
# Wheel layout (one build per platform for each row):
|
|
63
|
+
# cp39-abi3 every GIL-enabled Python from 3.9 up (the cp39-* selector;
|
|
64
|
+
# see py-api = "cp39" in pyproject.toml).
|
|
65
|
+
# cp313t / cp314t free-threaded 3.13 and 3.14: abi3 cannot be loaded by
|
|
66
|
+
# free-threaded builds, so each gets a version-specific
|
|
67
|
+
# wheel (this is where the no-GIL speed comes from).
|
|
68
|
+
# cp313t is built by the separate cibuildwheel 3.x step below,
|
|
69
|
+
# because cibuildwheel 4.x dropped 3.13 free-threading.
|
|
70
|
+
# cp315t free-threaded 3.15: abi3t (PEP 803, wheel.py-api =
|
|
71
|
+
# "cp315.cp315t" in scikit-build-core >= 1.0) would replace
|
|
72
|
+
# this and all later cpXXXt wheels, but it needs the PEP 793
|
|
73
|
+
# export hook, which released Cython versions do not generate
|
|
74
|
+
# yet. Until then 3.15t keeps a version-specific wheel.
|
|
75
|
+
#
|
|
76
|
+
# Free-threaded builds are enabled by default since cibuildwheel 4 (the old
|
|
77
|
+
# "cpython-freethreading" enable group no longer exists), and 3.15 is built
|
|
78
|
+
# without any prerelease flag.
|
|
79
|
+
CIBW_BUILD: "cp39-* cp314t-* cp315t-*"
|
|
80
|
+
# rpds-py (needed by jsonschema at build time) has no free-threaded wheel in its newest release; prefer an older
|
|
81
|
+
# binary over compiling the newest sdist with Rust.
|
|
82
|
+
CIBW_ENVIRONMENT: PIP_PREFER_BINARY=1
|
|
83
|
+
|
|
84
|
+
# cibuildwheel 4.x no longer supports free-threaded 3.13 (cp313t), so that one wheel
|
|
85
|
+
# comes from the 3.x series. Same wheelhouse/ folder: cibuildwheel never clears the
|
|
86
|
+
# output dir and the filenames differ by tag, so the artifact below stays flat.
|
|
87
|
+
- name: Build wheels (free-threaded 3.13)
|
|
88
|
+
uses: pypa/cibuildwheel@v3.4.1
|
|
89
|
+
env:
|
|
90
|
+
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
|
91
|
+
CIBW_ARCHS_MACOS: universal2
|
|
92
|
+
CIBW_BUILD: "cp313t-*"
|
|
93
|
+
CIBW_ENABLE: cpython-freethreading
|
|
94
|
+
CIBW_ENVIRONMENT: PIP_PREFER_BINARY=1
|
|
95
|
+
CIBW_SKIP: pp*
|
|
96
|
+
|
|
97
|
+
- uses: actions/upload-artifact@v7
|
|
98
|
+
with:
|
|
99
|
+
name: wheelhouse-${{ matrix.os }}
|
|
100
|
+
# A single path keeps the artifact flat (several paths would preserve
|
|
101
|
+
# their parent folders and end up as dist/wheelhouse/... after download).
|
|
102
|
+
path: wheelhouse/*.whl
|
|
103
|
+
overwrite: false
|
httpp-0.7.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to httpp are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project follows
|
|
5
|
+
[Semantic Versioning](https://semver.org/) (while the major version is 0, a minor release may still change an API;
|
|
6
|
+
such changes are listed under **Changed**).
|
|
7
|
+
|
|
8
|
+
## [0.7.0] - 2026-10-17
|
|
9
|
+
|
|
10
|
+
The biggest release so far: a native async client and server, a FastAPI-style Python layer with OpenAPI and Swagger
|
|
11
|
+
UI, and a download that verifies, locks and times out.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
#### Client
|
|
16
|
+
- **Async client** (`Client.run_async()`, `AsyncClient`) running on the library's own non-blocking network thread
|
|
17
|
+
(Asio) with the vendored `llhttp` parser, instead of a shared thread pool. Keep-alive connection pooling and reuse
|
|
18
|
+
across requests, redirect handling, TLS and proxy support.
|
|
19
|
+
- **Streaming responses** and **structured errors** (`httpp.errors`, with an error kind such as `timeout`) for both
|
|
20
|
+
the blocking and the async client; extra URL helpers in `httpp/url.hpp`.
|
|
21
|
+
|
|
22
|
+
#### Server (C++ and Python)
|
|
23
|
+
- **Async HTTP/HTTPS server** (`async_server`, with a worker pool). TLS (Mbed TLS) with session caching: TLS contexts
|
|
24
|
+
for identical (verify, CA file) settings are built once and reused.
|
|
25
|
+
- **Python handlers:** route handlers with path parameters, `async def` handlers, and `listen()` that blocks and
|
|
26
|
+
returns a status (0.6.1); new in this release: `ResponseHead`, `file()`, `redirect()`, `set_cookie()`,
|
|
27
|
+
`ServerRequest.cookies`, streaming responses from generators and async generators, `@app.before_request`,
|
|
28
|
+
`@app.after_request`, error and exception handlers, startup and shutdown hooks, and `handler_timeout` (60 s by
|
|
29
|
+
default) that cancels a hanging async route and answers 504. Header values are checked against injection.
|
|
30
|
+
- **OpenAPI 3.1 and Swagger UI for Python.** Schema generation with Pydantic v2 models, per-route options (`summary`,
|
|
31
|
+
`tags`, `response_model`, ...), and `Query`, `Path`, `Header`, `Cookie`, `Body` and `Depends` (dependencies with their
|
|
32
|
+
own scopes and caching) that drive both the request handling and the generated document, so the docs cannot drift
|
|
33
|
+
from the behaviour.
|
|
34
|
+
- **`httpp::mount_swagger_ui(server, docs_path = "/docs", openapi_url = "/openapi.json", title = "API")`** in C++:
|
|
35
|
+
serves the page and the Swagger UI files (`swagger-ui-bundle.js`, `swagger-ui.css`, `swagger-api-icon.svg`) from
|
|
36
|
+
bytes compiled into the library, with `Cache-Control: public, max-age=86400`. Title and URL are escaped; an invalid
|
|
37
|
+
path throws `std::invalid_argument`. The Python server's `/docs` is now served from C++, without the GIL, and there
|
|
38
|
+
is no CDN or data directory involved.
|
|
39
|
+
- **`cmake/EmbedFile.cmake`** (`embed_files()`): compiles data files into a header at configure time (`constexpr`
|
|
40
|
+
data in `.rodata`, binary-safe, 32 bytes per source line).
|
|
41
|
+
|
|
42
|
+
#### Downloads
|
|
43
|
+
- **`download::sha256(hex)` and `download::sha256_url(url = "")`**: verify the finished file against a SHA-256 digest
|
|
44
|
+
(any letter case) or against a checksum file in `sha256sum` format (default `<url>.sha256`). The checksum file is
|
|
45
|
+
fetched first, so a missing or malformed one (an HTML error page, a name for another file, several lines) fails the
|
|
46
|
+
call before any download. A mismatch deletes the file, returns `ok = false` and says what the digest actually was.
|
|
47
|
+
With `resume()`, a complete-looking but corrupt file is downloaded again once from byte 0. `download_result` has a
|
|
48
|
+
new `sha256` field.
|
|
49
|
+
- **`httpp/sha256.hpp`**: `sha256_hex()`, `sha256_file()` (chunked) and `parse_sha256_checksum()`, on top of the
|
|
50
|
+
Mbed TLS already linked for HTTPS. About 165 MB/s on the machine it was measured on (130 MB file in 0.8 s).
|
|
51
|
+
- **`download::set_timeout(seconds)`**: connect, read and write timeouts of the transfer (like
|
|
52
|
+
`Client::set_timeout`), and also how long to wait for another process that holds the same file's lock.
|
|
53
|
+
- **`download::set_max_wait(milliseconds)`**: how long a lock that is *not being updated* is waited for before its
|
|
54
|
+
owner is taken for dead (default 2 s; the wait is `min(max_wait, timeout)`).
|
|
55
|
+
- **Cross-process lock, always on.** A download takes the directory `<dest>.lock` and its owner rewrites
|
|
56
|
+
`<dest>.lock/alive` every 200 ms at most; a lock that keeps being updated is waited for as long as it lives, one that
|
|
57
|
+
stops is taken over after `min(max_wait, timeout)`. A waiter that finds the file finished and matching `sha256()` /
|
|
58
|
+
`sha256_url()` uses it without a request (`skipped = true`). If the lock directory cannot be created the download
|
|
59
|
+
goes ahead unlocked. Written with `mkdir`/`rmdir` and plain files, no `<filesystem>`.
|
|
60
|
+
|
|
61
|
+
#### Library and tooling
|
|
62
|
+
- **Logging** through the vendored AixLog, with a `set_log_*` API in C, C++ and Python.
|
|
63
|
+
- **Python wheels:** one `cp39-abi3` wheel per platform for every GIL-enabled Python from 3.9 up, plus version-specific
|
|
64
|
+
free-threaded wheels (`cp313t`, `cp314t`, `cp315t`), because free-threaded builds cannot load abi3 wheels.
|
|
65
|
+
- **Documentation:** `docs/Architecture.md` (design, goals and test strategy), `docs/agent.md`, Python micro-benchmark
|
|
66
|
+
for the validators, and README sections for streaming, files, hooks, error handling and the client's new
|
|
67
|
+
capabilities.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- **Mbed TLS 4.2.0** (release tag), with threading support switched on (`MBEDTLS_THREADING_C`, via
|
|
71
|
+
`cmake/httpp_mbedtls_config.h`): pthread on POSIX, a small `SRWLOCK`/`CONDITION_VARIABLE` layer on Windows, or on
|
|
72
|
+
every platform with `-DHTTPP_MBEDTLS_THREADING_ALT=ON`. `MBEDTLS_SELF_TEST` is off.
|
|
73
|
+
- **`HTTPP_EMBED_AS_ARRAY` is `ON` on every platform** (it was MSVC only). One code path everywhere and no
|
|
74
|
+
`-Woverlength-strings` warning for the 1.5 MB Swagger UI bundle. Cost: compiling that translation unit takes about
|
|
75
|
+
4.6 s instead of 0.9 s with GCC, once per build. `-DHTTPP_EMBED_AS_ARRAY=OFF` gives string literals again.
|
|
76
|
+
- The Swagger UI tab icon is a real SVG file served at `/docs/swagger-api-icon.svg`; the PNG favicon is gone.
|
|
77
|
+
- `<filesystem>` is not used any more (macOS 10.13 compatibility); `download.cpp` and the lock use `std::ifstream`,
|
|
78
|
+
`std::remove` and platform calls.
|
|
79
|
+
- Asio now drives both server loops and the async client (documentation and build comments updated).
|
|
80
|
+
- Build requirement: `scikit-build-core[pyproject]>=1.1`; the version is read through the standard
|
|
81
|
+
`[[tool.dynamic-metadata]]` table instead of the deprecated `tool.scikit-build.metadata`.
|
|
82
|
+
- A download creates (and removes again) `<dest>.lock` next to the destination file; the destination's directory must
|
|
83
|
+
be writable for the lock to work (otherwise the download is not locked).
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
- Concurrent TLS handshakes shared Mbed TLS's global random generator without a lock; two handshakes could draw the
|
|
87
|
+
same random bytes. Found with ThreadSanitizer, fixed by the threading support above.
|
|
88
|
+
- Async `after`/`error` hooks, or a slow client, could block the event loop and deadlock concurrent requests; the
|
|
89
|
+
Python adapter now dispatches synchronous work directly when no async hook is registered.
|
|
90
|
+
- **Windows:** a finished download did not replace an existing file (`std::rename` fails when the target exists); it is
|
|
91
|
+
now an atomic `MoveFileExA(MOVEFILE_REPLACE_EXISTING)`. `ws2_32` is linked for `send()`/`WSAGetLastError()`, and the
|
|
92
|
+
`EmbedFile` generator no longer emits a zero-size array for an empty file (MSVC `C2466`).
|
|
93
|
+
- **macOS:** link the Keychain frameworks for the C++ tests; a URL-encoding test relied on `std::isalnum` being false
|
|
94
|
+
for non-ASCII bytes.
|
|
95
|
+
- Coverage builds use atomic profile counters (the server is multi-threaded, lcov saw negative counts); free-threaded
|
|
96
|
+
wheel builds prefer binary wheels so `rpds-py` is not built from source.
|
|
97
|
+
- Tests for concurrent async downloads measure event-loop ticks and overlapping streams instead of wall-clock time.
|
|
98
|
+
- **Release pipeline:** wheels are uploaded as one flat artifact, so `dist/` holds only `.whl` and `.tar.gz` files and
|
|
99
|
+
the PyPI upload no longer fails on a `wheelhouse` sub-directory. Windows wheels are not run through `delvewheel`
|
|
100
|
+
(`httpp_core.dll` is loaded from `httpp/lib/` at import time), and the PyPI step uses `skip-existing`.
|
|
101
|
+
|
|
102
|
+
### Known limitations
|
|
103
|
+
- The async client has no timeout yet, and async hooks hold a thread while they run.
|
|
104
|
+
- `download::set_timeout`, `set_max_wait`, `sha256` and `sha256_url` are not exposed in the Python binding yet.
|
|
105
|
+
- A lock whose owner stops updating it for more than `max_wait` (heavy load, a suspended process) is taken over, and two
|
|
106
|
+
downloads can then run at once. Two waiters taking over the same dead lock in the same instant, or writing the same
|
|
107
|
+
destination, can write it together; use `sha256()` so a damaged result is caught and deleted. Keep `max_wait`
|
|
108
|
+
at 1 s or more.
|
|
109
|
+
- The Windows and macOS changes of this release were checked by CI only; the lock was not run under ThreadSanitizer.
|
|
110
|
+
- `/docs` has been looked at in Chromium only.
|
|
111
|
+
|
|
112
|
+
## [0.6.1] - 2026-10-03
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
- Python route handlers with path parameters and `async def` handlers; native async support for Python and C++
|
|
116
|
+
handlers.
|
|
117
|
+
- `listen()` blocks and returns a status in the C++ and Python bindings.
|
|
118
|
+
- Runnable standalone Python examples: server basics, routing, request and response handling, async handlers, static
|
|
119
|
+
files, error handling.
|
|
120
|
+
|
|
121
|
+
### Changed
|
|
122
|
+
- Asio 1.34.2 is a git submodule (no system dependency, better scalability).
|
|
123
|
+
- README rewritten with a clearer description and structure; the Asio documentation was consolidated.
|
|
124
|
+
|
|
125
|
+
### Fixed
|
|
126
|
+
- Windows: winsock type redefinition and missing socket headers in the tests; a Ctrl+C listener test that cannot run
|
|
127
|
+
there (Popen) is skipped and the SIGINT test was replaced with an `interrupt_main` variant.
|
|
128
|
+
|
|
129
|
+
## [0.6.0] - 2026-09-16
|
|
130
|
+
|
|
131
|
+
### Added
|
|
132
|
+
- Resumable downloads with skip-if-complete.
|
|
133
|
+
|
|
134
|
+
### Changed
|
|
135
|
+
- **Breaking:** `download_file` was renamed to `download` and folded into one fluent builder.
|
|
136
|
+
|
|
137
|
+
## [0.5.1] - 2026-09-16
|
|
138
|
+
|
|
139
|
+
### Added
|
|
140
|
+
- `max_response_size` for the client and `follow_redirects` for downloads.
|
|
141
|
+
- `abi3` wheels in CI.
|
|
142
|
+
|
|
143
|
+
### Changed
|
|
144
|
+
- `std::filesystem::remove` replaced by `std::remove` in downloads.
|
|
145
|
+
|
|
146
|
+
## [0.5.0] - 2026-09-15
|
|
147
|
+
|
|
148
|
+
### Added
|
|
149
|
+
- HTTPS support through Mbed TLS (documented in the API docs).
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
- Mbed TLS sources are generated before CMake configures; `jinja2` is a build dependency; submodules are no longer
|
|
153
|
+
fetched recursively by default.
|
|
154
|
+
- macOS: the Keychain frameworks are linked into `httpp_core`.
|
|
155
|
+
- Vendored-code warnings are suppressed and class-level exports avoided.
|
|
156
|
+
- Linux wheels are repaired with `auditwheel`.
|
|
157
|
+
|
|
158
|
+
## [0.4.0] - 2026-09-14
|
|
159
|
+
|
|
160
|
+
### Fixed
|
|
161
|
+
- Linux wheels are repaired with `auditwheel` in cibuildwheel builds.
|
|
162
|
+
|
|
163
|
+
## [0.3.0] - 2026-09-14
|
|
164
|
+
|
|
165
|
+
Release only; no functional change recorded in the history.
|
|
166
|
+
|
|
167
|
+
## [0.2.0] - 2026-09-13
|
|
168
|
+
|
|
169
|
+
### Added
|
|
170
|
+
- curl-compatible API and CLI commands.
|
|
171
|
+
|
|
172
|
+
## [0.1.1] - 2026-09-13
|
|
173
|
+
|
|
174
|
+
### Fixed
|
|
175
|
+
- Linux wheels are repaired with `auditwheel` instead of copying libraries.
|
|
176
|
+
|
|
177
|
+
## [0.1.0] - 2026-09-12
|
|
178
|
+
|
|
179
|
+
First release.
|
|
180
|
+
|
|
181
|
+
### Added
|
|
182
|
+
- C++17 core: client, server and URL parsing (`liburlparser`, IPv4, IPv6 and Public Suffix List aware).
|
|
183
|
+
- Downloads with a progress bar (vendored `indicators`).
|
|
184
|
+
- Python package with `httpp_core` as a shared library bundled in the wheel; macOS rpath handling.
|
|
185
|
+
- CMake package: consumers find httpp through `httpp.get_cmake_dir()`; `HTTPP_BUILDING_DLL` for the shared core.
|
|
186
|
+
- Single umbrella header `include/httpp.h` that carries the version, and `version.py` for tagging and releases.
|
|
187
|
+
- CMake and wheels workflows in CI.
|
|
188
|
+
|
|
189
|
+
[0.7.0]: https://github.com/MohammadRaziei/httpp/compare/v0.6.1...v0.7.0
|
|
190
|
+
[0.6.1]: https://github.com/MohammadRaziei/httpp/compare/v0.6.0...v0.6.1
|
|
191
|
+
[0.6.0]: https://github.com/MohammadRaziei/httpp/compare/v0.5.1...v0.6.0
|
|
192
|
+
[0.5.1]: https://github.com/MohammadRaziei/httpp/compare/v0.5.0...v0.5.1
|
|
193
|
+
[0.5.0]: https://github.com/MohammadRaziei/httpp/compare/v0.4.0...v0.5.0
|
|
194
|
+
[0.4.0]: https://github.com/MohammadRaziei/httpp/compare/v0.3.0...v0.4.0
|
|
195
|
+
[0.3.0]: https://github.com/MohammadRaziei/httpp/compare/v0.2.0...v0.3.0
|
|
196
|
+
[0.2.0]: https://github.com/MohammadRaziei/httpp/compare/v0.1.1...v0.2.0
|
|
197
|
+
[0.1.1]: https://github.com/MohammadRaziei/httpp/compare/v0.1.0...v0.1.1
|
|
198
|
+
[0.1.0]: https://github.com/MohammadRaziei/httpp/releases/tag/v0.1.0
|
|
@@ -34,6 +34,20 @@ set(HTTPP_SOURCE_DIR ${PROJECT_SOURCE_DIR})
|
|
|
34
34
|
# they never leak into the httpp .so/.a's public symbols.
|
|
35
35
|
file(GLOB HTTPP_CORE_SOURCES ${PROJECT_SOURCE_DIR}/src/core/*.cpp)
|
|
36
36
|
|
|
37
|
+
# Swagger UI (vendored in src/third_party/swagger-ui) is compiled into the library: at CONFIGURE time its three
|
|
38
|
+
# files become a generated header (cmake/EmbedFile.cmake), so /docs needs no data files at run time.
|
|
39
|
+
include(EmbedFile)
|
|
40
|
+
set(HTTPP_GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
|
41
|
+
set(HTTPP_SWAGGER_UI_DIR ${PROJECT_SOURCE_DIR}/src/third_party/swagger-ui)
|
|
42
|
+
embed_files(
|
|
43
|
+
OUTPUT ${HTTPP_GENERATED_DIR}/httpp_swagger_ui_data.hpp
|
|
44
|
+
NAMESPACE httpp::embedded
|
|
45
|
+
FILES
|
|
46
|
+
swagger_ui_bundle_js ${HTTPP_SWAGGER_UI_DIR}/swagger-ui-bundle.js
|
|
47
|
+
swagger_ui_css ${HTTPP_SWAGGER_UI_DIR}/swagger-ui.css
|
|
48
|
+
swagger_ui_icon_svg ${HTTPP_SWAGGER_UI_DIR}/swagger-api-icon.svg
|
|
49
|
+
)
|
|
50
|
+
|
|
37
51
|
# liburlparser (git submodule, built from source — no system package) does
|
|
38
52
|
# the real URL parsing (scheme/host/port/path, IPv4/IPv6, PSL-aware). It is
|
|
39
53
|
# linked PRIVATE into httpp_core, same as cpp-httplib: consumers of
|
|
@@ -84,8 +98,38 @@ endif()
|
|
|
84
98
|
# httpp links it in statically and never re-exports its headers/libs, so
|
|
85
99
|
# nothing from mbedtls itself belongs in the installed wheel.
|
|
86
100
|
set(DISABLE_PACKAGE_CONFIG_AND_INSTALL ON CACHE BOOL "" FORCE)
|
|
101
|
+
# Thread safety of Mbed TLS: its process-wide state (PSA random generator, key slots) is only locked when the
|
|
102
|
+
# threading layer is enabled, and httpp does TLS on many threads. See cmake/httpp_mbedtls_config.h.
|
|
103
|
+
option(HTTPP_MBEDTLS_THREADING_ALT "Use the alt threading layer (always on for Windows) instead of pthread" OFF)
|
|
104
|
+
if(HTTPP_MBEDTLS_THREADING_ALT)
|
|
105
|
+
add_compile_definitions(HTTPP_MBEDTLS_THREADING_ALT)
|
|
106
|
+
endif()
|
|
107
|
+
set(TF_PSA_CRYPTO_USER_CONFIG_FILE ${PROJECT_SOURCE_DIR}/cmake/httpp_mbedtls_config.h CACHE FILEPATH "" FORCE)
|
|
108
|
+
find_package(Threads REQUIRED)
|
|
109
|
+
set(LINK_WITH_PTHREAD ON CACHE BOOL "" FORCE)
|
|
110
|
+
# threading_alt.h (the alt layer's types) must be found by every Mbed TLS source (it builds several object libraries
|
|
111
|
+
# that do not see each other's include paths) and by everything that includes its headers: a directory-level include
|
|
112
|
+
# path, inherited by the subdirectories added below, reaches all of them.
|
|
113
|
+
if(WIN32 OR HTTPP_MBEDTLS_THREADING_ALT)
|
|
114
|
+
include_directories(${PROJECT_SOURCE_DIR}/src/core/mbedtls_alt)
|
|
115
|
+
endif()
|
|
87
116
|
add_subdirectory(${PROJECT_SOURCE_DIR}/src/third_party/mbedtls)
|
|
88
117
|
|
|
118
|
+
# llhttp (vendored release C sources, kept in src/ not third_party/: it is an interim parser for the async client and goes away with cpp-httplib, no Node needed): the HTTP/1.x parser for
|
|
119
|
+
# the async client. Own C static target so the generated code is built without
|
|
120
|
+
# httpp's -Wall -Wextra -Wpedantic; see src/llhttp/VENDORED.md.
|
|
121
|
+
enable_language(C)
|
|
122
|
+
add_library(httpp_llhttp STATIC
|
|
123
|
+
${PROJECT_SOURCE_DIR}/src/llhttp/src/llhttp.c
|
|
124
|
+
${PROJECT_SOURCE_DIR}/src/llhttp/src/api.c
|
|
125
|
+
${PROJECT_SOURCE_DIR}/src/llhttp/src/http.c)
|
|
126
|
+
target_include_directories(httpp_llhttp PUBLIC
|
|
127
|
+
${PROJECT_SOURCE_DIR}/src/llhttp/include)
|
|
128
|
+
set_target_properties(httpp_llhttp PROPERTIES
|
|
129
|
+
LINKER_LANGUAGE C POSITION_INDEPENDENT_CODE ON C_VISIBILITY_PRESET hidden)
|
|
130
|
+
target_compile_options(httpp_llhttp PRIVATE
|
|
131
|
+
$<IF:$<C_COMPILER_ID:MSVC>,/w,-w>)
|
|
132
|
+
|
|
89
133
|
add_library(httpp_core SHARED ${HTTPP_CORE_SOURCES})
|
|
90
134
|
add_library(httpp::core ALIAS httpp_core)
|
|
91
135
|
|
|
@@ -116,14 +160,16 @@ target_include_directories(httpp_core
|
|
|
116
160
|
# warnings (e.g. indicators.hpp's narrowing-conversion C4244/C4267 on MSVC)
|
|
117
161
|
# aren't ours to fix and shouldn't surface under our own -Wall/-Wextra/-W4
|
|
118
162
|
# below — without patching vendored code to silence its own warnings.
|
|
163
|
+
target_include_directories(httpp_core PRIVATE ${HTTPP_GENERATED_DIR})
|
|
119
164
|
target_include_directories(httpp_core SYSTEM PRIVATE
|
|
120
165
|
${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/cpp-httplib
|
|
166
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/aixlog
|
|
121
167
|
${CMAKE_CURRENT_SOURCE_DIR}/src/third_party
|
|
122
168
|
)
|
|
123
169
|
|
|
124
170
|
find_package(Threads REQUIRED)
|
|
125
171
|
target_link_libraries(httpp_core PUBLIC Threads::Threads)
|
|
126
|
-
target_link_libraries(httpp_core PRIVATE url::base)
|
|
172
|
+
target_link_libraries(httpp_core PRIVATE url::base httpp_llhttp)
|
|
127
173
|
|
|
128
174
|
# HTTPS support: mbedtls is linked PRIVATE and CPPHTTPLIB_MBEDTLS_SUPPORT is
|
|
129
175
|
# only ever defined in src/core/internal/httplib_common.hpp (never in a
|
|
@@ -131,6 +177,53 @@ target_link_libraries(httpp_core PRIVATE url::base)
|
|
|
131
177
|
# include/link path — see that file for the shared httplib.h include.
|
|
132
178
|
target_link_libraries(httpp_core PRIVATE mbedtls mbedx509)
|
|
133
179
|
target_compile_definitions(httpp_core PRIVATE CPPHTTPLIB_MBEDTLS_SUPPORT)
|
|
180
|
+
# Asio (standalone, header-only, vendored) runs the async engines: the server's
|
|
181
|
+
# connection loop and the non-blocking client (epoll on Linux, kqueue on macOS,
|
|
182
|
+
# IOCP on Windows). It is only ever included from src/core/async_server.cpp and
|
|
183
|
+
# src/core/async_http.cpp, never together with httplib.h.
|
|
184
|
+
# Where Asio comes from, in order:
|
|
185
|
+
# 1. -DHTTPP_ASIO_INCLUDE_DIR=<directory containing asio.hpp> (offline builds, packagers)
|
|
186
|
+
# 2. src/third_party/asio, if it holds a copy: a git submodule (<dir>/asio/include)
|
|
187
|
+
# or a plain copy (<dir>/include)
|
|
188
|
+
# 3. downloaded at configure time, pinned by version and SHA-256 (about 3 MB)
|
|
189
|
+
set(HTTPP_ASIO_VERSION 1.34.2)
|
|
190
|
+
set(HTTPP_ASIO_SHA256 f3bac015305fbb700545bd2959fbc52d75a1ec2e05f9c7f695801273ceb78cf5)
|
|
191
|
+
set(HTTPP_ASIO_INCLUDE_DIR "" CACHE PATH "Directory containing asio.hpp (empty: auto-detect, else download)")
|
|
192
|
+
if(NOT HTTPP_ASIO_INCLUDE_DIR)
|
|
193
|
+
foreach(_candidate
|
|
194
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/asio/asio/include
|
|
195
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/asio/include)
|
|
196
|
+
if(EXISTS "${_candidate}/asio.hpp")
|
|
197
|
+
set(HTTPP_ASIO_INCLUDE_DIR "${_candidate}" CACHE PATH "" FORCE)
|
|
198
|
+
break()
|
|
199
|
+
endif()
|
|
200
|
+
endforeach()
|
|
201
|
+
endif()
|
|
202
|
+
if(NOT HTTPP_ASIO_INCLUDE_DIR)
|
|
203
|
+
include(FetchContent)
|
|
204
|
+
if(POLICY CMP0135)
|
|
205
|
+
cmake_policy(SET CMP0135 NEW) # extracted files get the time of extraction
|
|
206
|
+
endif()
|
|
207
|
+
string(REPLACE "." "-" _asio_tag "asio-${HTTPP_ASIO_VERSION}")
|
|
208
|
+
FetchContent_Declare(httpp_asio
|
|
209
|
+
URL https://codeload.github.com/chriskohlhoff/asio/tar.gz/refs/tags/${_asio_tag}
|
|
210
|
+
URL_HASH SHA256=${HTTPP_ASIO_SHA256})
|
|
211
|
+
FetchContent_MakeAvailable(httpp_asio) # Asio has no CMakeLists.txt: this only downloads and extracts
|
|
212
|
+
set(HTTPP_ASIO_INCLUDE_DIR "${httpp_asio_SOURCE_DIR}/asio/include" CACHE PATH "" FORCE)
|
|
213
|
+
endif()
|
|
214
|
+
message(STATUS "Asio ${HTTPP_ASIO_VERSION}: ${HTTPP_ASIO_INCLUDE_DIR}")
|
|
215
|
+
|
|
216
|
+
target_include_directories(httpp_core SYSTEM PRIVATE ${HTTPP_ASIO_INCLUDE_DIR})
|
|
217
|
+
target_compile_definitions(httpp_core PRIVATE ASIO_STANDALONE ASIO_NO_DEPRECATED)
|
|
218
|
+
if(WIN32)
|
|
219
|
+
# Asio wants the target Windows version spelled out (Windows 10 and later).
|
|
220
|
+
target_compile_definitions(httpp_core PRIVATE _WIN32_WINNT=0x0A00)
|
|
221
|
+
target_link_libraries(httpp_core PRIVATE ws2_32 mswsock crypt32)
|
|
222
|
+
endif()
|
|
223
|
+
if(MSVC)
|
|
224
|
+
# Asio's templates produce very large object files.
|
|
225
|
+
set_source_files_properties(${PROJECT_SOURCE_DIR}/src/core/async_http.cpp ${PROJECT_SOURCE_DIR}/src/core/async_server.cpp PROPERTIES COMPILE_OPTIONS "/bigobj")
|
|
226
|
+
endif()
|
|
134
227
|
|
|
135
228
|
# macOS: cpp-httplib (src/third_party/cpp-httplib/httplib.h) reads the
|
|
136
229
|
# system trust store via the Keychain APIs (CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN),
|