[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1316
  • Last Modified:

Find filename to save internet downloaded file(via HTTP) to

hi
If I enter this URL into a browser
http://www.censusdata.abs.gov.au/ABSNavigation/download?format=xls&collection=Census&period=2006&productlabel=Ancestry%20by%20Country%20of%20Birth%20of%20Parents&producttype=Census%20Tables&method=Place%20of%20Usual%20Residence&areacode=SSC16003
for a file download
then the browser suggests
20680-b08-Aarons Pass-NSW (State Suburb).xls
as the filename to save to.

Note that this filename contains info which is not in the url

Looking around the net for downloading files I see various bits of code which use WinInet functions like InternetOpenURL, but the code always seems to want you to supply the target filename (ie the name of the file to which data is to be saved).

But I want to GET that filename, as per the above example.

How can I do that?

Thanks
0
Mutley2003
Asked:
Mutley2003
  • 3
  • 2
1 Solution
 
kretzschmarCommented:
usual i would guess a like servlet produces this file and responses with a Multipart or a URL (where the last segemnt is the filename) to the file

the name of the file may undefined until a like servlet has finished its production

meikl ;-)
0
 
Mutley2003Author Commented:
hmm, so how do you suggest I go about processing this?

0
 
Russell LibbySoftware Engineer, Advisory Commented:
Example below

Reagrds,
Russell

----

// uses WinInet

procedure TForm1.Button1Click(Sender: TObject);
var  lpBuffer:      Array [0..4096] of Char;
     hOpen:         HINTERNET;
     hOpenURL:      HINTERNET;
     hFile:         Integer;
     lpszFile:      PChar;
     dwIndex:       DWORD;
     dwSize:        DWORD;
begin

  // Open the connection handle
  hOpen:=InternetOpen('Delphi Agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);

  // Check handle
  if Assigned(hOpen) then
  begin
     // Resource protection
     try
        // Open the URL
        hOpenURL:=InternetOpenUrl(hOpen, 'http://www.censusdata.abs.gov.au/ABSNavigation/download?format=xls&collection=Census&period=2006&productlabel=Ancestry%20by%20Country%20of%20Birth%20of%20Parents&producttype=Census%20Tables&method=Place%20of%20Usual%20Residence&areacode=SSC16003', nil, 0, INTERNET_FLAG_NEED_FILE, 0);
        // Check handle
        if Assigned(hOpenURL) then
        begin
           // Resource protection
           try
              // Set index
              dwIndex:=0;
              // Set size of buffer
              dwSize:=SizeOf(lpBuffer);
              // Query for the content disposition
              if HttpQueryInfo(hOpenURL, HTTP_QUERY_CONTENT_DISPOSITION, @lpBuffer, dwSize, dwIndex) then
              begin
                 // Scan for the filename= in the string
                 dwIndex:=Pos('filename=', lpBuffer);
                 // Check for match
                 if (dwIndex > 0) then
                 begin
                    // Set filename string
                    lpszFile:=@lpBuffer[dwIndex + 8];
                    // Create file with desired name
                    hFile:=FileCreate(lpszFile);
                    // Check handle
                    if not(hFile = (-1)) then
                    begin
                       // Resource protection
                       try
                          // Read from connection and write contents
                          while (InternetReadFile(hOpenURL, @lpBuffer, SizeOf(lpBuffer), dwSize) and (dwSize > 0)) do
                          begin
                             // Write to the file
                             FileWrite(hFile, lpBuffer, dwSize);
                          end;
                       finally
                          // Close the file
                          FileClose(hFile);
                       end;
                    end;
                 end;
              end;
           finally
              // Close handle
              InternetCloseHandle(hOpenURL);
           end;
        end;
     finally
        // Close handle
        InternetCloseHandle(hOpen);
     end;
  end;

end;

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Mutley2003Author Commented:
Hi Russell,
great to hear from you .. I bet that is just what I needed. I will test it in the morning.

Curious about   lpszFile:=@lpBuffer[dwIndex + 8];

Where did you get that offset?

btw, having had the benefit of seeing your code, it gave me some googleideas and I came up with

http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=borland.public.delphi.internet.winsock&messageid=44f5619f$1@newsgroups.borland.com

which some folks might find helpful also.


Curious that
http://msdn2.microsoft.com/en-us/library/ms906347.aspx
says that HTTP_QUERY_CONTENT_DISPOSITION is obsolete.. but I did not see what they suggest instead.

great, I'll test and get back to you.

thanks again.

0
 
Russell LibbySoftware Engineer, Advisory Commented:
Good to hear from you as well, been awhile ;-) As to the q's, the offset of 8 is to account for the "filename=" matching. see below:

          // Scan for the filename= in the string
                 dwIndex:=Pos('filename=', lpBuffer);
                 // Check for match
                 if (dwIndex > 0) then
                 begin
                    // Set filename string
                    lpszFile:=@lpBuffer[dwIndex + 8];

As to it being depricated, that I could not say. But I can tell you what the w3c has to say about it:

<quote>
19.5.1 Content-Disposition
The Content-Disposition response-header field has been proposed as a means for the origin server to suggest a default filename if the user requests that the content is saved to a file. This usage is derived from the definition of Content-Disposition in RFC 1806 [35].

        content-disposition = "Content-Disposition" ":"
                              disposition-type *( ";" disposition-parm )
        disposition-type = "attachment" | disp-extension-token
        disposition-parm = filename-parm | disp-extension-parm
        filename-parm = "filename" "=" quoted-string
        disp-extension-token = token
        disp-extension-parm = token "=" ( token | quoted-string )

An example is

        Content-Disposition: attachment; filename="fname.ext"

The receiving user agent SHOULD NOT respect any directory path information present in the filename-parm parameter, which is the only parameter believed to apply to HTTP implementations at this time. The filename SHOULD be treated as a terminal component only.

If this header is used in a response with the application/octet- stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog.

<end quote>

I have tested the code I posted, so let me know if you run into any problems.

Russell
0
 
Mutley2003Author Commented:
works a treat, thanks Russell
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now