3

I have a url of a website. It looks something like this: http://www.example.com/downloads/file/4789/download?

I would like to save the file to my system, but I do not know how to get the file name of the download triggered by the URL in my example. Some files are pdf others are doc and rtf etc.

If someone can please point me in a direction of the filename problem and also what components to use, I would really appreciate it.

mjn
  • 36,362
  • 28
  • 176
  • 378
louis_coetzee
  • 393
  • 7
  • 14
  • Sorry, @Ken. I just removed the parts of the question you were talking about since they have nothing to do with the question at hand. User, please ask about how to log in to the system in a separate question and keep *this* question focused on how to discover the file name. – Rob Kennedy Jun 11 '12 at 22:01

1 Answers1

6

to get the filename from a url you can retrieve the HEAD information and check Content Disposition header field. For this task you can use the TIdHTTP indy component. if the Content Disposition doesn't have the file name you can try parsing the url.

Try this sample .

{$APPTYPE CONSOLE}

{$R *.res}

uses
  IdURI,
  IdHttp,
  SysUtils;

function GetRemoteFileName (const URI: string) : string;
var
  LHttp: TIdHTTP;
begin
  LHttp := TIdHTTP.Create(nil);
  try
    LHttp.Head(URI);
    Result:= LHTTP.Response.RawHeaders.Params['Content-Disposition', 'filename'];
    if Result = '' then
     with TIdURI.Create(URI) do
      try
       Result := Document;
      finally
       Free;
      end;
  finally
    LHttp.Free;
  end;
end;

begin
  try
    Writeln(GetRemoteFileName('http://dl.dropbox.com/u/12733424/Blog/Delphi%20Wmi%20Code%20Creator/Setup_WmiDelphiCodeCreator.exe'));
    Writeln(GetRemoteFileName('http://studiostyl.es/settings/downloadScheme/1305'));

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • 2
    Instead of parsing the headers manually, you can use Indy's `ExtractHeaderSubItem()` function: `Result := ExtractHeaderSubItem(LHTTP.Response.ContentDisposition, 'filename', QuoteHTTP);`, or its `TIdHeaderList.Params[]` property: `Result := LHTTP.Response.RawHeaders.Params['Content-Disposition', 'filename'];`. If you fallback to `TIdURI`, use its `Document` property: `with TIdURI.Create(URI) do try Result := Document; finally Free; end;` – Remy Lebeau Jun 12 '12 at 00:17
  • 1
    Thanks Remy, I add your suggestions to the answer. – RRUZ Jun 12 '12 at 00:24
  • 1
    You should be able to get the same information from the GET response headers, right? So if you're downloading the file, you can issue a GET, read the Content-Disposition header, and write the contents to a file with that name without having to issue two separate requests to the server. – Rob Kennedy Jun 12 '12 at 16:49
  • Thank you guys, that works. In the end I went without delphi and used wget instead, since it allows for sending post data and saving the cookie. Had the same problem here with getting the filename, and in wget also ContentDisposition was the answer. – louis_coetzee Jun 21 '12 at 21:54