▷ C++第三方库 【HTTP/HTTPS】— httplib库

⌹ 365bet线上 ⏱️ 2025-07-26 07:27:33 👤 admin 👁️‍🗨️ 8900 ❤️ 294
C++第三方库 【HTTP/HTTPS】— httplib库

目录

认识httplib库

安装httplib库

httplib的使用

httplib请求类

httplib响应类

Server类

Client类

httplib库搭建简单服务器&客户端

认识httplib库

httplib库,是一个C++11单头文件的,轻量级的跨平台HTTP/HTTPS库,可以用来创建简单的HTTP服务器和客户端。其被设计成简单易用,适用于快速开发和测试,而不需要深入了解底层的HTTP协议。免去搭建服务器或客户端的时间,更快设计具体的业务处理,提高开发效率。

安装httplib库

GitHub链接

在Linux命令行输入如下命令,安装rz

sudo yum install lrzsz

再使用unzip命令解压压缩包

若没有unzip命令,执行如下命令安装

sudo yum install unzip

httplib的使用

httplib请求类

HTTP请求报文可以参看HTTP请求

httplib中封装了一个结构——Request,用来保存客户端/浏览器发送的HTTP请求的内容。当服务器获取到客户端的请求,httplib会将请求字符串解析成Request

struct Request {

//成员变量

std::string method;//请求方法

std::string path;//请求资源路径——URL

Headers headers;//头部字段

std::string body;//正文部分

std::string version;//协议版本

Params params;//查询字符串

MultipartFormDataMap files;//客户端上传文件的信息

Ranges ranges;//实现断点续传的请求区间

//提供的API

//查询头部字段key是否存在

bool has_header(const char *key) const;

//获取头部字段的value

std::string get_header_value(const char *key, size_t id = 0) const;

//设置头部字段

void set_header(const char *key, const char *val);

//查询客户端是否上传该文件

bool has_file(const char *key) const;

//获取文件信息

MultipartFormData get_file_value(const char *key) const;

};

其中有一个文件结构体和文件结构体数组

struct MultipartFormData {

std::string name;//字段名称

std::string content;//文件内容

std::string filename;//文件名

std::string content_type;//文件类型

};

//文件结构体数组

using MultipartFormDataItems = std::vector;

httplib响应类

HTTP响应报文可以参看HTTP响应

httplib响应类是Responce,需要用户手动填补,httplib返回响应时,会将Responce组织成字符串返回给客户端

struct Response {

std::string version; //协议版本号,默认时http1.1

int status = -1; //响应状态码,

std::string reason;

Headers headers; //响应报头

std::string body; //响应正文

std::string location; // 重定向位置

//两个比较重要的API

//以key-val将相应的字段设定到响应报头中

void set_header(const char *key, const char *val);

//设置正文——可以设置类型

void set_content(const std::string &s, const char *content_type);

};

Server类

Server类就是httplib中用于搭建服务器的类

class Server {

//Handler一个函数指针,它的返回值为void,参数是Request,和Response

using Handler = std::function;

//Handlers是一个映射表,将请求资源和处理函数映射在一起

using Handlers = std::vector>;

//将Get方法的请求资源与处理函数加载到Handlers表中

Server &Get(const std::string &pattern, Handler handler);

Server &Post(const std::string &pattern, Handler handler);

Server &Put(const std::string &pattern, Handler handler);

Server &Patch(const std::string &pattern, Handler handler);

Server &Delete(const std::string &pattern, Handler handler);

Server &Options(const std::string &pattern, Handler handler);

//线程池

std::function new_task_queue;

//搭建并启动http

bool listen(const char *host, int port, int socket_flags = 0);

};

首先,Handler是一个回调的函数指针。Handlers是一个映射表。std::regex是正则表达式,用于匹配请求资源,即URL中的path。Handlers将请求的资源和处理函数进行映射。当服务器收到一个请求,解析Request,获取客户端请求的资源路径,在Handlers表中找是否存在映射关系,有则调用对应的Handler回调函数处理请求,无则返回404(请求资源不存在)。

Get,Post,Put,Patch,Delete,Options都是往Handlers表中设置映射关系

请求方法,请求资源和处理函数都是强相关的,如上表:

