【问题标题】:Using IdHTTP1.Get with Delphi and Indy 9/10 on a specific web server returns exception在特定 Web 服务器上将 IdHTTP1.Get 与 Delphi 和 Indy 9/10 一起使用会返回异常
【发布时间】:2013-01-26 23:54:41
【问题描述】:

我在使用 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 示例代码。它会生成一个“正常关闭连接”异常,结果是一个空字符串。

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 文件?

【问题讨论】:

  • 更改 Request.UserAgentIdHTTP1 组件,例如到Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1,你会没事的。服务器拒绝你(以正式的方式)只是因为你充当默认的Mozilla/3.0 (compatible; Indy Library) 代理(相当残忍的政策,但确实如此)。
  • 无论如何,您不必以字符串形式接收Get 响应。由于您显然正在下载一个文件,因此您不会以文本形式显示(为什么要将图标显示为文本文件),但您可能会像处理文件一样保存或操作它,您可以使用Get 重载,它接收对流的响应。

标签: delphi http indy indy10 indy-9


【解决方案1】:

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 UserAgents 发送 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 的问题跟踪器中打开了票证。

【讨论】:

    猜你喜欢
    • 2013-09-03
    • 2012-10-29
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 2011-10-07
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多