Jump to content

Download file from secure location and open in browser


wychegnome

Recommended Posts

I suspect the answer to this is simple - but I cannot find an understandable one in the W3 tutorials or by 'googling'. In order to prevent unauthorised download of files that are intended for 'members only' I have placed them in a 'secure' folder where they cannot be found by normal searches of the web site. And I don't want users or hackers to easily find the pathway to the file's true location by using the path in an anchor reference. I provide a link to the file on a page that is restricted to members only in this form: <a href="securedownload.asp?strFileName=book.pdf" target="_blank">Book</a> The file securedownload.asp contains coding that adds pathway information to the file name and places the precise location including filename of the file to be downloaded in a variable strFileToGet. A second variable strFileToSave simply contains the filename. Then the following code runs and allows the user the choice of opening the file in whatever external software is appropriate for the file, or of saving the file to their computer, using the system generated selection box: call downloadfile(strFileToGet, strFileToSave) sub downloadfile(f, saveas) Response.ContentType = "application/x-msdownload" Response.AddHeader "Content-transfer-encoding", "binary" Response.AddHeader "Content-Disposition", "attachment; filename = "& saveas &"" dim txt, objStream f = server.mappath(f) Set objStream = Server.CreateObject("ADODB.Stream") objStream.Mode = 3 objStream.open objStream.loadfromfile f txt=objStream.readtext(-1) response.binarywrite(txt) objStream.close set objStream=nothing txt=nullend sub Whilst this gives workable results and obtains the desired file I am completely baffled as how to amend the code in the sub-routine so that the file will open in a browser window rather than the open externally or save file process being forced upon the user. The file securedownload.asp contains only code that runs at the server, there being no html code to be sent to the browser. I have tried all sorts of tweaks without success - either the download fails or securedownload.asp is offered to the user as an empty file. Any help will be much appreciated.

Link to comment
Share on other sites

The headers you're sending tell the browser that the file is an unknown type ("application/x-msdownload"), and that it is an attachment. When a browser sees an unknown type it prompts the user to save or open the file. If you want the file to open in the browser you need to send a content type that the browser knows how to handle, like text/html. A PDF file is application/pdf.

Link to comment
Share on other sites

Thank you for responding so promptly. I amended the sub routine to read as follows: sub downloadfile(f, saveas)Response.ContentType = "application/pdf"Response.AddHeader "Content-transfer-encoding", "binary"dim txt, objStreamf = server.mappath(f)Set objStream = Server.CreateObject("ADODB.Stream")objStream.Mode = 3objStream.openobjStream.loadfromfile ftxt=objStream.readtext(-1)response.binarywrite(txt)objStream.closeset objStream=nothingtxt=nullend sub and that downloaded the PDF files without any problem, opening them in the browser as desired. I then tried one or two other combinations of ContentType to check that the same code would download other file types as well. "image/jpeg" produced an error message in Firefox claiming the file contained errors, IE9 just changed the tab colour without explanation or opening the file."application/msword" invites me to save the asp program file instead of the word file, as does "application/rtf". All the files are ok and open correctly with the appropriate application on my PC copy. Again I have tried to extract a solution from the 'jungle' but cannot see why the code only works correctly for PDF files.I have tried removing the line [Response.AddHeader "Content-transfer-encoding", "binary"] but this made no difference to the results. Could I again prevail on you to provide some guidance on what needs changing please. Incidentally, is there a complete list anywhere of the accceptable contenttype combinations possible? Thanks, again.

Link to comment
Share on other sites

The content disposition header includes the filename if you want to use a default filename when they save the file. If that's missing it will use the ASP filename instead, even though it's still sending the Word doc or whatever other file. The content transfer encoding header needs to be binary of you use response.binarywrite. If you use response.write then the encoding won't necessarily be binary. You should be able to find various lists online if you do a search for mime type or content type.

Link to comment
Share on other sites

Once again, thank you for your assistance. I searched for mime type and found the one at this link to be particularly well set out as it lists by file extension: http://www.webmaster-toolkit.com/mime-types.shtml I carried out some more changes to the subroutine and made further tests. One thing the tests revealed is that, on my computer at least, word and rtf documents don't open in the browser because the relevant links have not been embedded in the browser itself. The conclusion I reached, therefore, is that it is only worth opening a limited set of file types that browsers can be reasonably have built in handling for, and force downloads for everything else. I have ended up with the following code in the sub-routine which works: sub downloadfile(f, saveas) dim txt, objStream f = server.mappath(f) Response.ContentType = strContentType If Not blnBinary Then Response.AddHeader "Content-Disposition", "attachment; filename = "& saveas &"" End If Set objStream = Server.CreateObject("ADODB.Stream") objStream.Mode = 3 objStream.open objStream.loadfromfile f txt=objStream.readtext(-1) response.binarywrite(txt) objStream.close set objStream = nothing txt = nullend subFor the benefit of anyone else looking at this item, the variables not obvious from looking at the code are:f = the name of the file to open, complete with its full pathway to the secure directory on the server,saveas = the name of the file that will be used if it is downloaded rather than opening in the browser,strContentType = a string to tell the browser the type of file (examples are "application/pdf", "image/jpg")(for the forced downloads this value is set to "application/x-msdownload" although "application/octet-stream" also works),blnBinary is set to false for (only the) file types we want to download instead of being opened in the browser and is not invoked if blnBinary is set to true. The code works for small files, but not for large ones. I now need to see how to download large files ........

Link to comment
Share on other sites

Following my post earlier today I have found a way round the 4Mb file limit imposed by Microsoft in its IIS. The solution is to set a block size (less than 4Mb!) and then download a block at a time until the entire file is down. Tested up to a download file size of 109Mb and works ok. However, there is time to make the tea (or down a pint) while waiting for the download to finish - and you realise why they call it a while-wend loop!In Firefox I found it necessary to go to tools > options > advanced > network and tick the override automatic cache management as otherwise the download stopped before it was complete - although repeated operations of 'page refresh' would also (eventually) bring the download to a succesful conclusion. Now does anyone know how to show a progress bar while the large file is downloading .................. ?

Link to comment
Share on other sites

The browser should show the progress bar automatically. You can send a content length header to tell the browser how big the file is, so that the browser knows when it is finished and can show the normal progress bar. The value of the content-length header should be the length of the txt variable.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...