Classic ASP: "Push" File Downloads from A Directory Outside the Application Root
This is some super old code but I used it recently and figured I'd archive it on this site for my future reference. The sample code below aims to allow authenticated users to download files which are not available via direct download (ie. files within the web root). The script accomplishes this by doing the following:
- Check to see if the user is logged in (your method may vary).
 - Set the root directory location.
 - Check to see if the file exists; if so...
 - Retrieve the file size and add the appropriate HTTP headers including content disposition, filename, content type, and file size.
 - Use a binary stream to "push" the download.
 
Save this file as download.asp and call it with the filename in the querystring. Example: https://domain.com/downloads/download.asp?filename=myfile.pdf. Also, be sure to give read permissions to IUSR_SvrName to the root directory. Change the authentication requirements as needed:
 1<%
 2If session("loggedIn") = True Then
 3
 4    strFilePath = "D:\\webfiles\\downloads" & request.querystring("filename")
 5
 6    Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
 7    If objFSO.FileExists(strFilePath) Then
 8        Set objFile = objFSO.GetFile(strFilePath)
 9        intFileSize = objFile.Size
10        Set objFile = Nothing
11
12        strFileName = request.querystring("filename")
13        strFileName = replace(request.querystring("filename")," ","-")
14        Response.AddHeader "Content-Disposition","attachment; filename=" & strFileName
15
16        Response.ContentType = "application/x-msdownload"
17        Response.AddHeader "Content-Length", intFileSize
18
19        Set objStream = Server.CreateObject("ADODB.Stream")
20        objStream.Open
21        objStream.Type = 1 'adTypeBinary
22        objStream.LoadFromFile strFilePath
23
24        Do While Not objStream.EOS And Response.IsClientConnected
25            Response.BinaryWrite objStream.Read(1024)
26            Response.Flush()
27        Loop
28
29        objStream.Close
30        Set objStream = Nothing
31    Else
32        Response.write "Error finding file."
33    End if
34
35    Set objFSO = Nothing
36End If
37%>
Note: Even if the file is a PDF and a third-party application such as Adobe Reader is set to open the file within the browser, the code below will override that and force a download (by using the "application/x-msdownload" content type).
[The UPDATE below is no longer accurate as an alternative solution has been given below in the comments and subsequently, was added to the code (Thanks a bunch, David!). I wanted to leave it for Googlers looking for a solution, however]
UPDATE: Someone wrote to let me know that they were encountering the error "Response Buffer Limit Exceeded". As it turns out, IIS 6's ASPBufferingLimit is set to a measly 4MB (4194304 bits) so any file over 4MB would produce this error. To fix this issue, you will have to have access to IIS either via the command line or the MMC. Here's how to change the buffering limit via the command line:
************ NOTE: An easier solution is to use the updated Do While/Flush procedure given in the code ****************
1cd C:\inetpub\adminscripts
2cscript adsutil.vbs set /w3svc/aspbufferinglimit 4294967295
That's a buffering limit of more than 4 Gigabytes. Personally, I'd lop off the last digit and make that number closer to 430MB. Running that script worked immediately on my test machine, even though I do not have "Enable Direct Metabase Edit" checked in IIS' Properties. If it doesn't work for you, restart IIS and see if it works.