基于CppHttpLib的Httpserver

embedded/2024/11/28 2:31:51/

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/embedded/5269.html

相关文章

【6】mysql查询性能优化-关联子查询

【README】 0. 先说结论&#xff1a;一般用inner join来改写in和exist&#xff0c;用left join来改写not in&#xff0c;not exist&#xff1b;&#xff08;本文会比较内连接&#xff0c;包含in子句的子查询&#xff0c;exist的性能 &#xff09; 1. 本文总结自高性能mysql 6…

第3章 数据

第3章 数据 学习笔记书后练习问题3问题7问题10问题11问题21 学习笔记 value value - 0; 通常用于将字符转换为其对应的整数值enum Jar_Type { CUP, PINT, QUART, HALF_GALLON, GALLON }; 这些符号名的实际值都是整型值&#xff0c;例如&#xff0c;CUP 是0&#xff0c;PINT …

戒烟生活记录

今天是2024年4月15日&#xff0c;从大前天也就是12号下班后&#xff0c;吃的有一点饱&#xff0c;就感觉身体及其难受&#xff0c;气短呼吸不上&#xff0c;我查了后可能是心脏的问题&#xff0c;并且晚上睡觉有一种呼吸不上&#xff0c;憋气的感觉&#xff0c;然后我就又开始决…

【学习】软件压力测试对软件产品的作用

在信息化高速发展的今天&#xff0c;软件产品已经成为各行各业不可或缺的一部分。然而&#xff0c;随着软件功能的日益复杂和用户需求的不断增长&#xff0c;软件产品的稳定性和可靠性问题也愈发凸显。在这样的背景下&#xff0c;软件压力测试作为软件质量保障的重要手段之一&a…

第八章 透明效果

在渲染模型中控制透明通道。透明度为1,完全不透明;透明度为0,完全不会显示。 两种方法: (1)透明度测试 (2)透明度混合 深度缓冲(z-buffer)用于解决可见性问题。可以决定哪个物体的哪些部分被渲染到前面,哪些部分会被其他物体遮掩。根据深度缓存中的值来判断该片…

Linux的学习之路:9、冯诺依曼与进程(1)

摘要 本章主要是说一下冯诺依曼体系结构和进程的一部分东西。 目录 摘要 一、冯诺依曼体系结构 二、操作系统的概念 三、设计OS的目的 四、管理 五、进程的基本概念 六、PCB 七、在Linux环境下查看进程 八、使用代码创建进程 九、思维导图 一、冯诺依曼体系结构 如…

4.19作业 驱动开发

一、编程要求 在内[[核中不支持浮点类型打印将si7006硬件数据读取到内核空间&#xff0c;拷贝到用户空间在i2c子系统驱动中&#xff0c;需要编写读取温湿度传感器函数在probe函数中 注册字符设备驱动(分步注册)自动创建设备节点通过ioctl函数判断应用层发送命令码&#xff0c;…

嵌入式linux中利用QT控制蜂鸣器方法

大家好,今天给大家分享一下,如何控制开发板上的蜂鸣器。 第一:开发板原理图 从原理图中可以得出,当引脚输出低电平的时候,对应的蜂鸣器发出响声。 第二:QT代码详细实现 设置一个按钮,点击即可控制BEEP状态发生反转。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#in…