add some functions in class string, HttpServletResponse

This commit is contained in:
zsxxsz 2015-07-05 22:51:31 +08:00
parent 8410e85b0c
commit b5525ad021
8 changed files with 127 additions and 18 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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>

View File

@ -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 则指定服务器处理客户端连接过程的

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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*)
{
}