安装和使用httplib
httplib的源代码:GitHub - yhirose/cpp-httplib: A C++ header-only HTTP/HTTPS server and client library
第一种方法,安装httplib库使用git clone 把第三方库克隆到自己Linux目录里面
git clone https://github.com/yhirose/cpp-httplib.git
第二种方式,在GitHub上下载httplib库的解压包到桌面,然后从桌面将文件上传到Linux中

在使用httplib库的时候,只需要包含这个库里面的httplib.h的头文件即可使用

在使用的时候,主要使用<httplib.h>头文件里的httplib::中的Server和Client进行创建服务器和客户端。httplib安装和使用简单,可以以一个很低的时间成本去搭建一个http服务器,让更多的事件进行到处理业务上。
Request
作用:
1、客户端保存的所以http请求的信息,保存到Request结构体当中
2、服务端接收到http请求后,将信息解析到Request结构体,以供后面使用
通过下面Request结构体的成员和接口进行对这个类进行了解。

对于http的请求报文结构来看, 在结构体内和对于的保文结构能够很清楚的进行理解。
std::string method; -- 对于的请求方法,其中常见的有get、post
std::string path; -- 请求的资源路径
Headers headers; -- 头部字段
std::string body; -- 请求的正文
std::string version; -- http版本
Params params; -- 查询字符串
MultipartFormDataMap files; -- 保存客户端上传的文件信息
通过MultipartFormData 结构中包含了name,用于区分每个MultipartFormData的名字,content是文件的主要内容,filename是文件原本的名字,content_type的上传文件的类型。
Ranges ranges; -- 用于实现文件断点续传的请求文件区间
struct MultipartFormData {
std::string name;
std::string content;
std::string filename;
std::string content_type;
};
using MultipartFormDataItems = std::vector<MultipartFormData>;
bool has_header(const char *key) const; -- 查询header里面是否有某个头部字段
std::string get_header_value(const char *key, size_t id = 0) const; -- 获取头部字段的值
void set_header(const char *key, const char *val); -- 设置对应的头部字段的值为val
bool has_file(const char *key) const; -- 判断对应的文件name是否存在,主要判断MultipartFormData 里面的name是否存在
MultipartFormData get_file_value(const char *key) const; -- 获取文件信息
struct Request {
std::string method;
std::string path;
Headers headers;
std::string body;
// for server
std::string version;
Params params;
MultipartFormDataMap files;
Ranges ranges;
bool has_header(const char *key) const;
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;
};
Response
作用:将响应数据放到Response结构体中,然后通过httplib库组合成http报头响应给客户端。
响应报头结构为:
std::string version; -- 返回http协议版本
int status = -1; -- 返回响应状态码
Headers headers; -- 响应头部字段为 key : val结构
std::string body; -- 响应正文内容
std::string location; // Redirect location -- 重定向
void set_header(const char *key, const char *val); -- 设置头部字段
void set_content(const std::string &s, const char *content_type); -- 设置正文内容
struct Response {
std::string version;
int status = -1;
std::string reason;
Headers headers;
std::string body;
std::string location; // Redirect location
void set_header(const char *key, const char *val);
void set_content(const std::string &s, const char *content_type);
};
Server
在服务端主要使用到server类进行创建对应的请求方式和创建网络套接字一整套流程。
在server类中提供了对应的请求方法, 取出一个Get请求方法进行分析:
Server &Get(const std::string &pattern, Handler handler);第一个参数const std::string &pattern是请求路径,在浏览器中请求对应路径能够调用第二个参数的回调函数 Handler handler
其中using Handler = std::function<void(const Request &, Response &)>;回调函数是上面介绍的请求和响应结构体,在使用的时候可以定义一个void(const Request &, Response &)类型的函数进行传入,httplib会自动调用对应方法。
最后要建立起网络只需要调用listen(const char *host, int port, int socket_flags = 0);传入对应的ip和端口号即可创建。
class Server {
using Handler = std::function<void(const Request &, Response &)>;
using Handlers = std::vector<std::pair<std::regex, Handler>>;
std::function<TaskQueue *(void)> new_task_queue;
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);
bool listen(const char *host, int port, int socket_flags = 0);
};
使用样例:
void hi(const httplib::Request& req,httplib::Response& res)
{
res.version = "http2";
res.status = 200;
res.body = "hello world\n";
res.set_content("Hello World!", "text/plain");
}
void numbers(const httplib::Request& req,httplib::Response& res)
{
auto number = req.matches[1];
res.set_content(number,"text/plain");
}
void upload(const httplib::Request& req,httplib::Response& res)
{
size_t sz = req.files.size();
bool ret = req.has_file("file");
if(ret == false)
{
std::cout<<"不存在这个文件\n";
return;
}
auto file = req.get_file_value("file");
std::cout<<"filesize : "<<sz<<std::endl;
std::cout<<"filename : "<<file.filename<<std::endl;
std::cout<<"content : "<<file.content<<std::endl;
std::cout<<"content_type : "<<file.content_type<<std::endl;
}
int main()
{
httplib::Server svr;
svr.Get("/hi",hi);
svr.Get(R"(/numbers/(\d+))",numbers);
svr.Post("/upload",upload);
svr.listen("0.0.0.0",8888);
return 0;
}
Client
httplib提供的Client类用来搭建对应的客户端,搭建的客户端能够通过提供的请求和响应方法向server进行发送信息。
Client类提供了构造函数,通过对应的ip和端口号进行构建网络通讯,
get接口能够请求服务器对应请求路径的资源,请求成功后返回一个result值,这个值就是一个response类型,信息通过返回值进行获得
post接口是上传一个文件信息给服务器,重载了两个函数,一个是通过MultipartFormData类型进行组织好文件内容,然后插入到MultipartFormDataItems数组中上传,这种方式是可以在一个请求中上传多个文件信息,另一个则是只针对一个文件信息上传
class Client {
Client(const std::string &host, int port);
Result Get(const char *path, const Headers &headers);
Result Post(const char *path, const char *body, size_t content_length,
const char *content_type);
Result Post(const char *path, const MultipartFormDataItems &items);
}
样例代码:
int main()
{
httplib::Client clt("139.9.209.130",8888);
auto result1 = clt.Get("/hi");
std::cout<<"status : "<<result1->status<<std::endl;
std::cout<<"body : "<<result1->body<<std::endl;
auto result2 =clt.Get("/numbers/123456");
std::cout<<"status : "<<result2->status<<std::endl;
std::cout<<"body : "<<result2->body<<std::endl;
httplib::MultipartFormDataItems items;
httplib::MultipartFormData ml;
ml.name = "file";
ml.filename = "hello";
ml.content_type = "text/plain";
ml.content = "client say hello";
items.push_back(ml);
auto result3 = clt.Post("/upload",items);
std::cout<<"status : "<<result3->status<<std::endl;
std::cout<<"body : "<<result3->body<<std::endl;
return 0;
}


670

被折叠的 条评论
为什么被折叠?



