在特定的Web服务器上使用IdHTTP1.Get与Delphi和Indy 9/10返回异常

时间:2013-01-26 23:54:42

标签: delphi http indy indy10 indy-9

我在使用Delphi和Indy 9/10从特定Web服务器接收favicon.ico时遇到问题。其他服务器工作正常。问题不在于此Web服务器,因为wget命令行实用程序正确获取文件。

这是wget的输出:

c:\a>wget http://perforce.eigenbase.org:8080/favicon.ico
SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc
syswgetrc = c:/progra~1/wget/etc/wgetrc
--2013-01-27 00:12:39--  http://perforce.eigenbase.org:8080/favicon.ico
Resolving perforce.eigenbase.org... 72.14.190.177
Connecting to perforce.eigenbase.org|72.14.190.177|:8080... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Saving to: `favicon.ico'

    [ <=>                                   ] 2.862       --.-K/s   in 0s

2013-01-27 00:12:40 (143 MB/s) - `favicon.ico' saved [2862]

这是我的Delphi Indy 9/10示例代码。它生成一个“Connection Closed Gracefully”异常,结果是一个空字符串。

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
  s := '';
  try
    s := IdHTTP1.Get('http://perforce.eigenbase.org:8080/favicon.ico');
  except
     on E: Exception do
     begin
          {$IFDEF DEBUG}ShowMessage('get error:'+E.Message){$ENDIF};
     end;
  end;
  ShowMessage(IntToStr(Length(s)));
end;

如果我使用不同的服务器尝试相同的代码,例如:

s := IdHTTP1.Get('http://www.google.com/favicon.ico');

一切正常。

是否有解决方法从服务器使用IdHTTP1.Get获取http://perforce.eigenbase.org:8080/favicon.ico文件?

1 个答案:

答案 0 :(得分:7)

TIdHTTP失败的原因是wget报告的这一关键信息:

  

没有标题,假设HTTP / 0.9

在HTTP 0.9响应中,HTTP状态行和标题根本不存在,只有原始文件数据本身由断开连接终止。 wget支持,但TIdHTTP没有(尽管官方HTTP 1.0HTTP 1.1规范要求支持识别HTTP 0.9响应)。 TIdHTTP仅支持HTTP 1.0和1.1格式的消息,这些消息需要使用HTTP状态行和标头。无论出于何种原因,此特定服务器选择为Indy的UserAgent发送HTTP 0.9响应,但选择为Internet Explorer UserAgent发送HTTP 1.0响应。奇

短期解决方案是做@TLama所说的。将TIdHTTP.Request.UserAgent属性设置为模仿Internet Explorer可使TIdHTTP.Get()正常工作:

procedure TForm1.Button1Click(Sender: TObject);
var
  icon: TMemoryStream;
begin
  icon := TMemoryStream.Create;
  try
    try
      IdHTTP1.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1';
      IdHTTP1.Get('http://perforce.eigenbase.org:8080/favicon.ico', icon);
    except
      on E: Exception do
      begin
        {$IFDEF DEBUG}ShowMessage('get error:'+E.Message){$ENDIF};
      end;
    end;
    ShowMessage(IntToStr(icon.Size));
  finally
    icon.Free;
  end;
end;

长期解决方案是更新TIdHTTP以支持HTTP 0.9响应,即使它们现在非常罕见。我已经在Indy的问题跟踪器中打开了门票。