You are here: Home > Articles > Article Display

Downloading any file using ASP, FSO and the ADODB Stream object

In this article, we will see how to allow a user to download any file from our web server. They will see a prompt, giving them the option of opening or saving it, rather than simply opening it which is the default. We can achieve this using the FSO and ADODB objects.

Published: May 8, 2002 | Last Edited: Aug 21, 2005
Tested with: ASP 3.0
Category: ASP
101,010 views

Introduction

In this article, we will see how to allow a user to download any file from our web server. They will see a prompt, giving them the option of opening or saving it, rather than simply opening it which is the default. We can achieve this using the FSO and ADODB objects.

The desired effect

There are times when you want users to download a file instead of opening it up in a browser; like images, text files, ASP code files, MS Office files like Powerpoint or Word files, etc. That's easy to do for a ZIP file for example, but hard with a GIF or TXT. The reason is that anything that the browser recognizes as a valid format, it will open right away without giving you the option to save it. We want the user to receive a prompt though, asking them if they want to save or open the file, like below:

File Download screen capture

We can achieve the above for any file, by simply editing the Response that the browser receives from our web server. By editing the header and the content type, we can prepare the browser to accept binary streams, which would then save as attachments. So, it will always prompt the users to save the content.

ASP Code

1 <%@Language="VBScript"%>
2 <%Option Explicit%>
3 <%Response.Buffer = True%>
4 <%
5 On Error Resume Next
6 Dim strPath
7 strPath = CStr(Request.QueryString("file"))
8 '-- do some basic error checking for the QueryString
9 If strPath = "" Then
10     Response.Clear
11     Response.Write("No file specified.")
12     Response.End
13 ElseIf InStr(strPath, "..") > 0 Then
14     Response.Clear
15     Response.Write("Illegal folder location.")
16     Response.End
17 ElseIf Len(strPath) > 1024 Then
18     Response.Clear
19     Response.Write("Folder path too long.")
20     Response.End
21 Else
22     Call DownloadFile(strPath)
23 End If
24
25 Private Sub DownloadFile(file)
26     '--declare variables
27     Dim strAbsFile
28     Dim strFileExtension
29     Dim objFSO
30     Dim objFile
31     Dim objStream
32     '-- set absolute file location
33     strAbsFile = Server.MapPath(file)
34     '-- create FSO object to check if file exists and get properties
35     Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
36     '-- check to see if the file exists
37     If objFSO.FileExists(strAbsFile) Then
38         Set objFile = objFSO.GetFile(strAbsFile)
39         '-- first clear the response, and then set the appropriate headers
40         Response.Clear
41         '-- the filename you give it will be the one that is shown
42         ' to the users by default when they save
43         Response.AddHeader "Content-Disposition", "attachment; filename=" & objFile.Name
44         Response.AddHeader "Content-Length", objFile.Size
45         Response.ContentType = "application/octet-stream"
46         Set objStream = Server.CreateObject("ADODB.Stream")
47         objStream.Open
48         '-- set as binary
49         objStream.Type = 1
50         Response.CharSet = "UTF-8"
51         '-- load into the stream the file
52         objStream.LoadFromFile(strAbsFile)
53         '-- send the stream in the response
54         Response.BinaryWrite(objStream.Read)
55         objStream.Close
56         Set objStream = Nothing
57         Set objFile = Nothing
58     Else 'objFSO.FileExists(strAbsFile)
59         Response.Clear
60         Response.Write("No such file exists.")
61     End If
62     Set objFSO = Nothing
63 End Sub
64 %>

Copy the code above and save it as download.asp on your web server.

To use this code, you link to the page, passing the location of the file you want to send to the user. For example:
<a href="download.asp?file=/images/xefteri.gif">

The first part of the code does some basic error checking. The sub DownloadFile checks to see if the file is there, and if it is then it sends it as a binary stream using the ADODB Stream object. The header Content-Length is set so that the browser can properly display the progress bar.

Possible issues

If you are trying to stream a file bigger than 4MB, then IIS 6 might send back an error saying something to the sort of "Response Buffer Limit Exceeded". This is a maximum file setting in the web server's metabase, which you can easily fix.

Conclusion

Make sure that you have MDAC 2.5+ installed in order for this to work. It would be very easy to add some security to this code. For example, you could combine your database of content access to it. You would then first check if the users have access to content and if they do, only then proceed to send the file to them.

 



Other articles in this category
  1. Exporting Word files to HTML
    March 5, 2003
    In this article we will first discuss the case for and against using Word as your HTML editor. Then we will see how to properly save a Word file to smaller, more compact HTML files. Third and last, we will see how to do this through code, and possibly create a batch process for converting numerous Word files to HTML at once.
  2. GetRows VBScript Class - Part III: Paging the results
    January 16, 2003
    In Part I of this series, we saw how to create a VBScript class to query our database using the very fast GetRows() method, and return a recordset as a local array. In Part II, we extended the class to allow ADDing and UPDATEing a row in the database. In this Part III, we will expand the class further to allow pagination of the returned recordset.
  3. Dynamic Tree Menu of your site
    May 31, 2002
    We'll see how to create a menu system that is cross-browser and includes all your site's folders/files. It uses ASP, XML and DHTML and by simply copying it to your site you have an instant Windows Explorer-like navigation of the contents.
  4. Generating an XML file of your website's folders/files
    May 24, 2002
    Using the File System Object (FSO) we can traverse through our website's contents and write them out in a nicely nested form in an XML file. We can then use that file for example, in a content management system or a TreeView control.
  5. Calling MS Access Parameterized Queries from ASP
    April 30, 2002
    Instead of passing a SQL query through your ASP code against Microsoft Access as you would normally do, you can use the Queries design interface to create them in Access and then call them from your ASP code. It makes things easier to edit and maintain, and the results are returned faster.