基于CppHttpLib的Httpserver

1 背景

大多数嵌入式设备由于没有屏幕输出,只能通过Web页面来配置。这里利用CPPHttpLib来实现HttpServer。

2 HttpServer

HttpServer是利用CPPHttpLib开源库实现的Http服务器CppHttpLib是基于C++11的HTTP开源库,开源协议是MIT.
CppHttpLib下载地址

2.1 HttpServer定义

2.1.1 Http头文件

cpp 复制代码
#ifndef HTTP_H
#define HTTP_H
#include "httplib.h"
namespace http = httplib;
#endif

该文件引用C++ HTTPLIB库头文件httplib.h,将命名空间httplib重命名为http,简化后续引用。

2.1.1 HttpServer头文件

cpp 复制代码
#include "http.h"

#include <string>

struct HttpServer : private http::Server
{
    HttpServer(bool is_log = false);

    bool set_root_path(std::string const& url, std::string const& dir);

    HttpServer &get(const std::string &pattern, http::Server::Handler handler);
    HttpServer &post(const std::string &pattern, http::Server::Handler handler);
    HttpServer &put(const std::string &pattern, http::Server::Handler handler);

    bool run(const char *host, int port);
private:
    std::string log(const http::Request &req, const http::Response &res);
    std::string dump_headers(const http::Headers &headers);
private:
    bool is_log_;
};

类型说明:

  • HttpServer 构造函数,参数is_log用来指示HttpServer是否打印日志,在调试时会很有用。
  • set_root_path 设置静态网页的URL和文件路径
  • get 设置get请求处理函数
  • post 设置post请求处理函数
  • put 设置put请求处理函数
  • run 运行httpserver,参数host为主机地址,port为端口。

2.2 HttpServer实现

2.2.1 构造函数

cpp 复制代码
HttpServer::HttpServer(bool is_log)
: is_log_(is_log)
{
    if(is_log_)
      set_logger([this](const http::Request &req, const http::Response &res) 
      {
        printf("%s", this->log(req, res).c_str());
      });
}

函数说明:

  • 如果需要log,则调用HttpLib库的set_logger函数设置打印log函数。

2.2.2 set_root_path

cpp 复制代码
bool HttpServer::set_root_path(std::string const& url, std::string const& dir)
{
    return set_mount_point(url, dir);
}

函数说明:

  • 调用HttpLib库的set_mount_point设置静态网页的URL和文件路径

2.2.3 get/post/put

cpp 复制代码
HttpServer &HttpServer::get(const std::string &pattern, http::Server::Handler handler)
{
    Get(pattern, handler);
    return *this;
}

HttpServer &HttpServer::post(const std::string &pattern, http::Server::Handler handler)
{
    Post(pattern, handler);
    return *this;
}
HttpServer &HttpServer::put(const std::string &pattern, http::Server::Handler handler)
{
    Put(pattern, handler);
    return *this;
}

函数说明:

  • 调用HttpLib库对象函数设置请求处理函数。
  • 函数返回HttpServer引用是为了连续设置请求函数。

2.2.4 run

cpp 复制代码
bool HttpServer::run(const char *host, int port)
{
    return listen(host, port);
}

函数说明:

  • 调用listen启动http服务,该函数是阻塞函数。如果不想要阻塞的话,可以放到线程中执行该函数。

2.2.5 log

cpp 复制代码
std::string HttpServer::log(const http::Request &req, const http::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 (!req.body.empty()) { s += req.body; }

    s += "\n";

  return s;
}

std::string HttpServer::dump_headers(const http::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;
}

函数说明:

  • log函数将Request和Response转换为文本方便后续输出。
  • dump_headers函数将Headers转换为文本。

3 实例

cpp 复制代码
#include "httpserver.h"

int main(int argc, char* argv[]) 
{
    bool isLog = true;
    HttpServer server(isLog);

    if(argc > 1)
        server.set_root_path("/", argv[1]);
    else
        server.set_root_path("/", "dist/www");
    
    server.run("0.0.0.0", 80);

    return 0;
}

说明:

  • 定义HttpServer
  • 设置主页路径
  • 启动服务

4 总结

利用CppHttpLib库实现一个HttpServer还是很简单的。

相关推荐
奶香臭豆腐2 分钟前
C++ —— 模板类具体化
开发语言·c++·学习
不想当程序猿_8 分钟前
【蓝桥杯每日一题】分糖果——DFS
c++·算法·蓝桥杯·深度优先
cdut_suye20 分钟前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
波音彬要多做44 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
捕鲸叉1 小时前
C++软件设计模式之外观(Facade)模式
c++·设计模式·外观模式
只做开心事2 小时前
C++之红黑树模拟实现
开发语言·c++
程序员老冯头3 小时前
第十五章 C++ 数组
开发语言·c++·算法
程序猿会指北4 小时前
【鸿蒙(HarmonyOS)性能优化指南】启动分析工具Launch Profiler
c++·性能优化·harmonyos·openharmony·arkui·启动优化·鸿蒙开发
无 证明8 小时前
new 分配空间;引用
数据结构·c++
别NULL12 小时前
机试题——疯长的草
数据结构·c++·算法