C++ Http/Https服务器和客户端库cpp-httplib
A C++ header-only HTTP/HTTPS server and client library
https://github.com/yhirose/cpp-httplib
Windows下Qt Http Server例子
pro文件 SOURCES += main.cpp HEADERS += httplib.h LIBS += -lWs2_32
main.cpp
#include <httplib.h>
using namespace httplib;
void wuhan(const Request &req, Response &res)
{
printf("httplib server recv a req: %s\n ", req.path.c_str() );
res.set_content("<html> \
<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"> \
<h1> 武汉, 加油!</h1></html>",
"text/html");
res.status = 200;
}
int main(void)
{
using namespace httplib;
Server svr;
svr.set_base_dir("./");
/// Get
svr.Get("/wuhan", wuhan);
svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain");
});
svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
});
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");
});
svr.Get("/stop", [&](const Request& req, Response& res) {
svr.stop();
});
/// listen
svr.listen("localhost", 1234);
}浏览器输入:localhost:1234
默认打开当前目录下的index.html页面。


VS Https Server例子
首先需要下载安装OpenSSL,请自行百度
openssl 生成公钥、密钥及.pem文件
使用openssl 生成免费证书
使用openssl生成https证书
用Node.js创建自签名的HTTPS服务器
PEM转CRT文件:
openssl x509 -outform der -in your-cert.pem -out your-cert.crt

https服务端:
#include <chrono>
#include <cstdio>
#include <httplib.h>
#define SERVER_CERT_FILE "./cert.pem"
#define SERVER_PRIVATE_KEY_FILE "./key.pem"
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;
}
std::string log(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";
return s;
}
int main(void) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
#else
Server svr;
#endif
if (!svr.is_valid()) {
printf("server has an error...\n");
return -1;
}
svr.Get("/", [=](const Request & /*req*/, Response &res) {
res.set_redirect("/hi");
});
svr.Get("/hi", [](const Request & /*req*/, Response &res) {
res.set_content("Hello World!\n", "text/plain");
});
svr.Get("/slow", [](const Request & /*req*/, Response &res) {
std::this_thread::sleep_for(std::chrono::seconds(2));
res.set_content("Slow...\n", "text/plain");
});
svr.Get("/dump", [](const Request &req, Response &res) {
res.set_content(dump_headers(req.headers), "text/plain");
});
svr.Get("/stop",
[&](const Request & /*req*/, Response & /*res*/) { svr.stop(); });
svr.set_error_handler([](const Request & /*req*/, Response &res) {
const char *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");
});
svr.set_logger([](const Request &req, const Response &res) {
printf("%s", log(req, res).c_str());
});
svr.listen("localhost", 8080);
return 0;
}Https客户端:
#include <httplib.h>
#include <iostream>
//#define CA_CERT_FILE "./ca-bundle.crt"
#define CA_CERT_FILE "./cacert.crt"
using namespace std;
int main(void) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
httplib::SSLClient cli("localhost", 8080);
// httplib::SSLClient cli("google.com");
// httplib::SSLClient cli("www.youtube.com");
cli.set_ca_cert_path(CA_CERT_FILE);
cli.enable_server_certificate_verification(true);
#else
httplib::Client cli("localhost", 8080);
#endif
auto res = cli.Get("/hi");
if (res) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
} else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto result = cli.get_openssl_verify_result();
if (result) {
cout << "verify error: " << X509_verify_cert_error_string(result) << endl;
}
#endif
}
return 0;
}关于使用SSL的工程配置说明:
1、通过宏开关CPPHTTPLIB_OPENSSL_SUPPORT控制是否使用Https
2、若使用Https,加入openssl包含路径:C:\OpenSSL-Win64\include,加入openssl的导入库路径C:\OpenSSL-Win64\lib,并链接libcrypto.lib、libssl.lib、openssl.lib。
浏览器访问:

简单学习,进攻参考!
相关推荐
zhangwentaohh 2020-09-16
leodengzx 2020-06-28
服务器端攻城师 2020-06-26
xcznb 2020-06-26
sapliang 2020-06-12
xasdfg 2020-06-01
bruce 2020-05-17
cuiweisaidelike 2020-05-11
songjie 2020-02-14
仁鱼 2020-02-12
furongwei 2020-05-10
xcznb 2020-04-16
服务器端攻城师 2020-02-17
hygbuaa 2020-02-13
SoarFly00 2020-02-11
vanturman 2020-02-10