我正在开发一个小型的Web服务器,它应该允许下载管理器进行多个连接,并同时下载多个段中的一个巨大的文件。
我可以检测到下载管理器请求部分下载(ARequestInfo.Ranges
属性),并使用我自己的TFileFragmentStream
类(作为TStream
后代提供给定范围的文件)创建了一个函数来提供这些片段。
然而,我的下载管理器似乎不接受我的服务器支持这一点,并且只使用一个连接下载它。我可以看到它请求部分下载,所以我可能不满意我支持它。
我现在使用的代码是这样的:
PROCEDURE SendPartialFile(Response : TIdHttpResponseInfo ; CONST N : TFileName ; RangeStart,RangeEnd : Int64);
BEGIN
Response.ContentType:='application/octet-stream';
Response.ContentDisposition:='attachment; filename="'+ExrractFileName(N)+'"';
Response.ContentLength:=SUCC(RangeEnd-RangeStart);
Response.ContentStream:=TFileFragmentStream.Create(N,RangeStart,ContentLength)
Response.FreeContentStream:=TRUE
END;
我的Response是否还有其他属性需要设置?
更新最终代码:
ContentDisposition:='attachment; filename="'+N.NameOnly+'"';
VAR S:=TIdHTTPRangeStream.Create(TFileStream.Create(N,fmOpenRead OR fmShareDenyNone),RangeStart,RangeEnd);
ContentStream:=S;
ResponseNo:=S.ResponseCode;
ContentRangeStart:=S.RangeStart;
ContentRangeEnd:=S.RangeEnd;
ContentText:='';
ContentRangeInstanceLength:=S.SourceStream.Size;
OutputDebugString('Sending File Fragment: '+ContentType+' ['+IntToStr(ContentRangeStart)+'-'+IntToStr(ContentRangeEnd)+'] ('+IntToStr(ContentLength)+' bytes) "'+ContentDisposition+'" ResponseNo='+IntToStr(ResponseNo));
FreeContentStream:=TRUE;
下面是日志记录:
Sending Full File: video/mp4 XX.mp4 (6573584385 bytes)
Sending File Fragment: video/mp4 [233600-6573584384] (6573350785 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [3286914832-6573584384] (3286669553 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [4930249645-6573584384] (1643334740 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [1655659767-3286914895] (1631255129 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [4108582275-4930249708] (821667434 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [5751917052-6573584384] (821667333 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [2471287336-3286914895] (815627560 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
Sending File Fragment: video/mp4 [855370091-1655659830] (800289740 bytes) "attachment; filename="XX.mp4"" ResponseNo=206
完整文件只是一个
ContentType:='application/octet-stream'
ContentDisposition:='attachment; filename="'+ExtractFileName(FileName)+'"'
ContentStream:=TFileStream.Create(FileName,fmOpenRead OR fmShareDenyNone)
FreeContentStream:=TRUE
ResponseNo:=200
1条答案
按热度按时间2ledvvac1#
您需要设置各种
AResponseInfo.ContentRange...
属性来描述实际发送回客户端的范围:此外,请确保您正在设置
AResponseInfo.ResponseNo
,以指示您是发送部分范围(206)还是发送完整文件(200)。阅读RFC 2616第10.2.7 206节部分内容和第14.16节内容范围以了解更多详细信息。
顺便说一句,
TIdHTTPServer
有自己的TIdHTTPRangeStream
助手类,用于发送源TStream
的部分范围。您可以使用源流(例如TFileStream
)和请求的范围构建它,然后使用其ResponseCode
,RangeStart
和RangeEnd
属性来更新AResponseInfo
,例如: