Finding the mime type of a file on a remote server using INDY
I am using the Synapse library to download files from the internet, but I recently converted my application to use INDY and I am missing one of the best features in the Synapse library that makes it easy to get a Mime-Type of file that I downloaded from the server before save it to my local computer. INDY has this feature, and if so how do I get it?
source to share
You can send an HTTP request HEAD
and check the header Content-Type
. Before you actually GET
file (download):
procedure TForm1.Button1Click(Sender: TObject);
var
Url: string;
Http: TIdHTTP;
begin
Url := 'http://yoursite.com/yourfile.png';
Http := TIdHTTP.Create(nil);
try
Http.Head(Url);
ShowMessage(Http.Response.ContentType); // "image/png"
finally
Http.Free;
end;
end;
The return value ContentType
depends on the web server implementation and is not guaranteed to be the same on every server.
Another option is to actually GET
file and store its contents in a memory stream, for example TMemoryStream
(rather than a local file). Indy provides overloading:
Http.Get(Url, AStream);
Then you check Http.Response.ContentType
and save the stream to a file: AStream.SaveToFile
.
Not sure about the relevance here, but note also that Indy can return / guess the mime type of the local file (given the file extension). using GetMIMETypeFromFile
(uses IdGlobalProtocols
). See also here .
source to share
Or you can create your function
function GetMIMEType(sFile: TFileName): string;
var aMIMEMap: TIdMIMETable;
begin
aMIMEMap:= TIdMIMETable.Create(true);
try
result:= aMIMEMap.GetFileMIMEType(sFile);
finally
aMIMEMap.Free;
end;
end;
And then call
procedure HTTPServerGet(aThr: TIdPeerThread; reqInf: TIdHTTPRequestInfo;
respInf: TIdHTTPResponseInfo);
var localDoc: string;
ByteSent: Cardinal;
begin
//RespInfo.ContentType:= 'text/HTML';
Writeln(Format('Command %s %s at %-10s received from %s:%d',[ReqInf.Command, ReqInf.Document,
DateTimeToStr(Now),aThr.Connection.socket.binding.PeerIP,
aThr.Connection.socket.binding.PeerPort]));
localDoc:= ExpandFilename(Exepath+'/web'+ReqInf.Document);
RespInf.ContentType:= GetMIMEType(LocalDoc);
if FileExists(localDoc) then begin
ByteSent:= HTTPServer.ServeFile(AThr, RespInf, LocalDoc);
Writeln(Format('Serving file %s (%d bytes/ %d bytes sent) to %s:%d at %s',
[LocalDoc,ByteSent,FileSizeByName(LocalDoc), aThr.Connection.Socket.Binding.PeerIP,
aThr.Connection.Socket.Binding.PeerPort, dateTimeToStr(now)]));
end else begin
RespInf.ResponseNo:= 404; //Not found RFC
RespInf.ContentText:=
'<html><head><title>Sorry WebBox Error</title></head><body><h1>' +
RespInf.ResponseText + '</h1></body></html>';
end;
end;
source to share