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服务器

PEMCRT文件:
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.liblibssl.libopenssl.lib

浏览器访问:


由于自己测试,所以没有CA证书,而构造一个自签名的证书。
CA签名的证书兼具身份证明和加密双重功能,而由于自证身份不可信,自签名证书就只有加密功能,用于无需身份证明的场合。
所以
cli.enable_server_certificate_verification(true);这句调用可以注释掉,不要服务端身份证明,只数据加密即可。

简单学习,进攻参考!

posted on   我来乔23  阅读(25573)  评论(1编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示