[英]Indy Http Server with resume support
I have written an indy http server, I want to serve file download with resume support. 我写了一个indy http服务器,我想用简历支持服务文件下载。 When I use IDM to download file, the download is single threaded: 当我使用IDM下载文件时,下载是单线程的:
Note that the Resume capability is Yes , but When I pause and resume the download, It starts form beginning. 请注意,“ 恢复”功能为“是” ,但是当我暂停并恢复下载时,它将从表单开始。
My Indy Http Server is as: 我的Indy Http服务器如下:
void __fastcall TfrmMain::httpServerCommandGet(TIdContext *AContext,
TIdHTTPRequestInfo *ARequestInfo, TIdHTTPResponseInfo *AResponseInfo)
{
Beep(1000, 100);
string fileName = ExtractFileDir(Application->ExeName) + ARequestInfo->Document;
fileName = fileName.replace("/", "\\");
TFileStream *stream = new TFileStream(fileName, fmOpenRead | fmShareDenyNone);
int start = 0, end = 0;
string range = ARequestInfo->Range;
if(!range.empty())
{
int dash_pos = range.find("-");
start = range.substr(0, dash_pos).intValue();
end = range.substr(dash_pos + 1).intValue();
if(end == 0) // Endless Range: start-
end = stream->Size;
}
else
{
start = 0;
end = stream->Size;
}
OutputDebugStringW(string("ctx=[] start=[] end=[]") <<
IntToHex((int)AContext, 8) << start << end);
stream->Seek((__int64)start, soBeginning);
AResponseInfo->ContentStream = stream;
AResponseInfo->FreeContentStream = true;
AResponseInfo->ContentLength = stream->Size;
if(!range.empty())
{
AResponseInfo->ContentRangeStart = start;
AResponseInfo->ContentRangeEnd = end;
AResponseInfo->ResponseNo = 206;
AResponseInfo->ContentRangeInstanceLength = end + 1;
AResponseInfo->ContentLength = end - start + 1;
AResponseInfo->AcceptRanges = "bytes";
}
AResponseInfo->WriteHeader();
AResponseInfo->WriteContent();
}
any help would be appreciated. 任何帮助,将不胜感激。
The IdCustomHTTPServer
unit has a TIdHTTPRangeStream
helper class for this very purpose. 出于此目的, IdCustomHTTPServer
单元具有TIdHTTPRangeStream
辅助类。
If the client requests a ranged download, create an instance of TIdHTTPRangeStream
and pass it your intended TStream
and the client's requested range, then assign it as the ContentStream
to be sent. 如果客户端请求范围下载,请创建TIdHTTPRangeStream
的实例并将其传递给您预期的TStream
和客户端请求的范围,然后将其指定为要发送的ContentStream
。 TIdHTTPRangeStream
also has a ResponseCode
property that you need to assign to the response's ResponseNo
property. TIdHTTPRangeStream
还有一个ResponseCode
属性,您需要将该属性分配给响应的ResponseNo
属性。
For example: 例如:
void __fastcall TfrmMain::httpServerCommandGet(TIdContext *AContext, TIdHTTPRequestInfo *ARequestInfo, TIdHTTPResponseInfo *AResponseInfo)
{
// create file stream ...
// THTTPServer parses the ranges for you
if (ARequestInfo->Ranges->Count > 0)
{
if (ARequestInfo->Ranges->Count > 1)
{
AResponseInfo->ResponseNo = 416;
return;
}
TIdEntityRange *range = ARequestInfo->Ranges->Range[0];
TIdHTTPRangeStream *rstream = new TIdHTTPRangeStream(stream, range->StartPos, range->EndPos, true);
AResponseInfo->ResponseNo = rstream->ResponseCode;
AResponseInfo->ContentRangeStart = rstream->RangeStart;
AResponseInfo->ContentRangeEnd = rstream->RangeEnd;
AResponseInfo->ContentStream = rstream;
AResponseInfo->AcceptRanges = "bytes";
}
else
{
AResponseInfo->ContentStream = stream;
}
// no need to seek the target stream manually
// no need to set the ContentLength manually
// no need to call WriteHeader() and WriteContent() manually
//
// TIdHTTPServer handles all that for you internally!
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.