mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-29 18:37:41 +08:00
add some functions in class string, HttpServletResponse
This commit is contained in:
parent
8410e85b0c
commit
b5525ad021
@ -524,6 +524,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkg_client", "lib_acl_cpp\s
|
||||
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wizard_demo", "wizard_demo", "{1C02A405-3726-4410-80DF-91D60736352B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd_download", "app\wizard_demo\httpd_download\httpd_download_vc2012.vcxproj", "{1A38C49B-F712-4115-980B-6DBD632D25CF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
@ -2493,6 +2497,36 @@ Global
|
||||
{094E23DA-F097-4510-9977-0995B8502197}.Template|Win32.ActiveCfg = DebugDll|Win32
|
||||
{094E23DA-F097-4510-9977-0995B8502197}.Template|Win32.Build.0 = DebugDll|Win32
|
||||
{094E23DA-F097-4510-9977-0995B8502197}.Template|x64.ActiveCfg = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Debug|x64.Build.0 = Debug|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.DebugDll|Mixed Platforms.ActiveCfg = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.DebugDll|Mixed Platforms.Build.0 = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.DebugDll|Win32.Build.0 = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.DebugDll|x64.ActiveCfg = DebugDll|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.DebugDll|x64.Build.0 = DebugDll|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Release|Win32.Build.0 = Release|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Release|x64.ActiveCfg = Release|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Release|x64.Build.0 = Release|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Releasedll|Mixed Platforms.ActiveCfg = ReleaseDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Releasedll|Mixed Platforms.Build.0 = ReleaseDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Releasedll|Win32.ActiveCfg = ReleaseDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Releasedll|Win32.Build.0 = ReleaseDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Releasedll|x64.ActiveCfg = ReleaseDll|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Releasedll|x64.Build.0 = ReleaseDll|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Template|Mixed Platforms.ActiveCfg = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Template|Mixed Platforms.Build.0 = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Template|Win32.ActiveCfg = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Template|Win32.Build.0 = DebugDll|Win32
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Template|x64.ActiveCfg = DebugDll|x64
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF}.Template|x64.Build.0 = DebugDll|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -2508,6 +2542,7 @@ Global
|
||||
{128791D9-6787-471C-9A0C-0DCAE53F4911} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{DC7E75E5-FE42-4529-9D9A-19D240B8727B} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{1F3F3884-7F9B-4BA1-8CA3-61E6758A7193} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{37A14D60-8196-4BCA-9B1A-48302446AFAF} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{BE48C8C9-2F6D-450B-9D42-4666E9257C8A} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{A76344E8-D8EF-4E0D-9A01-73DB25B5B76E} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{2AAD256A-E891-4CFA-BA5F-70DDA2CC63AE} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
@ -2517,7 +2552,6 @@ Global
|
||||
{C799E376-2F01-4877-AF18-7F3CC8B95792} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{14531A45-383C-4CCF-870B-B5C867A314F2} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{37A14D60-8196-4BCA-9B1A-48302446AFAF} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064}
|
||||
{956FA905-A77F-41FE-A4BE-C3BD3B5B3E83} = {02535D96-1693-4AA3-B650-B22DC776FDC2}
|
||||
{225D0BFA-64D7-4F8F-951E-36A494CF6178} = {02535D96-1693-4AA3-B650-B22DC776FDC2}
|
||||
{ADE6F714-BD52-432D-AB86-62FA59AB6746} = {02535D96-1693-4AA3-B650-B22DC776FDC2}
|
||||
@ -2562,6 +2596,7 @@ Global
|
||||
{D232833B-57A9-4167-B37C-A4594953F93D} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
|
||||
{84376B60-FF20-4FD0-967E-C568FC2FBC53} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
|
||||
{C8535C82-3DCB-472E-9E8F-DA769D9375B1} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
|
||||
{1C02A405-3726-4410-80DF-91D60736352B} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
|
||||
{3C74E826-5E72-48A1-9DFD-777F4A7C9E1F} = {D232833B-57A9-4167-B37C-A4594953F93D}
|
||||
{B59C7CB6-5708-4522-B833-CEB160AA4817} = {D232833B-57A9-4167-B37C-A4594953F93D}
|
||||
{2DABFAD1-114B-4F96-9185-DC0C56A3662D} = {C799E376-2F01-4877-AF18-7F3CC8B95792}
|
||||
@ -2588,5 +2623,6 @@ Global
|
||||
{067E9700-A518-4747-AE70-0C6F433AE478} = {B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E}
|
||||
{2425D8B1-FE96-4D7F-BDB0-48C932935D96} = {B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E}
|
||||
{AFC106A8-C78A-43C6-BA55-1B7EB541F559} = {B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E}
|
||||
{1A38C49B-F712-4115-980B-6DBD632D25CF} = {1C02A405-3726-4410-80DF-91D60736352B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -68,6 +68,8 @@ bool http_servlet::doPost(acl::HttpServletRequest& req,
|
||||
req.getSession().setAttribute("sid", "xxxxxx");
|
||||
sid = req.getSession().getAttribute("sid");
|
||||
*/
|
||||
|
||||
// 调试:将客户端请求头记录在日志中
|
||||
acl::string hdr;
|
||||
req.getClient()->sprint_header(hdr);
|
||||
logger("request head:\r\n%s\r\n", hdr.c_str());
|
||||
@ -79,6 +81,7 @@ bool http_servlet::doPost(acl::HttpServletRequest& req,
|
||||
return transfer_file(req, res, range_from, range_to);
|
||||
}
|
||||
|
||||
// 普通下载过程
|
||||
bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
acl::HttpServletResponse& res)
|
||||
{
|
||||
@ -99,11 +102,18 @@ bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
|
||||
bool keep_alive = req.isKeepAlive();
|
||||
|
||||
acl::string hdr_entry;
|
||||
acl::string filename;
|
||||
filename.basename(in.file_path()); // 从文件全路径中提取文件名
|
||||
hdr_entry.format("attachment;filename=\"%s\"", filename.c_str());
|
||||
|
||||
// 设置 HTTP 响应头中的字段
|
||||
res.setStatus(200)
|
||||
.setKeepAlive(keep_alive)
|
||||
.setContentLength(fsize)
|
||||
.setContentType("application/octet-stream");
|
||||
.setContentType("application/octet-stream")
|
||||
// 设置 HTTP 头中的文件名
|
||||
.setHeader("Content-Disposition", hdr_entry.c_str());
|
||||
|
||||
acl::string hdr;
|
||||
res.getHttpHeader().build_response(hdr);
|
||||
@ -129,7 +139,8 @@ bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
|
||||
// 支持断点续传的数据传输过程
|
||||
bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
acl::HttpServletResponse& res, long long range_from, long long range_to)
|
||||
acl::HttpServletResponse& res,
|
||||
long long range_from, long long range_to)
|
||||
{
|
||||
if (range_from < 0)
|
||||
return reply(req, res, 400, "invalid range_from: %lld",
|
||||
@ -175,19 +186,23 @@ bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
|
||||
bool keep_alive = req.isKeepAlive();
|
||||
|
||||
acl::string hdr_entry;
|
||||
acl::string filename;
|
||||
filename.basename(in.file_path()); // 从文件全路径中提取文件名
|
||||
hdr_entry.format("attachment;filename=\"%s\"", filename.c_str());
|
||||
|
||||
// 设置 HTTP 响应头中的字段
|
||||
res.setStatus(206) // 响应状态必须为 206
|
||||
res.setStatus(206) // 响应状态 206 表示部分数据
|
||||
.setKeepAlive(keep_alive) // 是否保持长连接
|
||||
.setContentLength(length) // 实际要传输的数据长度
|
||||
.setContentType("application/octet-stream"); // 数据类型
|
||||
|
||||
// 设置分段传输数据的范围
|
||||
res.getHttpHeader()
|
||||
// 设置本次传输区间
|
||||
.set_range(range_from, range_to > 0 ? range_to : fsize - 1)
|
||||
// 设置数据总长度
|
||||
.set_range_total(fsize);
|
||||
|
||||
.setContentType("application/octet-stream") // 数据类型
|
||||
// 设置 HTTP 头中的文件名
|
||||
.setHeader("Content-Disposition", hdr_entry.c_str())
|
||||
// 设置本次传输区间的起始偏移位置及数据的总长度
|
||||
.setRange(range_from, range_to > 0
|
||||
? range_to : fsize - 1, fsize);
|
||||
|
||||
// 调试:将 HTTP 响应头记在本地日志中
|
||||
acl::string hdr;
|
||||
res.getHttpHeader().build_response(hdr);
|
||||
logger("response head:\r\n%s\r\n", hdr.c_str());
|
||||
@ -196,9 +211,13 @@ bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
int ret;
|
||||
size_t size;
|
||||
|
||||
// 从文件指定位置读取数据,并将数据传输给客户端
|
||||
while (!in.eof() && length > 0)
|
||||
{
|
||||
size = sizeof(buf) > (size_t) length ? (size_t) length : sizeof(buf);
|
||||
size = sizeof(buf) > (size_t) length ?
|
||||
(size_t) length : sizeof(buf);
|
||||
|
||||
// 第三个参数为 false 表示仅进行一次读操作,不必待缓冲区满后再返回
|
||||
ret = in.read(buf, size, false);
|
||||
if (ret == -1)
|
||||
{
|
||||
@ -212,6 +231,10 @@ bool http_servlet::transfer_file(acl::HttpServletRequest& req,
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
logger_error("read file failed");
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true && keep_alive;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}</ProjectGuid>
|
||||
<ProjectGuid>{1A38C49B-F712-4115-980B-6DBD632D25CF}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectName>httpd_download</ProjectName>
|
||||
</PropertyGroup>
|
||||
@ -362,4 +362,4 @@ copy ..\..\..\dist\lib\win64\lib_protocol_d.dll $(OutDir) /Y</Command>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -51,7 +51,7 @@ int main(int argc, char* argv[])
|
||||
acl::log::stdout_open(true);
|
||||
|
||||
// 监听的地址列表,格式:ip:port1,ip:port2,...
|
||||
const char* addrs = "127.0.0.1:8888";
|
||||
const char* addrs = ":8888";
|
||||
printf("listen on: %s\r\n", addrs);
|
||||
|
||||
// 测试时设置该值 > 0 则指定服务器处理客户端连接过程的
|
||||
|
@ -84,6 +84,22 @@ public:
|
||||
*/
|
||||
HttpServletResponse& setHeader(const char* name, int value);
|
||||
|
||||
/**
|
||||
* 对于分区下载,调用本函数设置数据下载的偏移位置(下标从 0 开始)
|
||||
* @param from {http_off_t} 数据区间起始偏移位置(下标从 0 开始计算)
|
||||
* @param to {http_off_t} 数据区间结束位置(该值需小于总数据长度)
|
||||
* @param total {http_off_t} 总数据长度,当数据源为一个静态文件时该值应
|
||||
* 等于该文件的总长度大小
|
||||
* @return {HttpServletResponse&}
|
||||
*/
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
HttpServletResponse& setRange(__int64 from,
|
||||
__int64 to, __int64 total);
|
||||
#else
|
||||
HttpServletResponse& setRange(long long from,
|
||||
long long to, long long total);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 设置 HTTP 响应头中的状态码:1xx, 2xx, 3xx, 4xx, 5xx
|
||||
* @param status {int} HTTP 响应状态码, 如:200
|
||||
|
@ -1101,6 +1101,20 @@ public:
|
||||
*/
|
||||
string& hex_decode(const char* s, size_t len);
|
||||
|
||||
/**
|
||||
* 从文件全路径中提取文件名
|
||||
* @param path {const char*} 文件全路径字符串,非空字符串
|
||||
* @return {string&} 当前对象的引用
|
||||
*/
|
||||
string& basename(const char* path);
|
||||
|
||||
/**
|
||||
* 从文件全路径中提取文件所在目录
|
||||
* @param path {const char*} 文件全路径字符串,非空字符串
|
||||
* @return {string&} 当前对象的引用
|
||||
*/
|
||||
string& dirname(const char* path);
|
||||
|
||||
/**
|
||||
* 将 32 位有符号整数转为字符串存(内部使用了线程局部变量)
|
||||
* @param n {int} 32 位有符号整数
|
||||
|
@ -95,6 +95,14 @@ HttpServletResponse& HttpServletResponse::setStatus(int status)
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpServletResponse& HttpServletResponse::setRange(
|
||||
http_off_t from, http_off_t to, http_off_t total)
|
||||
{
|
||||
header_->set_range(from, to);
|
||||
header_->set_range_total(total);
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpServletResponse& HttpServletResponse::setCgiMode(bool on)
|
||||
{
|
||||
header_->set_cgi_mode(on);
|
||||
|
@ -1403,6 +1403,18 @@ string& string::hex_decode(const char* s, size_t len)
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::basename(const char* path)
|
||||
{
|
||||
(void) acl_sane_basename(vbf_, path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::dirname(const char* path)
|
||||
{
|
||||
(void) acl_sane_dirname(vbf_, path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static void dummy_free(void*)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user