365bet扑克客户端-beat365进不去-365手机app

httplib库的使用(支持http/https)(一)

httplib库的使用(支持http/https)(一)

httplib库的使用,支持http/https

httplib库简介1. 文件目录2. client端2.1 快速搭建一个client端2.2 HTTPS2.3 下载文件2.4 GET大数据2.5 POST大数据2.6 上传文件

3. server端的简单使用4.其他资料

httplib库简介

httplib库是一个以C++11特性编写的库,所以编译器也需要能支持C++11的。库在使用时只需包含一个头文件即可,非常方便。

下载地址

注意:此库为线程阻塞,使用时还请注意。

1. 文件目录

下载后的包解压后有如下文件 其中httplib.h为库的头文件,使用时只需要将此头文件包含在你的代码中即可。

example:此文件夹中有作者分享的一些代码示例,使用时可参考。

split.py:此文件为python执行文件,如果你还是想用.h和.cpp的方式将库加入到你的工程中,可以运行此文件。执行成功后会在同目录下生成一个out文件夹,里面便包含了分离的.cc和.h文件。

2. client端

2.1 快速搭建一个client端

使用时需先引入命名空间using namespace httplib,当然也可以在调用相关类时直接加上httplib::域。

如下直接建立一个http的client端,连接到本地 1234端口,获取链接 /hi下的数据,数据的主体都在返回的res->body中。

#include

#include

int main(void)

{

httplib::Client cli("localhost", 1234);

if (auto res = cli.Get("/hi")) {

if (res->status == 200) {

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

}

} else {

auto err = res.error();

...

}

}

我们一般主要引用body,这里面就是数据。头字段的话则包含在header中。

链接的错误信息返回在res.error中,error定义为

enum Error {

Success = 0,

Unknown,

Connection,

BindIPAddress,

Read,

Write,

ExceedRedirectCount,

Canceled,

SSLConnection,

SSLLoadingCerts,

SSLServerVerification,

UnsupportedMultipartBoundaryChars

};

链接成功后,通过Get的url返回的状态码在res->status中,此状态码即为HTTP状态码。

2.2 HTTPS

库默认使用的是HTTP,如果要使用HTTPS,需在程序中定义

#define CPPHTTPLIB_OPENSSL_SUPPORT

使用时可参考

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT

httplib::SSLClient client(ser_ip, ser_port); //https

client.enable_server_certificate_verification(true); //看实际情况使能

client.set_ca_cert_path("ca-bundle.crt"); //设置ca证书

#else

httplib::Client client("127.0.0.1:80"); //http

#endif

另外注意:使用HTTPS方式时,需引入ssl库,且当前库只支持ssl version 1.1.1版本。

2.3 下载文件

下载可以使用GET方法,并且可以通过以下代码获取下载文件的进度(代码将获取到的数据保存为down_file.tar格式的文件,因为传递过程中是以二进制数据传递,文件类型可以根据实际情况保存,此只是做个示例):

if(auto res = client.Get("/hi", [](uint64_t len, uint64_t total) {

printf("%lld / %lld bytes => %d%% complete\n",len, total,(int)(len*100/total));

return true; // return 'false' if you want to cancel the request.

}))

{

printf("status:%d\n",res->status);

if(res->status == 200)

{

std::ofstream out;

out.open("down_file.tar", std::ios_base::binary | std::ios::out);

printf("savefile!\n");

if(out.is_open())

{

out<body;

out.close();

printf("down load file finished!\n");

}

else

{

printf("open file error!\n");

}

}

}

else

{

printf("url connect failed! error = %d\n",(int)res.error());

}

2.4 GET大数据

如果GET数据太大,可使用如下的方式接收:

std::string body;

auto res = cli.Get("/large-data",

[&](const char *data, size_t data_length) {

body.append(data, data_length);

return true;

});

2.5 POST大数据

笔者在使用过程中将一个200M以上的文件读取后POST会报段错误,原因是读取文件后POST过程中会有拷贝过程,文件或者数据量太大时会有问题。可使用如下方法POST:

std::string body = ...;

auto res = cli.Post(

"/stream", body.size(),

[&](size_t offset, size_t length, DataSink &sink) {

sink.write(body.data() + offset, length);

return true; // return 'false' if you want to cancel the request.

},

"text/plain");

2.6 上传文件

上传文件需使用MultipartFormData,笔者在使用过程中发现,利用此方法上传文件有限制,文件太大时会报段错误(笔者测试时使用的是200多M的文件,具体临界值没有测试)。所以建议在读取文件时加上文件大小限制的判断。

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT

httplib::SSLClient client(ser_ip, ser_port);

client.enable_server_certificate_verification(true); //看实际情况使能

client.set_ca_cert_path("ca-bundle.crt");

#else

httplib::Client client("127.0.0.1:80");

#endif

std::string body = "";

//此处添加读取上传文件的代码,将读取到的数据存入body中

httplib::MultipartFormData updataData;

updataData.name = "upfile";

updataData.content = body;

updataData.filename = file_name;

updataData.content_type = content_type;

httplib::MultipartFormDataItems items;

items.push_back(updataData);

if (auto res = client.Post(file_upload_url.c_str(), items))

{

if (res->status != 200)

{

printf("error status = %d\n",res->status);

return -4;

}

else

{

return 0; //upload file success

}

}

else

{

printf("url connect failed! error = %d\n",(int)res.error());

return -5;

}

}

else

{

printf("read upload file error\n");

return -3;

}

3. server端的简单使用

服务端程序可参考如下代码,程序线程会阻塞在listen处,因此建议另开一个线程来监听。

#define SERVER_CERT_FILE "./cert.pem"

#define SERVER_PRIVATE_KEY_FILE "./key.pem"

int main(void) {

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT

SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);

#else

Server svr;

#endif

if (!svr.is_valid()) {

printf("server has an error...\n");

return -1;

}

svr.Get("/hi", [](const Request& req, Response& res) {

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

});

svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {

auto numbers = req.matches[1];

res.set_content(numbers, "text/plain");

});

svr.Get("/body-header-param", [](const Request& req, Response& res) {

if (req.has_header("Content-Length")) {

auto val = req.get_header_value("Content-Length");

}

if (req.has_param("key")) {

auto val = req.get_param_value("key");

}

res.set_content(req.body, "text/plain");

});

svr.Get("/stop", [&](const Request& req, Response& res) {

svr.stop();

});

svr.listen("localhost", 1234);

return 0;

}

4.其他资料

第二篇: httlib库的使用(文件分块传输chunked data)(二)

此外还有几篇针对httplib库写的不错的文章,一并收藏在此: C++ httplib 解读 cpp-httplib库的原理 C++ Http/Https服务器和客户端库cpp-httplib

相关推荐