Solved

Trying to hide the path to a download file using content-dispostition

Posted on 2004-08-04
27
385 Views
Last Modified: 2008-01-09
Hi,

I'm trying to make a file available for download, but do not want to reveal its absolute path. The following code does work with small files (100K), but fails with anything large:


<%
Response.Expires = 0
if session("username") <> "" then
      Response.ContentType = "application/zip"
      Response.AddHeader "Content-Disposition", "attachment; filename=blah4.zip"
      Session("DL1") = ""
Else
      Response.redirect ("https://dl.company.com/nologin.htm")
End If

%><!-- #INCLUDE FILE = secret/secretfile.zip //-->

Questions:
1) Is there something I'm missing or is there a system limitation?

2) Is this even the right approach? How would i secure files that I don't want the users to have access to, unless they are authenticated?

Thanks.
0
Comment
Question by:kurukken
  • 13
  • 9
  • 4
  • +1
27 Comments
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11721223
This might help you:


<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
<%
Function downloadFile( strFile, strDownloadFilename )
     Dim strFilename,objStream,objFilesystem,objFilestream
     Dim intFileLength
     ' get full path of specified file
     strFilename = Server.MapPath( "../InProgress/Uploads/"  & strFile)
     ' clear the buffer
     Response.Buffer = True
     Response.Clear

     ' create stream
     Set objStream = Server.CreateObject("ADODB.Stream")
     objStream.Open

     ' set as binary
     objStream.Type = 1

     ' check the file exists
     Set objFilesystem = Server.CreateObject("Scripting.FileSystemObject")
     if not objFilesystem.FileExists(strFilename) then
          Response.Write("<h1>Error</h1>: " & strFilename & " does not exist<p>")
          Response.End
     end if


     ' get length of file
     Set objFilestream = objFilesystem.GetFile( strFilename )
     intFilelength = objFilestream.size
 
     objStream.LoadFromFile( strFilename )
     if err then
          Response.Write("<h1>Error: </h1>" & err.Description & "<p>")
          Response.End
     end if
     
     'format strFileName
     if Len( Trim(strDownloadFilename) ) > 0 then
          strDownloadFilename = Trim( strDownloadFilename )
     else
          strDownloadFilename = objFilestream.name
     end if

     ' send the headers to the users browser
     Response.AddHeader "Content-Disposition", "attachment; filename=" & strDownloadFilename
     Response.AddHeader "Content-Length", intFilelength
     Response.Charset = "UTF-8"
     Response.ContentType = "application/octet-stream"

     ' output the file to the browser
     Response.BinaryWrite objStream.Read
     Response.Flush

     ' tidy up
     objFilestream.Close
     Set objFilestream = Nothing
