我在使用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文件?
答案 0 :(得分:7)
TIdHTTP
失败的原因是wget报告的这一关键信息:
没有标题,假设HTTP / 0.9
在HTTP 0.9响应中,HTTP状态行和标题根本不存在,只有原始文件数据本身由断开连接终止。 wget支持,但TIdHTTP
没有(尽管官方HTTP 1.0和HTTP 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的问题跟踪器中打开了门票。