cpp-httplib
- 1. 介紹
- 2. 安裝
- 3. 類與接口
- 3.1 httplib請求
- 3.2 httplib響應
- 3.3 httplib服務端
- 3.4 httplib客戶端
- 4. 使用
- 4.1 服務端
- 4.2 客戶端
1. 介紹
C++ HTTP 庫(cpp-httplib)是一個輕量級的 C++ HTTP 客戶端/服務器庫,它提供了簡單的 API 來創建 HTTP 服務器和客戶端,支持同步和異步操作。這種第三方網絡庫,可以讓我們免去搭建服務器或客戶端的時間,把更多的精力投入到具體的業務處理中,提高開發效率。以下是一些關于cpp-httplib 的主要特點:
- 輕量級:cpp-httplib 的設計目標是簡單和輕量,只有一個頭文件包含即可,不依賴于任何外部庫。
- 跨平臺:它支持多種操作系統,包括 Windows、Linux 和 macOS。
- 同步和異步操作:庫提供了同步和異步兩種操作方式,允許開發者根據需要選擇。
- 支持 HTTP/1.1:它實現了 HTTP/1.1 協議,包括持久連接和管道化。
- Multipart form-data:支持發送和接收 multipart/form-data 類型的請求,這對于
文件上傳非常有用。 - SSL/TLS 支持:通過使用 OpenSSL 或 mbedTLS 庫,cpp-httplib 支持 HTTPS
和 WSS。 - 簡單易用:API 設計簡潔,易于學習和使用。
- 性能:盡管是輕量級庫,但性能表現良好,適合多種應用場景。
- 社區活躍:cpp-httplib 有一個活躍的社區,不斷有新的功能和改進被加入。
2. 安裝
git clone https://github.com/yhirose/cpp-httplib.git
3. 類與接口
3.1 httplib請求
namespace httplib
{// 文件信息結構體struct MultipartFormData{std::string name; // 字段名稱std::string content; // 文件內容std::string filename; // 文件名稱std::string content_type; // 文件類型};using MultipartFormDataItems = std::vector<MultipartFormData>;struct Request{std::string method;//請求方法std::string path;//請求資源路徑Headers headers;//請求報頭std::string body;//請求正文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;//將key-val的字段值設定在http請求中void set_header(const char *key, const char *val);//判斷對應的文件name是否存在,主要判斷MultipartFormData里面的name是否存在bool has_file(const char *key) const;//獲取對應的文件信息MultipartFormData get_file_value(const char *key) const;};
}
3.2 httplib響應
struct Response
{std::string version;//響應版本int status = -1;//響應狀態碼std::string reason;Headers headers;//響應報頭std::string body;//響應正文std::string location; // 重定向位置//設置正文內容+正文類型void set_content(const std::string &s,const std::string &content_type);//設置頭部字段,以key val方式void set_header(const std::string &key,const std::string &val);
};
3.3 httplib服務端
class Server
{//Handler是對應請求資源路徑的回調函數using Handler = std::function<void(const Request &, Response &)>;//Handlers是一個映射表,它映射的是請求資源路徑和對應回調函數using Handlers = std::vector<std::pair<std::regex, Handler>>//對應方法設置對應請求路徑和回調函數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 &Delete(const std::string &pattern, Handler handler);//啟動服務器bool listen(const std::string &host, int port);
};
Http請求對應每個請求方法都有自己的路由選擇表。構建服務器的時候可以調用Server里面的Get(“/hello”,Hello),將請求方為GET,請求資源/hello,與函數Hello 注冊 在Handlers表中。當http請求的請求方法是GET方法,且請求資源是/hello,那么服務器則會調用Hello函數,構建相對應的http響應。
3.4 httplib客戶端
Get接口請求服務器對應請求路徑的資源,請求成功后返回一個result值,這個值就是一個response類型,信息通過返回值進行獲得。
post接口是上傳一個文件信息給服務器,重載了兩個函數,一個是通過MultipartFormData類型進行組織好文件內容,然后插入到MultipartFormDataItems數組中上傳,這種方式是可以在一個請求中上傳多個文件信息,另一個則是只針對一個文件信息上傳。
class Client
{//構造一個客戶端對象,傳入服務器Ip地址和端口explicit Client(const std::string &host, int port);//向服務器發送GET請求Result Get(const std::string &path);Result Get(const std::string &path, const Headers &headers);//向服務器發送Post請求//path是路徑//body是正文//content_type是正文的類型Result Post(const std::string &path, const std::string &body,const std::string &content_type);//以Post方法上傳文件Result Post(const char *path, const MultipartFormDataItems &items);Result Put(const std::string &path, const std::string &body,const std::string &content_type);Result Delete(const std::string &path, const std::string &body,const std::string &content_type);
};
4. 使用
4.1 服務端
#include<iostream>
#include"cpp-httplib/httplib.h"void Hi(const httplib::Request& req,httplib::Response& rsp)
{std::cout<<req.method<<std::endl;std::cout<<req.path<<std::endl;std::string res = "<html><body><h1>你好世界!</hi></body></html>";rsp.set_content(res,"text/html");}void File(const httplib::Request& req,httplib::Response& rsp)
{bool ret = req.has_file("file");if(ret == false){std::cout<<"文件不存在"<<std::endl;return;}auto file = req.get_file_value("file");std::cout<<file.name<<std::endl;std::cout<<file.filename<<std::endl;std::cout<<file.content<<std::endl;std::cout<<file.content_type<<std::endl;
}int main()
{httplib::Server server;server.Get("/Hi",Hi);server.Post("/File",File);server.listen("0.0.0.0",8080);return 0;
}
4.2 客戶端
#include<iostream>
#include"cpp-httplib/httplib.h"int main()
{httplib::Client client("127.0.0.1",8080);auto result1 = client.Get("/Hi");if(result1 && result1->status == 200){std::cout<<result1->body<<std::endl;}else{std::cerr<<"No content return"<<std::endl;}httplib::MultipartFormData data;data.name = "file";data.filename = "upload";data.content = "upload content";data.content_type = "text/plain";httplib::MultipartFormDataItems items;items.push_back(data);auto result2 = client.Post("/File",items);if(result2 && result2->status == 200){std::cout<<result2->body<<std::endl;}else{std::cerr<<"upload error"<<std::endl;}return 0;
}
all:server clientservre:server.ccg++ -o $@ $^ -std=c++17 -lpthreadclient:client.ccg++ -o $@ $^ -std=c++17 -lpthread