End Function
%>
</HEAD>
<BODY>
<%
Call downloadFile( Replace( Request("FILE") ,"/","\"), Request("FILENAME") )
'Response.Write (Request("FILE")  & "----" & Request("FILENAME") )
%>

</BODY>
</HTML>
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11721234
Just modify this line:

 strFilename = Server.MapPath( "../InProgress/Uploads/"  & strFile)

to match your environment and make sure that the IUSR_ account has Read access to the directory that houses your files.

FtB
0
 
LVL 7

Expert Comment

by:msice
ID: 11721426
To fix the tmeout for large files use <% Server.ScriptTimeout = 700 %>
0
 

Author Comment

by:kurukken
ID: 11721535
Hi,

I gave it a shot and I'm getting:

Error
: D:\WWW\Inetpub\wwwroot\download\temp\test does not exist

The above path does physically exist and iuser account has read and execute privilages.
The asp page resides in the same directory as the "test" directory.

Verified that:
strFilename = Server.MapPath( "test/"  & strFile)

do I have to do anything with the "strFile"? I tried declaring the filename above the code you provided but no dice. Same error.

Then NOW I realized that you gave me a function. Sorry for being a dope, how do I call this function?
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11721868
Yes, you would call it like this:

downloadFile( strFile, strDownloadFilename )

where strFile is the name of the file as it exists on the server and strDownloadFilename is the name that you want your user to see, for example:

downloadFile( "jane's Resume 2.doc", "resume.doc")

FtB
0
 

Author Comment

by:kurukken
ID: 11727229
Hi,

thanks.  Appologies - I'm new to asp. So here's what I did:

<BODY>
<%
Call downloadFile( Replace( Request("FILE") ,"/","\"), Request("FILENAME") )
'Response.Write (Request("FILE")  & "----" & Request("FILENAME") )
downloadFile("the-test-file.exe", "testing.exe")
%>

</BODY>
</HTML>

This time round, i got a:

HTTP 500 - Internal server error
Internet Explorer

So I checked the iis logs and saw this line associated with the asp page:
Cannot_use_parentheses_when_calling_a_sub

which tells me that I'm doing something wrong.

0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11727307
Okay, you're close (just being a little too literal or I was being a little too abstract). Please try this:

<HTML>
<BODY>
<%
call downloadFile("the-test-file.exe", "testing.exe")
%>

</BODY>
</HTML>
0
 

Author Comment

by:kurukken
ID: 11727583
Thanks for your patience.

i think i"m narrowing the problem made that change and now I get this:

Execution of the ASP page caused the Response Buffer to exceed its configured limit.

So, this is now an IIS issue? I've started poking around. Any clues?
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11727613
Okay, this is good. At least now the function appears to be called and it seems to be doing its thing.

Before we chase down the server configuration, would you please try testing with a very small file to make sure that we are hunting down the correct problem?

FtB
0
 

Author Comment

by:kurukken
ID: 11727878
It works with a small file!

Come to think of it, i was getting the same problem with my code above (I like your code better though!)
0
 
LVL 7

Expert Comment

by:msice
ID: 11727888
To fix the tmeout for large files use <% Server.ScriptTimeout = 700 %>
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11727925
I don't know that this is a timeout issue (although it may become one after this issue is set).

Try putting this as the first line on your page:

<%Response.Buffer = False%>
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11727951
@msice--

I see that you have posted that idea twice, and it is a good one for long scripts. The reason why I am not echoing it is because none of the errors indicate a script time out. Now, once we get everything else fixed, the script timeout might become an issue, but I think that these other problems are the real culprit.

Fritz the Blank
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 7

Expert Comment

by:msice
ID: 11727992
It fixed my issue with this same type of error as the file begins to send the page was timing out causing the file not to download.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11728061
But would that throw a " Response Buffer to exceed its configured limit" error?

FtB
0
 

Author Comment

by:kurukken
ID: 11728326
fritz:

While working with the small file, I tried the <%Response.Buffer = False%>, but it conflicted with the line within the function. So I deleted it and turned the one in the function to false and got an internal error.


msice:
i set the time out as you suggested, no luck. I don't think the script is timing out, I think there's some buffer limit that's being exceeded by large files.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11728451
Is there any other code on the page besides this?
0
 

Author Comment

by:kurukken
ID: 11728475
I googled this and found a response:

An ASP application uses internal server buffers when writing data to
the client, irrespective of the value of Response.Buffer. As the
application is writing data synchronously, the data buffer can be
reused when the BinaryWrite function returns, while the server is
writing the data asynchronously to the client. The server, in turn,
makes a copy of the data into its internal buffers. As a result of
this buffering, the ASP application should not try to send
unreasonable amounts of data in a single BinaryWrite, but rather break
it into fragments so as to avoid running out of buffer space. Should
the buffer space be exceeded, ASP error 251, "response exceeds the
buffer limit," will be returned. While the default maximum buffer size
is 4MB, the server administrator may increase it.

The maximum buffer size can be increased by changing the AspBufferingLimit
property.  You can do this by downloading the IIS 6.0 Resource Kit Tools
and change the property using MB Explorer. Here is a link to the IIS 6.0
Resource Kit Tools.

http://www.microsoft.com/downloads/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499&DisplayLang=en

For more information on the AspBufferingLimit property, see the below link.

http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/windowsserver2003/proddocs/standard/ref_mb_aspbufferinglimit.asp


What do you think??
0
 

Author Comment

by:kurukken
ID: 11728482
Just saw your response. I copied your code into a blank page and have been using that for testing. Not modified it except for the path.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11728487
Give it a try....

BTW, did you see my last question? How large is this file?

FtB
0
 

Author Comment

by:kurukken
ID: 11728589
The file is 21267.94KB (21778367 bytes)

I'd rather not muck with the metabase if I can help it. I'm concerned about concurrant downloads of this file. Will it kill the memory on my server if it uses up 21MB for each download?

If you've gotten it to work with a file larger than 4mb without this fix, then I'm going to try your solution first.

0
 
LVL 46

Accepted Solution

by:
fritz_the_blank earned 500 total points
ID: 11728605
I usually use this for resumes and the like. I haven't tried it with files that large....

FtB
0
 
LVL 7

Expert Comment

by:msice
ID: 11728639
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11728863
I thought about that, and mentioned it above, but as kurukken observes, the code requires buffering to be enabled.

FtB
0
 

Author Comment

by:kurukken
ID: 11730028
Tried both. and Yup, it appears that there is a 4 meg limit. I'm now going to look for objects out there that allow me to download files outside the iis webroot.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11730083
there is something about chunking that can deal with this, but I don't remember the details...

FtB
0
 
LVL 9

Expert Comment

by:leechoonhwee
ID: 11732655
You can also do this.

if session("username") <> "" then
    Response.Write("<script>window.open("./path/filename",null,"toolbar=no,menubar=no,location=no")</script>")
Else
     Response.redirect ("https://dl.company.com/nologin.htm")
End If

Just some alternative suggestions. :)
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

I have helped a lot of people on EE with their coding sources and have enjoyed near about every minute of it. Sometimes it can get a little tedious but it is always a challenge and the one thing that I always say is:  The Exchange of information …
Hello, all! I just recently started using Microsoft's IIS 7.5 within Windows 7, as I just downloaded and installed the 90 day trial of Windows 7. (Got to love Microsoft for allowing 90 days) The main reason for downloading and testing Windows 7 is t…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now