mirror of
https://github.com/yhirose/cpp-httplib
synced 2026-06-08 18:30:49 +00:00
Compare commits
158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3779800322 | |||
| 986a20fb7d | |||
| 8311e1105f | |||
| ba6845925d | |||
| 343a0fc073 | |||
| 54f8a4d0f3 | |||
| 9c36aae4b7 | |||
| b766025a83 | |||
| 9b5f76f833 | |||
| d647f484a4 | |||
| 8794792baa | |||
| b85768c1f3 | |||
| e6d71bd702 | |||
| 258992a160 | |||
| a7bc00e330 | |||
| 11a40584e9 | |||
| 3e86bdb4d8 | |||
| c817d65695 | |||
| 51dee793fe | |||
| 457fc4306e | |||
| 4f5b003e76 | |||
| 5421e27106 | |||
| fe07660f40 | |||
| da2f9e476e | |||
| 1a7a7ed1c3 | |||
| 413994912d | |||
| 01dcf1d0ad | |||
| 8e378779c2 | |||
| 970b52897c | |||
| 412ba04d19 | |||
| bfef4b3e9b | |||
| 7bd316f3d0 | |||
| 26208363ee | |||
| b1b4bb8850 | |||
| 9dd565b6e3 | |||
| 924f214303 | |||
| 5c1a34e766 | |||
| fa90d06dd5 | |||
| d869054318 | |||
| 0cc1ca9a8d | |||
| 3701195033 | |||
| f884a56258 | |||
| d79633ff52 | |||
| e0ebc431dc | |||
| 131bc6c674 | |||
| 10d68cff50 | |||
| 996acc5253 | |||
| 7c4799d0cf | |||
| c239087332 | |||
| 7018e9263d | |||
| 4990b4b4b7 | |||
| 5064373c23 | |||
| 6c93aea59a | |||
| 6553cdedab | |||
| a61b2427b0 | |||
| af4ece3d5f | |||
| e64379c3d7 | |||
| 5053912534 | |||
| 932b1cbc32 | |||
| de36ea7755 | |||
| 9f8db2c230 | |||
| 3f00e1b321 | |||
| 7ab9c119ef | |||
| 3f2922b3fa | |||
| 509f583dca | |||
| 2d01e71286 | |||
| e612154694 | |||
| 82fcbe3901 | |||
| dbd2465b56 | |||
| ea79494b29 | |||
| f35aff84c2 | |||
| 7b18ae6f16 | |||
| a79c56d06b | |||
| 3d6e315a4c | |||
| 4c27f9c6ef | |||
| d173a37d17 | |||
| 7fd346a2ca | |||
| c673d502b9 | |||
| c43c51362a | |||
| 3e86d93d13 | |||
| f6e4e2d0f3 | |||
| 01a52aa8bd | |||
| 8415bf0823 | |||
| 327ff263f5 | |||
| 61c418048d | |||
| 9720ef8c34 | |||
| 978a4f6345 | |||
| 80fb03628b | |||
| 2480c0342c | |||
| eb6f610a45 | |||
| cb74e4191b | |||
| dfa641ca41 | |||
| 969a9f99d5 | |||
| c099b42ba3 | |||
| b8315278cb | |||
| 485f8f2411 | |||
| 953e4f3841 | |||
| adf65cfe61 | |||
| 12c829f6d3 | |||
| 913314f1b1 | |||
| ef63f97afe | |||
| bda74db01d | |||
| 9ff3ff9446 | |||
| c75d071615 | |||
| b4989130da | |||
| 4fc0303bda | |||
| 3d9cc51851 | |||
| f69587656f | |||
| d5fc340c30 | |||
| d79a547dc9 | |||
| bd1da4346a | |||
| 4c2a608a0c | |||
| ee4eb8deaa | |||
| 7196ac8a07 | |||
| c88b09bc6b | |||
| 87fab847b8 | |||
| 4e6055f084 | |||
| 975cf0dae5 | |||
| 4854a694cd | |||
| b1f8e986bf | |||
| c5ee208775 | |||
| ddfdacfa49 | |||
| 2514ebc20f | |||
| 4f9c6540b2 | |||
| 21c9a6a1ff | |||
| 7f6d413ddd | |||
| 88277139e7 | |||
| 6cdd3493a1 | |||
| 9c91b6f4a6 | |||
| cee838e335 | |||
| d82c82db2c | |||
| ba638ff38e | |||
| da0c6579fa | |||
| 52a18c78a5 | |||
| 048edec9ed | |||
| af56b7ec0b | |||
| 6c3e8482f7 | |||
| 390f2c41f6 | |||
| aa04feebb4 | |||
| 45f3694f82 | |||
| c5c54b31e2 | |||
| 69c84c9597 | |||
| ae63b89cbf | |||
| ff038f98b7 | |||
| e00fd06355 | |||
| 521529d24d | |||
| ed0719f2bc | |||
| 6a848b1a16 | |||
| c8bcaf8a91 | |||
| 8cd0ed0509 | |||
| 177d8420a1 | |||
| 388a8c007c | |||
| bdefdce1ae | |||
| 9e4f93d87e | |||
| 0b657d28cf | |||
| c1a09daf15 | |||
| fb739dbaec | |||
| 50fce538c6 |
@@ -0,0 +1,2 @@
|
||||
/test/www*/dir/*.html text eol=lf
|
||||
/test/www*/dir/*.txt text eol=lf
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
dry-run: false
|
||||
language: c++
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
|
||||
+34
-12
@@ -8,10 +8,10 @@ jobs:
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: install brotli
|
||||
run: sudo apt-get update && sudo apt-get install -y libbrotli-dev
|
||||
- name: install libraries
|
||||
run: sudo apt-get update && sudo apt-get install -y libbrotli-dev libcurl4-openssl-dev
|
||||
- name: build and run tests
|
||||
run: cd test && make -j4
|
||||
run: cd test && make
|
||||
- name: run fuzz test target
|
||||
run: cd test && make fuzz_test
|
||||
|
||||
@@ -21,23 +21,45 @@ jobs:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: build and run tests
|
||||
run: |
|
||||
cd test && make -j2
|
||||
run: cd test && make
|
||||
- name: run fuzz test target
|
||||
run: cd test && make fuzz_test
|
||||
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: prepare git for checkout on windows
|
||||
- name: Prepare Git for Checkout on Windows
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
- name: checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: setup msbuild on windows
|
||||
- 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: make-windows
|
||||
- name: Install libraries
|
||||
run: |
|
||||
cd test
|
||||
msbuild.exe test.sln /verbosity:minimal /t:Build "/p:Configuration=Release;Platform=x64"
|
||||
x64\Release\test.exe
|
||||
vcpkg install gtest curl zlib brotli
|
||||
choco install openssl
|
||||
|
||||
- name: Configure CMake with SSL
|
||||
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON
|
||||
- name: Build with with SSL
|
||||
run: cmake --build build --config Release
|
||||
- name: Run tests with SSL
|
||||
run: ctest --output-on-failure --test-dir build -C Release
|
||||
|
||||
- name: Configure CMake without SSL
|
||||
run: cmake -B build-no-ssl -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON
|
||||
- name: Build without SSL
|
||||
run: cmake --build build-no-ssl --config Release
|
||||
- name: Run tests without SSL
|
||||
run: ctest --output-on-failure --test-dir build-no-ssl -C Release
|
||||
env:
|
||||
VCPKG_ROOT: "C:/vcpkg"
|
||||
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||
|
||||
@@ -9,6 +9,8 @@ example/benchmark
|
||||
example/redirect
|
||||
example/sse*
|
||||
example/upload
|
||||
example/one_time_request
|
||||
example/server_and_client
|
||||
example/*.pem
|
||||
test/httplib.cc
|
||||
test/httplib.h
|
||||
@@ -21,9 +23,12 @@ test/test.xcodeproj/*/xcuser*
|
||||
test/*.o
|
||||
test/*.pem
|
||||
test/*.srl
|
||||
work/
|
||||
benchmark/server*
|
||||
|
||||
*.swp
|
||||
|
||||
build/
|
||||
Debug
|
||||
Release
|
||||
*.vcxproj.user
|
||||
@@ -33,5 +38,7 @@ Release
|
||||
*.db
|
||||
ipch
|
||||
*.dSYM
|
||||
*.pyc
|
||||
.*
|
||||
!/.gitattributes
|
||||
!/.travis.yml
|
||||
|
||||
@@ -299,6 +299,8 @@ if(HTTPLIB_INSTALL)
|
||||
# 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_TEST)
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
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. -DCPPHTTPLIB_USE_POLL main.cc && strip server
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /build/server /server
|
||||
COPY docker/html/index.html /html/index.html
|
||||
EXPOSE 80
|
||||
CMD ["/server"]
|
||||
@@ -77,6 +77,9 @@ 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);
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
@@ -122,6 +125,21 @@ int main(void)
|
||||
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();
|
||||
});
|
||||
@@ -384,6 +402,18 @@ svr.Get("/chunked", [&](const Request& req, Response& res) {
|
||||
});
|
||||
```
|
||||
|
||||
### Send file content
|
||||
|
||||
```cpp
|
||||
svr.Get("/content", [&](const Request &req, Response &res) {
|
||||
res.set_file_content("./path/to/conent.html");
|
||||
});
|
||||
|
||||
svr.Get("/content", [&](const Request &req, Response &res) {
|
||||
res.set_file_content("./path/to/conent", "text/html");
|
||||
});
|
||||
```
|
||||
|
||||
### 'Expect: 100-continue' handler
|
||||
|
||||
By default, the server sends a `100 Continue` response for an `Expect: 100-continue` header.
|
||||
@@ -542,18 +572,18 @@ enum Error {
|
||||
|
||||
```c++
|
||||
httplib::Headers headers = {
|
||||
{ "Accept-Encoding", "gzip, deflate" }
|
||||
{ "Hello", "World!" }
|
||||
};
|
||||
auto res = cli.Get("/hi", headers);
|
||||
```
|
||||
or
|
||||
```c++
|
||||
auto res = cli.Get("/hi", {{"Accept-Encoding", "gzip, deflate"}});
|
||||
auto res = cli.Get("/hi", {{"Hello", "World!"}});
|
||||
```
|
||||
or
|
||||
```c++
|
||||
cli.set_default_headers({
|
||||
{ "Accept-Encoding", "gzip, deflate" }
|
||||
{ "Hello", "World!" }
|
||||
});
|
||||
auto res = cli.Get("/hi");
|
||||
```
|
||||
@@ -808,6 +838,21 @@ The server can apply compression to the following MIME type contents:
|
||||
Brotli compression is available with `CPPHTTPLIB_BROTLI_SUPPORT`. Necessary libraries should be linked.
|
||||
Please see https://github.com/google/brotli for more detail.
|
||||
|
||||
### Default `Accept-Encoding` value
|
||||
|
||||
The default `Acdcept-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", "gzip, deflate, br"}});
|
||||
```
|
||||
|
||||
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++
|
||||
@@ -819,8 +864,9 @@ res = cli.Post("/resource/foo", "...", "text/plain");
|
||||
|
||||
```c++
|
||||
cli.set_decompress(false);
|
||||
res = cli.Get("/resource/foo", {{"Accept-Encoding", "gzip, deflate, br"}});
|
||||
res = cli.Get("/resource/foo");
|
||||
res->body; // Compressed data
|
||||
|
||||
```
|
||||
|
||||
Use `poll` instead of `select`
|
||||
@@ -828,6 +874,23 @@ Use `poll` instead of `select`
|
||||
|
||||
`select` system call is used as default since it's more widely supported. If you want to let cpp-httplib use `poll` instead, you can do so with `CPPHTTPLIB_USE_POLL`.
|
||||
|
||||
Unix Domain Socket Support
|
||||
--------------------------
|
||||
|
||||
Unix Domain Socket support is available on Linux and macOS.
|
||||
|
||||
```c++
|
||||
// Server
|
||||
httplib::Server svr("./my-socket.sock");
|
||||
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. You 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.
|
||||
|
||||
|
||||
Split httplib.h into .h and .cc
|
||||
-------------------------------
|
||||
@@ -848,6 +911,35 @@ $ ./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
|
||||
...
|
||||
|
||||
> docker run --init --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 ..."
|
||||
```
|
||||
|
||||
NOTE
|
||||
----
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
CXXFLAGS = -std=c++11 -O2 -I..
|
||||
|
||||
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_FLAGS) cpp-httplib/main.cpp
|
||||
|
||||
# cpp-httplib
|
||||
bench-base: server-base
|
||||
@echo "---------------------\n cpp-httplib v0.18.0\n---------------------\n"
|
||||
@./server-base & export PID=$$!; $(BENCH); kill $${PID}
|
||||
@echo ""
|
||||
|
||||
monitor-base: server-base
|
||||
@./server-base & export PID=$$!; $(MONITOR); kill $${PID}
|
||||
|
||||
run-base : server-base
|
||||
@./server-base
|
||||
|
||||
server-base : cpp-httplib-base/main.cpp cpp-httplib-base/httplib.h
|
||||
g++ -o $@ $(CXXFLAGS) $(CPPHTTPLIB_FLAGS) cpp-httplib-base/main.cpp
|
||||
|
||||
# crow
|
||||
bench-crow: server-crow
|
||||
@echo "-------------\n Crow v1.2.0\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
|
||||
g++ -o $@ $(CXXFLAGS) crow/main.cpp
|
||||
|
||||
# misc
|
||||
build: server server-base server-crow
|
||||
|
||||
bench-all: bench-crow bench bench-base
|
||||
|
||||
issue:
|
||||
bombardier -c 10 -d 30s localhost:8080
|
||||
|
||||
clean:
|
||||
rm -rf server*
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
#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);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#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 diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
#include "crow_all.h"
|
||||
|
||||
class CustomLogger : public crow::ILogHandler {
|
||||
public:
|
||||
void log(std::string, crow::LogLevel) {}
|
||||
};
|
||||
|
||||
int main() {
|
||||
CustomLogger logger;
|
||||
crow::logger::setHandler(&logger);
|
||||
|
||||
crow::SimpleApp app;
|
||||
|
||||
CROW_ROUTE(app, "/")([]() { return "Hello world!"; });
|
||||
|
||||
app.port(8080).multithreaded().run();
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
rm -f httplib.h
|
||||
wget https://raw.githubusercontent.com/yhirose/cpp-httplib/v$1/httplib.h
|
||||
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
http:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./docker/html:/html
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to cpp-httplib!</title>
|
||||
<style>
|
||||
html { color-scheme: light dark; }
|
||||
body { width: 35em; margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to cpp-httplib!</h1>
|
||||
<p>If you see this page, the cpp-httplib web server is successfully installed and
|
||||
working. Further configuration is required.</p>
|
||||
|
||||
<p>For online documentation and support please refer to
|
||||
<a href="https://github.com/yhirose/cpp-httplib">github.com/yhirose/cpp-httplib</a>.<br/>
|
||||
|
||||
<p><em>Thank you for using cpp-httplib.</em></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// main.cc
|
||||
//
|
||||
// Copyright (c) 2024 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <format>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <httplib.h>
|
||||
|
||||
constexpr auto error_html = R"(<html>
|
||||
<head><title>{} {}</title></head>
|
||||
<body>
|
||||
<center><h1>404 Not Found</h1></center>
|
||||
<hr><center>cpp-httplib/{}</center>
|
||||
</body>
|
||||
</html>
|
||||
)";
|
||||
|
||||
void sigint_handler(int s) { exit(1); }
|
||||
|
||||
std::string time_local() {
|
||||
auto p = std::chrono::system_clock::now();
|
||||
auto t = std::chrono::system_clock::to_time_t(p);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), "%d/%b/%Y:%H:%M:%S %z");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string log(auto &req, auto &res) {
|
||||
auto remote_user = "-"; // TODO:
|
||||
auto request = std::format("{} {} {}", req.method, req.path, req.version);
|
||||
auto body_bytes_sent = res.get_header_value("Content-Length");
|
||||
auto http_referer = "-"; // TODO:
|
||||
auto http_user_agent = req.get_header_value("User-Agent", "-");
|
||||
|
||||
// NOTE: From NGINX defualt access log format
|
||||
// log_format combined '$remote_addr - $remote_user [$time_local] '
|
||||
// '"$request" $status $body_bytes_sent '
|
||||
// '"$http_referer" "$http_user_agent"';
|
||||
return std::format(R"({} - {} [{}] "{}" {} {} "{}" "{}")", req.remote_addr,
|
||||
remote_user, time_local(), request, res.status,
|
||||
body_bytes_sent, http_referer, http_user_agent);
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
auto base_dir = "./html";
|
||||
auto host = "0.0.0.0";
|
||||
auto port = 80;
|
||||
|
||||
httplib::Server svr;
|
||||
|
||||
svr.set_error_handler([](auto & /*req*/, auto &res) {
|
||||
auto body =
|
||||
std::format(error_html, res.status, httplib::status_message(res.status),
|
||||
CPPHTTPLIB_VERSION);
|
||||
|
||||
res.set_content(body, "text/html");
|
||||
});
|
||||
|
||||
svr.set_logger(
|
||||
[](auto &req, auto &res) { std::cout << log(req, res) << std::endl; });
|
||||
|
||||
svr.set_mount_point("/", base_dir);
|
||||
|
||||
std::cout << std::format("Serving HTTP on {0} port {1} ...", host, port)
|
||||
<< std::endl;
|
||||
|
||||
auto ret = svr.listen(host, port);
|
||||
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
+9
-4
@@ -1,8 +1,7 @@
|
||||
#CXX = clang++
|
||||
CXXFLAGS = -O2 -std=c++11 -I.. -Wall -Wextra -pthread
|
||||
|
||||
PREFIX = /usr/local
|
||||
#PREFIX = $(shell brew --prefix)
|
||||
PREFIX ?= $(shell brew --prefix)
|
||||
|
||||
OPENSSL_DIR = $(PREFIX)/opt/openssl@3
|
||||
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
|
||||
@@ -19,7 +18,7 @@ ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
||||
BROTLI_DIR = $(PREFIX)/opt/brotli
|
||||
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
|
||||
|
||||
all: server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark issue
|
||||
all: server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark one_time_request server_and_client
|
||||
|
||||
server : server.cc ../httplib.h Makefile
|
||||
$(CXX) -o server $(CXXFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
|
||||
@@ -51,9 +50,15 @@ ssecli : ssecli.cc ../httplib.h Makefile
|
||||
benchmark : benchmark.cc ../httplib.h Makefile
|
||||
$(CXX) -o benchmark $(CXXFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
|
||||
|
||||
one_time_request : one_time_request.cc ../httplib.h Makefile
|
||||
$(CXX) -o one_time_request $(CXXFLAGS) one_time_request.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
|
||||
|
||||
server_and_client : server_and_client.cc ../httplib.h Makefile
|
||||
$(CXX) -o server_and_client $(CXXFLAGS) server_and_client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
|
||||
|
||||
pem:
|
||||
openssl genrsa 2048 > key.pem
|
||||
openssl req -new -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
|
||||
|
||||
clean:
|
||||
rm server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark *.pem
|
||||
rm server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark one_time_request server_and_client *.pem
|
||||
|
||||
@@ -22,34 +22,34 @@
|
||||
<ProjectGuid>{6DB1FC63-B153-4279-92B7-D8A11AF285D6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>client</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include <httplib.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace httplib;
|
||||
|
||||
const char *HOST = "localhost";
|
||||
const int PORT = 1234;
|
||||
|
||||
void one_time_request_server(const char *label) {
|
||||
std::thread th;
|
||||
Server svr;
|
||||
|
||||
svr.Get("/hi", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content(std::string("Hello from ") + label, "text/plain");
|
||||
|
||||
// Stop server
|
||||
th = std::thread([&]() { svr.stop(); });
|
||||
});
|
||||
|
||||
svr.listen(HOST, PORT);
|
||||
th.join();
|
||||
|
||||
std::cout << label << " ended..." << std::endl;
|
||||
}
|
||||
|
||||
void send_request(const char *label) {
|
||||
Client cli(HOST, PORT);
|
||||
|
||||
std::cout << "Send " << label << " request" << std::endl;
|
||||
auto res = cli.Get("/hi");
|
||||
|
||||
if (res) {
|
||||
std::cout << res->body << std::endl;
|
||||
} else {
|
||||
std::cout << "Request error: " + to_string(res.error()) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
auto th1 = std::thread([&]() { one_time_request_server("Server #1"); });
|
||||
auto th2 = std::thread([&]() { one_time_request_server("Server #2"); });
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
send_request("1st");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
send_request("2nd");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
send_request("3rd");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
th1.join();
|
||||
th2.join();
|
||||
}
|
||||
@@ -18,38 +18,41 @@
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="simplesvr.cc" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{864CD288-050A-4C8B-9BEF-3048BD876C5B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>sample</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -151,9 +154,6 @@
|
||||
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="server.cc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// server_and_client.cc
|
||||
//
|
||||
// Copyright (c) 2024 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <httplib.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace httplib;
|
||||
|
||||
std::string dump_headers(const Headers &headers) {
|
||||
std::string s;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
for (auto it = headers.begin(); it != headers.end(); ++it) {
|
||||
const auto &x = *it;
|
||||
snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
|
||||
s += buf;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void logger(const Request &req, const Response &res) {
|
||||
std::string s;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
s += "================================\n";
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(),
|
||||
req.version.c_str(), req.path.c_str());
|
||||
s += buf;
|
||||
|
||||
std::string query;
|
||||
for (auto it = req.params.begin(); it != req.params.end(); ++it) {
|
||||
const auto &x = *it;
|
||||
snprintf(buf, sizeof(buf), "%c%s=%s",
|
||||
(it == req.params.begin()) ? '?' : '&', x.first.c_str(),
|
||||
x.second.c_str());
|
||||
query += buf;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s\n", query.c_str());
|
||||
s += buf;
|
||||
|
||||
s += dump_headers(req.headers);
|
||||
|
||||
s += "--------------------------------\n";
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str());
|
||||
s += buf;
|
||||
s += dump_headers(res.headers);
|
||||
s += "\n";
|
||||
|
||||
if (!res.body.empty()) { s += res.body; }
|
||||
|
||||
s += "\n";
|
||||
|
||||
std::cout << s;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// Server
|
||||
Server svr;
|
||||
svr.set_logger(logger);
|
||||
|
||||
svr.Post("/post", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("POST", "text/plain");
|
||||
});
|
||||
|
||||
auto th = std::thread([&]() { svr.listen("localhost", 8080); });
|
||||
|
||||
auto se = detail::scope_exit([&] {
|
||||
svr.stop();
|
||||
th.join();
|
||||
});
|
||||
|
||||
svr.wait_until_ready();
|
||||
|
||||
// Client
|
||||
Client cli{"localhost", 8080};
|
||||
|
||||
std::string body = R"({"hello": "world"})";
|
||||
|
||||
auto res = cli.Post("/post", body, "application/json");
|
||||
std::cout << "--------------------------------" << std::endl;
|
||||
std::cout << to_string(res.error()) << std::endl;
|
||||
}
|
||||
+4
-6
@@ -13,7 +13,7 @@ project(
|
||||
'b_lto=true',
|
||||
'warning_level=3'
|
||||
],
|
||||
meson_version: '>=0.47.0'
|
||||
meson_version: '>=0.62.0'
|
||||
)
|
||||
|
||||
# Check just in case downstream decides to edit the source
|
||||
@@ -98,20 +98,18 @@ if get_option('cpp-httplib_compile')
|
||||
)
|
||||
else
|
||||
install_headers('httplib.h')
|
||||
cpp_httplib_dep = declare_dependency(compile_args: args, dependencies: deps, include_directories: include_directories('.'))
|
||||
cpp_httplib_dep = declare_dependency(compile_args: args, dependencies: deps, include_directories: '.')
|
||||
|
||||
import('pkgconfig').generate(
|
||||
name: 'cpp-httplib',
|
||||
description: 'A C++ HTTP/HTTPS server and client library',
|
||||
install_dir: join_paths(get_option('datadir'), 'pkgconfig'),
|
||||
install_dir: get_option('datadir')/'pkgconfig',
|
||||
url: 'https://github.com/yhirose/cpp-httplib',
|
||||
version: version
|
||||
)
|
||||
endif
|
||||
|
||||
if meson.version().version_compare('>=0.54.0')
|
||||
meson.override_dependency('cpp-httplib', cpp_httplib_dep)
|
||||
endif
|
||||
meson.override_dependency('cpp-httplib', cpp_httplib_dep)
|
||||
|
||||
if get_option('cpp-httplib_test')
|
||||
subdir('test')
|
||||
|
||||
+10
-3
@@ -24,9 +24,11 @@ else()
|
||||
FetchContent_MakeAvailable(gtest)
|
||||
endif()
|
||||
|
||||
find_package(CURL REQUIRED)
|
||||
|
||||
add_executable(httplib-test test.cc)
|
||||
target_compile_options(httplib-test PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8;/bigobj>")
|
||||
target_link_libraries(httplib-test PRIVATE httplib GTest::gtest_main)
|
||||
target_link_libraries(httplib-test PRIVATE httplib GTest::gtest_main CURL::libcurl)
|
||||
gtest_discover_tests(httplib-test)
|
||||
|
||||
file(
|
||||
@@ -35,6 +37,11 @@ file(
|
||||
)
|
||||
|
||||
if(HTTPLIB_IS_USING_OPENSSL)
|
||||
if (OPENSSL_VERSION VERSION_LESS "3.2.0")
|
||||
set(OPENSSL_X509_FLAG "-x509")
|
||||
else()
|
||||
set(OPENSSL_X509_FLAG "-x509v1")
|
||||
endif()
|
||||
find_program(OPENSSL_COMMAND
|
||||
NAMES openssl
|
||||
PATHS ${OPENSSL_INCLUDE_DIR}/../bin
|
||||
@@ -54,7 +61,7 @@ if(HTTPLIB_IS_USING_OPENSSL)
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${OPENSSL_COMMAND} req -x509 -new -config ${CMAKE_CURRENT_LIST_DIR}/test.conf -key key.pem -sha256 -days 3650 -nodes -out cert2.pem -extensions SAN
|
||||
COMMAND ${OPENSSL_COMMAND} req ${OPENSSL_X509_FLAG} -new -config ${CMAKE_CURRENT_LIST_DIR}/test.conf -key key.pem -sha256 -days 3650 -nodes -out cert2.pem -extensions SAN
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
@@ -65,7 +72,7 @@ if(HTTPLIB_IS_USING_OPENSSL)
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${OPENSSL_COMMAND} req -x509 -new -batch -config ${CMAKE_CURRENT_LIST_DIR}/test.rootCA.conf -key rootCA.key.pem -days 1024
|
||||
COMMAND ${OPENSSL_COMMAND} req ${OPENSSL_X509_FLAG} -new -batch -config ${CMAKE_CURRENT_LIST_DIR}/test.rootCA.conf -key rootCA.key.pem -days 1024
|
||||
OUTPUT_FILE rootCA.cert.pem
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
|
||||
+3
-13
@@ -18,7 +18,7 @@ ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
||||
BROTLI_DIR = $(PREFIX)/opt/brotli
|
||||
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
|
||||
|
||||
TEST_ARGS = gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread
|
||||
TEST_ARGS = gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread -lcurl
|
||||
|
||||
# By default, use standalone_fuzz_target_runner.
|
||||
# This runner does no fuzzing, but simply executes the inputs
|
||||
@@ -63,18 +63,8 @@ httplib.cc : ../httplib.h
|
||||
python3 ../split.py -o .
|
||||
|
||||
cert.pem:
|
||||
openssl genrsa 2048 > key.pem
|
||||
openssl req -new -batch -config test.conf -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
|
||||
openssl req -x509 -config test.conf -key key.pem -sha256 -days 3650 -nodes -out cert2.pem -extensions SAN
|
||||
openssl genrsa 2048 > rootCA.key.pem
|
||||
openssl req -x509 -new -batch -config test.rootCA.conf -key rootCA.key.pem -days 1024 > rootCA.cert.pem
|
||||
openssl genrsa 2048 > client.key.pem
|
||||
openssl req -new -batch -config test.conf -key client.key.pem | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client.cert.pem
|
||||
openssl genrsa -passout pass:test123! 2048 > key_encrypted.pem
|
||||
openssl req -new -batch -config test.conf -key key_encrypted.pem | openssl x509 -days 3650 -req -signkey key_encrypted.pem > cert_encrypted.pem
|
||||
openssl genrsa -aes256 -passout pass:test012! 2048 > client_encrypted.key.pem
|
||||
openssl req -new -batch -config test.conf -key client_encrypted.key.pem -passin pass:test012! | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client_encrypted.cert.pem
|
||||
#c_rehash .
|
||||
./gen-certs.sh
|
||||
|
||||
clean:
|
||||
rm -f test test_split test_proxy server_fuzzer *.pem *.0 *.o *.1 *.srl httplib.h httplib.cc
|
||||
|
||||
|
||||
@@ -50,8 +50,12 @@ class FuzzableServer : public httplib::Server {
|
||||
public:
|
||||
void ProcessFuzzedRequest(FuzzedStream &stream) {
|
||||
bool connection_close = false;
|
||||
process_request(stream, /*last_connection=*/false, connection_close,
|
||||
nullptr);
|
||||
process_request(stream,
|
||||
/*remote_addr=*/"",
|
||||
/*remote_port =*/0,
|
||||
/*local_addr=*/"",
|
||||
/*local_port =*/0,
|
||||
/*last_connection=*/false, connection_close, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
if [[ $(openssl version) =~ 3\.[2-9]\.[0-9]+ ]]; then
|
||||
OPENSSL_X509_FLAG='-x509v1'
|
||||
else
|
||||
OPENSSL_X509_FLAG='-x509'
|
||||
fi
|
||||
|
||||
openssl genrsa 2048 > key.pem
|
||||
openssl req -new -batch -config test.conf -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
|
||||
openssl req -x509 -config test.conf -key key.pem -sha256 -days 3650 -nodes -out cert2.pem -extensions SAN
|
||||
openssl genrsa 2048 > rootCA.key.pem
|
||||
openssl req $OPENSSL_X509_FLAG -new -batch -config test.rootCA.conf -key rootCA.key.pem -days 1024 > rootCA.cert.pem
|
||||
openssl genrsa 2048 > client.key.pem
|
||||
openssl req -new -batch -config test.conf -key client.key.pem | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client.cert.pem
|
||||
openssl genrsa -passout pass:test123! 2048 > key_encrypted.pem
|
||||
openssl req -new -batch -config test.conf -key key_encrypted.pem | openssl x509 -days 3650 -req -signkey key_encrypted.pem > cert_encrypted.pem
|
||||
openssl genrsa -aes256 -passout pass:test012! 2048 > client_encrypted.key.pem
|
||||
openssl req -new -batch -config test.conf -key client_encrypted.key.pem -passin pass:test012! | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client_encrypted.cert.pem
|
||||
+10
-7
@@ -3,8 +3,10 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
gtest_dep = dependency('gtest', main: true)
|
||||
libcurl_dep = dependency('libcurl')
|
||||
openssl = find_program('openssl')
|
||||
test_conf = files('test.conf')
|
||||
req_x509_flag = openssl.version().version_compare('>=3.2.0') ? '-x509v1' : '-x509'
|
||||
|
||||
key_pem = custom_target(
|
||||
'key_pem',
|
||||
@@ -30,7 +32,7 @@ cert2_pem = custom_target(
|
||||
'cert2_pem',
|
||||
input: key_pem,
|
||||
output: 'cert2.pem',
|
||||
command: [openssl, 'req', '-x509', '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN']
|
||||
command: [openssl, 'req', req_x509_flag, '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN']
|
||||
)
|
||||
|
||||
key_encrypted_pem = custom_target(
|
||||
@@ -43,7 +45,7 @@ cert_encrypted_pem = custom_target(
|
||||
'cert_encrypted_pem',
|
||||
input: key_encrypted_pem,
|
||||
output: 'cert_encrypted.pem',
|
||||
command: [openssl, 'req', '-x509', '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN']
|
||||
command: [openssl, 'req', req_x509_flag, '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN']
|
||||
)
|
||||
|
||||
rootca_key_pem = custom_target(
|
||||
@@ -56,7 +58,7 @@ rootca_cert_pem = custom_target(
|
||||
'rootca_cert_pem',
|
||||
input: rootca_key_pem,
|
||||
output: 'rootCA.cert.pem',
|
||||
command: [openssl, 'req', '-x509', '-new', '-batch', '-config', files('test.rootCA.conf'), '-key', '@INPUT@', '-days', '1024', '-out', '@OUTPUT@']
|
||||
command: [openssl, 'req', req_x509_flag, '-new', '-batch', '-config', files('test.rootCA.conf'), '-key', '@INPUT@', '-days', '1024', '-out', '@OUTPUT@']
|
||||
)
|
||||
|
||||
client_key_pem = custom_target(
|
||||
@@ -102,9 +104,9 @@ client_encrypted_cert_pem = custom_target(
|
||||
# Copy test files to the build directory
|
||||
configure_file(input: 'ca-bundle.crt', output: 'ca-bundle.crt', copy: true)
|
||||
configure_file(input: 'image.jpg', output: 'image.jpg', copy: true)
|
||||
subdir(join_paths('www', 'dir'))
|
||||
subdir(join_paths('www2', 'dir'))
|
||||
subdir(join_paths('www3', 'dir'))
|
||||
subdir('www')
|
||||
subdir('www2'/'dir')
|
||||
subdir('www3'/'dir')
|
||||
|
||||
# GoogleTest 1.13.0 requires C++14
|
||||
test_options = []
|
||||
@@ -119,7 +121,8 @@ test(
|
||||
'test.cc',
|
||||
dependencies: [
|
||||
cpp_httplib_dep,
|
||||
gtest_dep
|
||||
gtest_dep,
|
||||
libcurl_dep
|
||||
],
|
||||
override_options: test_options
|
||||
),
|
||||
|
||||
+954
-258
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -28,26 +28,26 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -177,4 +177,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -0,0 +1 @@
|
||||
file
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-FileCopyrightText: 2024 Andrea Pappacoda
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
configure_file(input: 'empty_file', output: 'empty_file', copy: true)
|
||||
configure_file(input: 'file', output: 'file', copy: true)
|
||||
subdir('dir')
|
||||
@@ -0,0 +1 @@
|
||||
日本語コンテンツ
|
||||
Reference in New Issue
Block a user