kurukken
asked on
Trying to hide the path to a download file using content-dispostition
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.
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.
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
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
To fix the tmeout for large files use <% Server.ScriptTimeout = 700 %>
ASKER
Hi,
I gave it a shot and I'm getting:
Error
: D:\WWW\Inetpub\wwwroot\dow nload\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?
I gave it a shot and I'm getting:
Error
: D:\WWW\Inetpub\wwwroot\dow
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?
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
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
ASKER
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-fil e.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_whe n_calling_ a_sub
which tells me that I'm doing something wrong.
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-fil
%>
</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_whe
which tells me that I'm doing something wrong.
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-fil e.exe", "testing.exe")
%>
</BODY>
</HTML>
<HTML>
<BODY>
<%
call downloadFile("the-test-fil
%>
</BODY>
</HTML>
ASKER
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?
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?
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
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
ASKER
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!)
Come to think of it, i was getting the same problem with my code above (I like your code better though!)
To fix the tmeout for large files use <% Server.ScriptTimeout = 700 %>
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%>
Try putting this as the first line on your page:
<%Response.Buffer = False%>
@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
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
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.
But would that throw a " Response Buffer to exceed its configured limit" error?
FtB
FtB
ASKER
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.
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.
Is there any other code on the page besides this?
ASKER
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??
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??
ASKER
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.
Give it a try....
BTW, did you see my last question? How large is this file?
FtB
BTW, did you see my last question? How large is this file?
FtB
ASKER
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.
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Maybe try setting this to false http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iissdk/iis/ref_mb_aspbufferingon.asp
I thought about that, and mentioned it above, but as kurukken observes, the code requires buffering to be enabled.
FtB
FtB
ASKER
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.
there is something about chunking that can deal with this, but I don't remember the details...
FtB
FtB
You can also do this.
if session("username") <> "" then
Response.Write("<script>wi ndow.open( "./path/fi lename",nu ll,"toolba r=no,menub ar=no,loca tion=no")< /script>")
Else
Response.redirect ("https://dl.company.com/nologin.htm")
End If
Just some alternative suggestions. :)
if session("username") <> "" then
Response.Write("<script>wi
Else
Response.redirect ("https://dl.company.com/nologin.htm")
End If
Just some alternative suggestions. :)
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
<%
Function downloadFile( strFile, strDownloadFilename )
Dim strFilename,objStream,objF
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
objStream.Open
' set as binary
objStream.Type = 1
' check the file exists
Set objFilesystem = Server.CreateObject("Scrip
if not objFilesystem.FileExists(s
Response.Write("<h1>Error<
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:
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>