zoukankan      html  css  js  c++  java
  • 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
     ", 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
    ", 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 += "================================
    ";
    
      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
    ", query.c_str());
      s += buf;
    
      s += dump_headers(req.headers);
    
      s += "--------------------------------
    ";
    
      snprintf(buf, sizeof(buf), "%d %s
    ", res.status, res.version.c_str());
      s += buf;
      s += dump_headers(res.headers);
      s += "
    ";
    
      if (!res.body.empty()) { s += res.body; }
    
      s += "
    ";
    
      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...
    ");
        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!
    ", "text/plain");
      });
    
      svr.Get("/slow", [](const Request & /*req*/, Response &res) {
        std::this_thread::sleep_for(std::chrono::seconds(2));
        res.set_content("Slow...
    ", "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-Win64include,加入openssl的导入库路径C:OpenSSL-Win64lib,并链接libcrypto.liblibssl.libopenssl.lib

    浏览器访问:


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

    简单学习,进攻参考!

  • 相关阅读:
    winform 关于Messagebox自动定时关闭
    Git常用命令
    使用消息队列异步化系统
    在Servlet(或者Filter,或者Listener)中使用spring的IOC容器
    基于Annotation与SpringAOP的缓存简单解决方案
    Ant自动构建
    Quartz定时调度
    Sybase数据库的分页功能
    oracle 日期相减
    n个List<Map>合并,Map中某属性值相等的value值相加
  • 原文地址:https://www.cnblogs.com/MakeView660/p/12777549.html
Copyright © 2011-2022 走看看