第三方库httplib的使用

安装和使用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;
}

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值