自学内容网 自学内容网

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)!