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?
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With