I have been using the Synapse library to download files from the internet, but I have recently converted my application to use INDY instead and I am missing one of the nicer features in the Synapse library which is the ability to easily get the Mime-Type of a file that I was downloading from a server before saving it to my local machine. Does INDY have this feature and if so how do I go about accessing it?
问题:
回答1:
You can issue an HTTP HEAD
request and check the Content-Type
header. Before you actually GET
the 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 ContentType
you receive back depends on the web server implementation and is not guaranteed to be the same on each and every server.
The other option, is to actually GET
the file and save it's content to a memory stream such as TMemoryStream
(not to a local file). Indy provides an overload:
Http.Get(Url, AStream);
Then you check the Http.Response.ContentType
, and Save the stream to file: AStream.SaveToFile
.
Not sure about the relevancy here, but note also that Indy can return/guess the mime type of a local file as well (given a file extension). with GetMIMETypeFromFile
(uses IdGlobalProtocols
). See also here.
回答2:
Or you can build 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;