如何创建一个在Indy中创建文件下载工作的页面?

问题描述:

我有一个Indy服务器,并在URL请求文件时发送一个文件是微不足道的,而且似乎总能正常工作。如何创建一个在Indy中创建文件下载工作的页面?

但我也想设置一个类似如下的第二种情况:(这适用于动态生成的内容,所以要求一个静态文件将无法正常工作)

http://example.com/getFile.html?filename=myImage.png

我使用的是定制的印客户端,并呼吁TIdHTTP.Get检索所有这些文件,并在第二个用例,似乎这个算法是继:

Roll 1D4. If you rolled 2 or higher, download correctly. 
Otherwise, roll 1D6 against this table of Indy exceptions and 
raise one of them. 
If a random exception is raised, it MUST NOT be caught inside 
of Indy code. 

到目前为止,常见的似乎是EIdHTTPProtocolExceptionEIdClosedSocketEIdNotConnected,但我也见过其他一些人。设置一个异常处理程序来捕获这些异常,并重新尝试下载工作,有时甚至会引发更多的异常,这些异常看起来是随机的,没有确定性原则。

事实上,这个从来没有发生使用静态下载用例告诉我,在第二个用例中可能会有一些奇怪的事情发生,我的代码没有正确计算。代码真的很简单。在客户端:

procedure TdmConnection.GetFile(const URL: string; stream: TStream); 

    procedure Retry; 
    begin 
    sleep(100); 
    stream.Size := 0; //clear any aborted partial download 
    http.Get(URL, stream); 
    end; 

begin 
    try 
     http.Get(URL, stream); 
    except 
     on EIdClosedSocket do 
     Retry; 
     on EIdNotConnected do 
     Retry; 
     on EIdHTTPProtocolException do 
     Retry; 
    end; 
end; 

而在服务器端,请求运行产生该文件的脚本(正确;我验证过的部分),并告诉印服务器,使其返回的HTTP响应。我试着简单地打开一个TFileStream并将其分配给Response.ContentStream,并且我试着在Response对象上调用ServeFile方法,并且我最终还是在客户端获得了相同的错误。服务器代码的相关部分如下所示:

if lServeFile <> '' then begin //variable set by the script 
    if lServeFile = '***' then 
     response.ResponseNo := 404 
    else begin 
     response.ResponseNo := 200; 
     response.ServeFile(AContext, lServeFile); 
    end; 
    end; 

任何有经验的Indy用户知道我在做什么错了?使用Delphi XE附带的Indy 10库存。

+0

我已经使用了ServeFile,但由于某种原因,我已经结束了使用WriteFile,不记得为什么,也许你可以尝试吗? – ComputerSaysNo

+0

您的客户端代码没有问题。请显示您的服务器代码。 –

+0

@Remy:编辑添加服务器代码。这真的很简单。 –

没关系,问题不在Indy。经过进一步调试,我最终发现有两个线程都使用了IdHTTP组件,有时他们同时使用它。保证每个线程都有自己的IdHTTP解决了这个问题。

+0

不要这么快责怪indy,这个bug通常在你自己的代码中。但不是总是[正如我在这里指出的那样](http://stackoverflow.com/a/4414918/407361) – MikeT