Cas*_*ady 3 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]
Run Code Online (Sandbox Code Playgroud)
这是我的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;
Run Code Online (Sandbox Code Playgroud)
如果我使用不同的服务器尝试相同的代码,例如:
s := IdHTTP1.Get('http://www.google.com/favicon.ico');
Run Code Online (Sandbox Code Playgroud)
一切正常.
是否有解决方法从服务器使用IdHTTP1.Get 获取http://perforce.eigenbase.org:8080/favicon.ico文件?
原因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发送HTTP 0.9响应UserAgent,但是选择为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;
Run Code Online (Sandbox Code Playgroud)
长期解决方案是更新TIdHTTP以支持HTTP 0.9响应,即使它们现在非常罕见.我已经在Indy的问题跟踪器中打开了门票.