Skip to content

Commit 4bf6f28

Browse files
feat: add httplib (#260)
* feat: add brotli example to test suite - include tests/examples/brotli in the members list of mcpp.toml - enables testing for brotli library integration * feat: add httplib - Add httplib example project - Add httplib-brotli example project - Add httplib-no-exceptions example project - Add httplib-tls example project - Add httplib-zlib example project - Add httplib-zstd example project --------- Co-authored-by: SPeak <speakshen@163.com>
1 parent d1ff152 commit 4bf6f28

16 files changed

Lines changed: 386 additions & 0 deletions

File tree

mcpp.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ members = [
9898
"tests/examples/magic_enum",
9999
"tests/examples/mimalloc",
100100
"tests/examples/harfbuzz",
101+
"tests/examples/httplib",
102+
"tests/examples/httplib-brotli",
103+
"tests/examples/httplib-no-exceptions",
104+
"tests/examples/httplib-tls",
105+
"tests/examples/httplib-zlib",
106+
"tests/examples/httplib-zstd",
101107
"tests/examples/msdfgen",
102108
"tests/examples/gtl",
103109
"tests/examples/miniaudio",

pkgs/c/compat.httplib.lua

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
-- Form B header-only descriptor for cpp-httplib. Optional backends stay off
2+
-- unless a consumer requests the corresponding mcpp feature.
3+
package = {
4+
spec = "1",
5+
namespace = "compat",
6+
name = "httplib",
7+
description = "C++ single-header HTTP/HTTPS server and client library",
8+
licenses = {"MIT"},
9+
repo = "https://github.com/yhirose/cpp-httplib",
10+
type = "package",
11+
12+
xpm = {
13+
-- No mcpp-res credentials are available in this environment. Keep the
14+
-- GLOBAL URL as a plain string until a byte-identical CN asset exists.
15+
linux = {
16+
["0.53.1"] = {
17+
url = "https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.53.1.tar.gz",
18+
sha256 = "185af9587e270de9a3bfee234c6740f02e82265da33c7a41f97e02ee42f979d2",
19+
},
20+
},
21+
macosx = {
22+
["0.53.1"] = {
23+
url = "https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.53.1.tar.gz",
24+
sha256 = "185af9587e270de9a3bfee234c6740f02e82265da33c7a41f97e02ee42f979d2",
25+
},
26+
},
27+
windows = {
28+
["0.53.1"] = {
29+
url = "https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.53.1.tar.gz",
30+
sha256 = "185af9587e270de9a3bfee234c6740f02e82265da33c7a41f97e02ee42f979d2",
31+
},
32+
},
33+
},
34+
35+
mcpp = {
36+
language = "c++23",
37+
import_std = false,
38+
include_dirs = { "*" },
39+
generated_files = {
40+
["mcpp_generated/compat_httplib_anchor.cpp"] =
41+
"int mcpp_compat_httplib_anchor(void) { return 0; }\n",
42+
},
43+
sources = { "mcpp_generated/compat_httplib_anchor.cpp" },
44+
targets = { ["httplib"] = { kind = "lib" } },
45+
46+
-- Feature defines are interface requirements for this header-only
47+
-- package: cpp-httplib's implementation is compiled in consumer TUs.
48+
features = {
49+
["tls"] = {
50+
defines = { "CPPHTTPLIB_OPENSSL_SUPPORT" },
51+
deps = { ["compat.openssl"] = "3.5.1" },
52+
},
53+
["zlib"] = {
54+
defines = { "CPPHTTPLIB_ZLIB_SUPPORT" },
55+
deps = { ["compat.zlib"] = "1.3.2" },
56+
},
57+
["brotli"] = {
58+
defines = { "CPPHTTPLIB_BROTLI_SUPPORT" },
59+
deps = { ["compat.brotli"] = "1.2.0" },
60+
},
61+
["zstd"] = {
62+
defines = { "CPPHTTPLIB_ZSTD_SUPPORT" },
63+
deps = { ["compat.zstd"] = "1.5.7" },
64+
},
65+
["no-exceptions"] = {
66+
defines = { "CPPHTTPLIB_NO_EXCEPTIONS" },
67+
},
68+
},
69+
deps = {},
70+
71+
-- Feature entries cannot carry platform-local ldflags. These are the
72+
-- upstream target's system link requirements; unused system libraries
73+
-- and frameworks are harmless for feature-free consumers.
74+
linux = {
75+
ldflags = { "-lpthread" },
76+
},
77+
macosx = {
78+
ldflags = {
79+
"-lpthread",
80+
"-framework", "CFNetwork",
81+
"-framework", "CoreFoundation",
82+
"-framework", "Security",
83+
},
84+
},
85+
windows = {
86+
ldflags = { "-lws2_32", "-lcrypt32" },
87+
},
88+
},
89+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "httplib-brotli-tests"
3+
version = "0.1.0"
4+
5+
[dependencies.compat]
6+
httplib = { version = "0.53.1", features = ["brotli"] }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef CPPHTTPLIB_BROTLI_SUPPORT
2+
#error "compat.httplib[brotli] must define CPPHTTPLIB_BROTLI_SUPPORT in consumers"
3+
#endif
4+
5+
#define MCPP_HTTPLIB_FEATURE_NAME "brotli"
6+
#define MCPP_HTTPLIB_ENCODING "br"
7+
#include "../../../fixtures/httplib_compression_case.hpp"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "httplib-no-exceptions-tests"
3+
version = "0.1.0"
4+
5+
[dependencies.compat]
6+
httplib = { version = "0.53.1", features = ["no-exceptions"] }
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef CPPHTTPLIB_NO_EXCEPTIONS
2+
#error "compat.httplib[no-exceptions] must define CPPHTTPLIB_NO_EXCEPTIONS in consumers"
3+
#endif
4+
5+
#include <httplib.h>
6+
7+
#include <string>
8+
9+
int main() {
10+
// Without CPPHTTPLIB_NO_EXCEPTIONS this constructor throws for an invalid
11+
// scheme. The feature changes it into a normal invalid client result.
12+
httplib::Client invalid("ftp://127.0.0.1:1");
13+
if (invalid.is_valid()) return 1;
14+
15+
httplib::Headers headers;
16+
const char *prohibited = httplib::detail::get_header_value(
17+
headers, "REMOTE_ADDR", "missing", 0);
18+
return prohibited != nullptr && prohibited[0] == '\0' ? 0 : 2;
19+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "httplib-tls-tests"
3+
version = "0.1.0"
4+
5+
[dependencies.compat]
6+
httplib = { version = "0.53.1", features = ["tls"] }
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#ifndef CPPHTTPLIB_OPENSSL_SUPPORT
2+
#error "compat.httplib[tls] must define CPPHTTPLIB_OPENSSL_SUPPORT in consumers"
3+
#endif
4+
5+
#include <httplib.h>
6+
7+
#include "../../../fixtures/httplib_localhost_pem.hpp"
8+
9+
#include <atomic>
10+
#include <cstring>
11+
#include <string>
12+
#include <thread>
13+
14+
int main() {
15+
httplib::SSLServer::PemMemory pem{
16+
kHttplibCertificatePem,
17+
std::strlen(kHttplibCertificatePem),
18+
kHttplibPrivateKeyPem,
19+
std::strlen(kHttplibPrivateKeyPem),
20+
nullptr,
21+
0,
22+
nullptr,
23+
};
24+
httplib::SSLServer server(pem);
25+
if (!server.is_valid()) return 1;
26+
27+
const std::string expected = "certificate-validated HTTPS response";
28+
std::atomic<bool> handled{false};
29+
server.Get("/secure", [&](const httplib::Request &req, httplib::Response &res) {
30+
handled = req.method == "GET" && req.path == "/secure";
31+
res.set_content(expected, "text/plain");
32+
});
33+
34+
const int port = server.bind_to_any_port("127.0.0.1");
35+
if (port <= 0) return 2;
36+
std::thread server_thread([&] { server.listen_after_bind(); });
37+
38+
httplib::SSLClient client("localhost", port);
39+
client.enable_system_ca(false);
40+
client.load_ca_cert_store(kHttplibCertificatePem,
41+
std::strlen(kHttplibCertificatePem));
42+
client.set_connection_timeout(8, 0);
43+
client.set_read_timeout(8, 0);
44+
const auto result = client.Get("/secure");
45+
46+
const bool ok = result && result->status == httplib::StatusCode::OK_200 &&
47+
result->get_header_value("Content-Type") == "text/plain" &&
48+
result->body == expected && handled.load();
49+
50+
server.stop();
51+
server_thread.join();
52+
return ok ? 0 : 3;
53+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "httplib-zlib-tests"
3+
version = "0.1.0"
4+
5+
[dependencies.compat]
6+
httplib = { version = "0.53.1", features = ["zlib"] }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef CPPHTTPLIB_ZLIB_SUPPORT
2+
#error "compat.httplib[zlib] must define CPPHTTPLIB_ZLIB_SUPPORT in consumers"
3+
#endif
4+
5+
#define MCPP_HTTPLIB_FEATURE_NAME "zlib"
6+
#define MCPP_HTTPLIB_ENCODING "gzip"
7+
#include "../../../fixtures/httplib_compression_case.hpp"

0 commit comments

Comments
 (0)