只有http请求的请求方法是GET,且请求的资源是/Hello/a,服务器才会调用echoHelloA处理请求只要请求方法和请求资源在Handlers表中找不到映射的处理函数,http服务器就会返回404的http响应,表示请求资源不存在Get("/Hello/a", echoHelloA):将请求方法为GET,请求资源为/Hello/a,与函数echoHelloA注册到Handlers表中

线程池的工作:

当服务器接收到一个http请求,会将该http请求放入线程池,线程池的线程会调用相应的函数解析http请求,形成一个Request对象在Handlers映射表中查找有无对应请求方法和请求资源的处理函数,有则调用处理函数,并构建http响应处理函数调用完后,将Responce构建成http响应,并将构建好的http响应返回给客户端

Client类

class Client {

//构造一个客户端对象,传入服务器Ip地址和端口

Client(const std::string &host, int port);

//向服务器发送GET请求

Result Get(const char *path, const Headers &headers);

//向服务器发送Post请求

//path是路径,body是request请求路径

//content_length是正文大小

//content_type是正文的类型

Result Post(const char *path, const char *body, size_t content_length,

const char *content_type);

//以Post方法上传文件

Result Post(const char *path, const MultipartFormDataItems &items);

}

httplib库搭建简单服务器&客户端

搭建服务器:

定义server对象在Handlers表中注册相应请求方法和请求资源的处理函数listen绑定IP地址和端口号,启动服务器,监听连接和请求

#include

#include "httplib.h"

#include

int main()

{

httplib::Server server;

//设置处理函数

//GET请求方法,/hello请求资源的映射函数

server.Get("/hello", [](const httplib::Request& req, httplib::Response& resp){

resp.set_content("Hello World!", "text/plain");

resp.status = 200;

});

//GET请求方法,/number/数字请求资源的映射函数

server.Get(R"(/number/(\d+))", [](const httplib::Request& req, httplib::Response& resp){

//matches[0]是完整请求资源,后续都是捕捉的参数

auto num = req.matches[1];

resp.set_content(num, "text/plain");

resp.status = 200;

});

//POST请求方法,/upload请求资源的映射函数

server.Post("/upload", [](const httplib::Request& req, httplib::Response& resp){

auto ret = req.has_file("file");//查找客户端是否上传file文件

if(ret == false)

{

resp.set_content("没有上传file文件", "text/plain");

resp.status = 404;

return -1;

}

auto size = req.files.size();

const auto& file = req.get_file_value("file");

//获取到文件结构体——MultipartFormData

//构建Responce响应

resp.body.clear();

resp.body = file.filename;

resp.body += "\n";

resp.body += file.content;

resp.set_header("Content-Type", "text/plain");

resp.status = 200;

});

//启动服务器——绑定IP地址和端口号

server.listen("0.0.0.0", 8080);

return 0;

}

简单客户端

定义Clinet对象,绑定要连接的服务器的IP地址和端口号构建请求获取响应,处理响应

#include

#include

#include "httplib.h"

int main()

{

//连接服务器

httplib::Client client("106.55.180.125", 8080);

//构建文件结构体

httplib::MultipartFormData item;

item.name = "file";

item.filename = "Hello.txt";

item.content = "Hello World!";

item.content_type = "text/plain";

//文件结构体数组——传输多个文件

httplib::MultipartFormDataItems items;

items.push_back(item);

//发送请求

auto res = client.Post("/upload", items);

//接收并处理响应

std::cout << res->status << std::endl;

std::cout << res->body << std::endl;

}

◈ 相关文章

家用4K新选择 测康佳易彩6680智能电视(全文)
⌹ 365bet线上

▷ 家用4K新选择 测康佳易彩6680智能电视(全文)

⏱️ 07-14 👁️‍🗨️ 3688
您所访问的页面不存在
⌹ 365bet线上

▷ 您所访问的页面不存在

⏱️ 07-23 👁️‍🗨️ 2823
一帮很懂的人,做出了一个真正的“媚宅”游戏
⌹ 365bet现场滚球

▷ 一帮很懂的人,做出了一个真正的“媚宅”游戏

⏱️ 07-01 👁️‍🗨️ 2935