Using IdHTTP1.Get with Delphi and Indy 9/10 on a specific webserver returns an exception
I have a problem getting favicon.ico from a specific webserver using Delphi and Indy 9/10. Other servers are working fine. The problem is not with this webserver, as the wget command line utility is getting the file correctly.
Here's the output from 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]
Here is my Delphi Indy 9/10 code example. It throws a "Closed connection" exception and the result is an empty string.
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;
If I try the same code with a different server, for example:
s := IdHTTP1.Get('http://www.google.com/favicon.ico');
everything works perfectly.
Is there a way to bypass the http://perforce.eigenbase.org:8080/favicon.ico file using IdHTTP1.Get from the server?
source to share
The reason for the error TIdHTTP
is due to this key piece of information that wget reports:
No headers suggesting HTTP / 0.9
In the HTTP 0.9 response, there are no HTTP status bar and headers at all, only the raw file data itself, completed by disconnecting. wget supports this but TIdHTTP
does not work (even though the official HTTP 1.0 and HTTP 1.1 require support for recognizing HTTP 0.9 responses). TIdHTTP
only supports formatted HTTP 1.0 and 1.1 messages, which require the use of status bars and HTTP headers. For some reason, this particular server prefers to send an HTTP 0.9 response for Indy UserAgent
, but instead sends an HTTP 1.0 response for Internet Explorer UserAgents. Odd.
The short term solution is to do what @TLama said. Setting the property TIdHTTP.Request.UserAgent
to simulate Internet Explorer allows it to TIdHTTP.Get()
work properly:
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;
The long term solution would be to update TIdHTTP
to support HTTP 0.9 responses, even if they are very rare. I opened Indy tickets to track issues.
source to share