delphi - 在特定 Web 服务器上将 IdHTTP1.Get 与 Delphi 和 Indy 9/10 一起使用会返回异常

标签 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 示例代码。它会生成“正常关闭连接”异常,结果为空字符串。

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');

一切正常。

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

最佳答案

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

No headers, assuming HTTP/0.9

在 HTTP 0.9 响应中,HTTP 状态行和 header 根本不存在,只有原始文件数据本身,由断开连接终止。 wget 支持,但 TIdHTTP 不支持(即使官方 HTTP 1.0HTTP 1.1 规范要求支持识别 HTTP 0.9 响应)。 TIdHTTP 仅支持 HTTP 1.0 和 1.1 格式的消息,这需要使用 HTTP 状态行和 header 。无论出于何种原因,此特定服务器选择为 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 的问题跟踪器中打开了工单。

关于delphi - 在特定 Web 服务器上将 IdHTTP1.Get 与 Delphi 和 Indy 9/10 一起使用会返回异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14542873/

相关文章:

delphi - 如何在参数化查询中显式插入空值?

德尔福:idHttp+SSL

java - Spring security - 自定义保持 Activity Controller

delphi - TIdHTTP 组件可以处理 javascript 代码吗?

delphi - 向同一台计算机上的多个客户端发送多播消息

delphi - For 循环变量违反循环界限

delphi - 如何在 Delphi XE2 dbExpress 和 Firebird 2.5 中使用 bool 值

android - Blogger api 总是返回 401 错误响应

apache - 405 方法不允许 : PUT http://localhost:3030/dataset/data? 默认

delphi - 在 IdHTTPServer 中动态更改 SSL 证书