我试图使用indy (HTTP )恢复上传,代码如下(使用Delphi2010,Indy 10.4736):
IdHttp.Head('http://localhost/_tests/resume/large-file.bin');
ByteRange := IdHttp.Response.ContentLength + 1;
// Attach the file to post/upload
Stream := TIdMultipartFormDataStream.Create;
with Stream.AddFile('upload_file', 'D:\large-file.bin', 'application/octet-stream') do
begin
HeaderCharset := 'utf-8';
HeaderEncoding := '8';
end; // with
with IdHTTP do
begin
IOHandler.LargeStream := True;
with Request do
begin
ContentRangeStart := ByteRange;
ContentRangeEnd := (Stream.Size - ByteRange);
ContentLength := ContentRangeEnd;
ContentRangeInstanceLength := ContentLength;
end; // with
Post('http://localhost/_tests/resume/t1.php', Stream);
end; // with但是上传简历不起作用:
我查看了Indy的代码,似乎这个函数在IdIOHandler.pas中
TIdIOHandler.Write()
始终处理完整的流/文件(因为参数ASize: TIdStreamSize似乎总是0,根据代码,这意味着发送完整的文件/流)。
这样可以防止indy继续上传。
我的问题是:是否有可能避免发送完整的文件?
设置内容范围没有改变任何事情。我还修改了indy的代码(修改了3行),以使indy服从内容范围/流位置,但是它是错误的,并且indy总是挂在IdStackWindows.pas中,因为这里有一个无限的超时:
TIdSocketListWindows.FDSelect()
发布于 2012-03-07 10:55:53
正如我在your earlier question中告诉您的,您必须发布一个包含要上载的剩余文件数据的TStream。不要使用TIdMultipartFormDataStream.AddFile(),因为这将发送整个文件。改用TStream重载版本的TIdMultipartFormDataStream.AddFormField()。
TIdHTTP并不是为了尊重ContentRange...属性而设计的。大多数Request属性仅设置相应的headers,它们不影响数据。这就是为什么你的编辑破坏了它。
试试这个:
IdHttp.Head('http://localhost/_tests/resume/large-file.bin');
FileSize := IdHttp.Response.ContentLength;
FileStrm := TFileStream.Create('D:\large-file.bin', fmOpenRead or fmShareDenyWrite);
try
if FileSize < FileStrm.Size then
begin
FileStrm.Position := FileSize;
Stream := TIdMultipartFormDataStream.Create;
try
with Stream.AddFormField('upload_file', 'application/octet-stream', '', FileStrm, 'large-file.bin') do
begin
HeaderCharset := 'utf-8';
HeaderEncoding := '8';
end;
with IdHTTP do
begin
with Request do
begin
ContentRangeStart := FileSize + 1;
ContentRangeEnd := FileStrm.Size;
end;
Post('http://localhost/_tests/resume/t1.php', Stream);
end;
finally
Stream.Free;
end;
end;
finally
FileStrm.Free;
end;尽管如此,这是一个严重滥用的HTTP和multipart/form-data。首先,ContentRange值位于错误的位置。您正在将它们应用于整个Request,这是错误的。它们需要在FormField上应用,但是TIdMultipartFormDataStream目前不支持这一点。第二,multipart/form-data的设计并不是为了像这样使用。从一开始上传一个文件是可以的,但是不能恢复一个坏的上传。您真的应该停止使用TIdMultipartFormDataStream,直接将文件数据像i suggested earlier那样传递给TIdHTTP.Post(),例如:
FileStrm := TFileStream.Create('D:\large-file.bin', fmOpenRead or fmShareDenyWrite);
try
IdHTTP.Post('http://localhost/_tests/upload.php?name=large-file.bin', FileStrm);
finally
FileStrm.Free;
end;。
IdHTTP.Head('http://localhost/_tests/files/large-file.bin');
FileSize := IdHTTP.Response.ContentLength;
FileStrm := TFileStream.Create('D:\large-file.bin', fmOpenRead or fmShareDenyWrite);
try
if FileSize < FileStrm.Size then
begin
FileStrm.Position := FileSize;
IdHTTP.Post('http://localhost/_tests/resume.php?name=large-file.bin', FileStrm);
end;
finally
FileStrm.Free;
end;我已经知道如何在explained earlier中访问原始的POST数据。
https://stackoverflow.com/questions/9598273
复制相似问题