hv 支持内容压缩
本文参考:HTTP协议之压缩,需要依赖zlib,摘抄Crow源码
xHttpCompress.h
#pragma once
#include <string>
#include <zlib.h>
// http://zlib.net/manual.html
namespace xHttpCompress
{
// Values used in the 'windowBits' parameter for deflateInit2.
enum algorithm
{
// 15 is the default value for deflate
DEFLATE = 15,
// windowBits can also be greater than 15 for optional gzip encoding.
// Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper.
GZIP = 15 | 16,
};
inline std::string compress_string(std::string const& str, algorithm algo)
{
std::string compressed_str;
z_stream stream{};
// Initialize with the default values
if (::deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, algo, 8, Z_DEFAULT_STRATEGY) == Z_OK)
{
char buffer[8192];
stream.avail_in = str.size();
// zlib does not take a const pointer. The data is not altered.
stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(str.c_str()));
int code = Z_OK;
do
{
stream.avail_out = sizeof(buffer);
stream.next_out = reinterpret_cast<Bytef*>(&buffer[0]);
code = ::deflate(&stream, Z_FINISH);
// Successful and non-fatal error code returned by deflate when used with Z_FINISH flush
if (code == Z_OK || code == Z_STREAM_END)
{
std::copy(&buffer[0], &buffer[sizeof(buffer) - stream.avail_out], std::back_inserter(compressed_str));
}
} while (code == Z_OK);
if (code != Z_STREAM_END)
compressed_str.clear();
::deflateEnd(&stream);
}
return compressed_str;
}
inline std::string decompress_string(std::string const& deflated_string)
{
std::string inflated_string;
Bytef tmp[8192];
z_stream zstream{};
zstream.avail_in = deflated_string.size();
// Nasty const_cast but zlib won't alter its contents
zstream.next_in = const_cast<Bytef*>(reinterpret_cast<Bytef const*>(deflated_string.c_str()));
// Initialize with automatic header detection, for gzip support
if (::inflateInit2(&zstream, MAX_WBITS | 32) == Z_OK)
{
do
{
zstream.avail_out = sizeof(tmp);
zstream.next_out = &tmp[0];
auto ret = ::inflate(&zstream, Z_NO_FLUSH);
if (ret == Z_OK || ret == Z_STREAM_END)
{
std::copy(&tmp[0], &tmp[sizeof(tmp) - zstream.avail_out], std::back_inserter(inflated_string));
}
else
{
// Something went wrong with inflate; make sure we return an empty string
inflated_string.clear();
break;
}
} while (zstream.avail_out == 0);
// Free zlib's internal memory
::inflateEnd(&zstream);
}
return inflated_string;
}
} // namespace xHttpCompress
hv 实现content压缩
HttpService router;
http_sync_handler user_status = std::bind(&XHttpServices::OnUserStatus, this, std::placeholders::_1, std::placeholders::_2);
router.GET("/user/status", user_status);
```cpp
int XHttpServices::OnUserStatus(HttpRequest* req, HttpResponse* resp)
{
XLOGI("OnUserStatus:%s", UTF82ACSTR(req->body));
hv::Json jresp, jdata;
try
{
jresp["code"] = jeflib::ERR_OK;
jresp["msg"] = jeflib::strerror(jresp["code"]);
jdata = UserMgr::instance().GetUserStatus();
jresp["data"] = jdata;
//查询客户端支持的压缩算法
std::string accept_encoding = req->GetHeader("Accept-Encoding");
if (accept_encoding.find("gzip") != std::string::npos)
{
resp->SetHeader("Content-Encoding", "gzip");
std::string strcontent = xHttpCompress::compress_string(jresp.dump(), xHttpCompress::algorithm::GZIP);
return resp->String(strcontent);
}
else if (accept_encoding.find("deflate") != std::string::npos)
{
resp->SetHeader("Content-Encoding", "deflate");
std::string strcontent = xHttpCompress::compress_string(jresp.dump(), xHttpCompress::algorithm::DEFLATE);
return resp->String(strcontent);
}
return resp->String(jresp.dump());
}
catch (const nlohmann::detail::exception& e)
{
jresp["code"] = jeflib::ERR_JSON_EXCEPTION;
jresp["msg"] = e.what();
return resp->String(jresp.dump());
}
}
测试结果:
原文地址:https://blog.csdn.net/CAir2/article/details/136563899
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!