使用INDY检测远程服务器上文件的Mime-Type

时间:2014-08-25 07:32:04

标签: delphi mime-types indy

我一直在使用Synapse库从互联网上下载文件,但我最近将我的应用程序转换为使用INDY而我错过了Synapse库中的一个更好的功能,即能够轻松获取Mime - 在将服务器保存到本地计算机之前从服务器下载的文件的类型。 INDY是否具有此功能,如果有,我该如何访问它?

2 个答案:

答案 0 :(得分:8)

您可以发出HTTP HEAD请求并检查Content-Type标头。在您真正GET文件(下载)之前:

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;

您收到的ContentType取决于Web服务器的实现,并且不保证在每台服务器上都是相同的。


另一个选项是实际GET文件,并将其内容保存到内存流,例如TMemoryStream(不是本地文件)。 Indy提供了一个过载:

Http.Get(Url, AStream);

然后检查Http.Response.ContentType,并将流保存到文件:AStream.SaveToFile


不确定这里的相关性,但请注意Indy也可以返回/猜测本地文件的mime类型(给定文件扩展名)。使用GetMIMETypeFromFile(使用IdGlobalProtocols)。另请参阅here

答案 1 :(得分:1)

或者你可以建立你的功能

function GetMIMEType(sFile: TFileName): string;
var aMIMEMap: TIdMIMETable;
begin
  aMIMEMap:= TIdMIMETable.Create(true);
    try
  result:= aMIMEMap.GetFileMIMEType(sFile);
    finally
      aMIMEMap.Free;
    end;
  end;

然后致电

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;