基于CppHttpLib的Httpserver

devtools/2024/11/13 5:32:03/

1 背景

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

HttpServer_2">2 HttpServer

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

HttpServer_5">2.1 HttpServer定义

2.1.1 Http头文件

#ifndef HTTP_H
#define HTTP_H
#include "httplib.h"
namespace http = httplib;
#endif

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

HttpServer_15">2.1.1 HttpServer头文件

#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为端口。

HttpServer_46">2.2 HttpServer实现

2.2.1 构造函数

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

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

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

bool HttpServer::run(const char *host, int port)
{return listen(host, port);
}

函数说明:

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

2.2.5 log

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 实例

#include "httpserver.h"int main(int argc, char* argv[]) 
{bool isLog = true;HttpServer server(isLog);if(argc > 1)server.set_root_path("/", argv[1]);elseserver.set_root_path("/", "dist/www");server.run("0.0.0.0", 80);return 0;
}

说明:

4 总结

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


http://www.ppmy.cn/devtools/19700.html

相关文章

Php 通过 FFmpeg 获取远程视频的时长和截图

突然发现 FFmpeg 这个软件还可以直接拉取远程视频的相关信息&#xff0c;也就是可以不通过下载视频到本地的方式&#xff0c;直接远程去获取视频时长和截图。 假设我们的视频url是&#xff1a;http://my.com/a.mp4 第一步&#xff0c;Linux 安装 FFmpeg 软件 第二步&#xf…

Linux CentOS 本地yum配置

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 我们这种老土程序员很难接受开…

2、Flink DataStreamAPI 概述(下)

代码示例 Maven 依赖 <dependencies><dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-java</artifactId><version>1.19.0</version></dependency><dependency><groupId>org…

什么是数据库事务,事物的四大特性(ACID)分别是什么?什么是脏读?幻读?不可重复读?

数据库事务及其四大特性&#xff08;ACID&#xff09;详解 在日常的开发工作中&#xff0c;我们经常会遇到需要确保数据一致性和完整性的场景&#xff0c;这时候&#xff0c;数据库事务就显得尤为重要。简单来说&#xff0c;数据库事务就是一组一起执行的数据库操作&#xff0…

C++解方程组的库

解决多元多次方程组的问题&#xff0c;你可以考虑以下几个C库&#xff1a; Eigen: Eigen库是一个高性能的C模板库&#xff0c;用于线性代数运算。它提供了强大的矩阵运算功能&#xff0c;可以用来解多元一次方程组。对于多次方程组&#xff0c;你可能需要结合Eigen和一些数值优…

【嵌入式】程序编译流程、Makefile以及链接脚本详解

记录嵌入式中程序编译流程、makefile详解 目录 0. 授权须知1.编译流程2.将编写的C代码编译为 .bin 文件流程2.1 编写 Makefile2.2 makefile文件解析 3.lds链接脚本4.修改makefile文件 0. 授权须知 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff…

知识图谱嵌入领域的重要研究:编辑基于语言模型的知识图谱嵌入

今天&#xff0c;向大家介绍一篇在知识图谱嵌入领域具有重要意义的研究论文——Editing Language Model-based Knowledge Graph Embeddings。这项工作由浙江大学和腾讯公司的研究人员联合完成&#xff0c;为我们在动态更新知识图谱嵌入方面提供了新的视角和方法。 研究背景 在…

Android Binder——APP中AIDL解析(二十)

上一篇我们最后运行了项目,并完成了跨进成通信。这里我们就来以 getTitleText() 为例分析一下调用流程。 一、调用流程 首先,我们在 bindService 成功回调 onServiceConnected 中,通过 IMyAidlInterface.Stub.asInterface() 获取 Binder 的代理对象。对应方法在 IMyAidlInt…