Problem "pushing" files to the browser as a result of buffer limits when using ASP

Discussion in 'Classic ASP' started by dmoore, Jul 10, 2011.

Thread Status:
Threads that have been inactive for 5 years or longer are closed to further replies. Please start a new thread.
  1. My issue is that when I attempt to push hidden downloads to a client browser, it works fine with smaller (less than a few mb) files but fails when you get to several tens of mb files. In my web searches it appears to be an issue with the buffers in IIS but I can't be sure. Here is a test site that uses the code below: http://www.holidaycoro.com/contentdownload/download.asp

    I'm wondering if there is a way to fix this code, do it another way (ASP .Net?), if there is some component on DiscountASP that will do it (like the upload stuff) or just some other route I need to take when wanting to share large files with customers without presenting the actual download URL to them.

    Thank you,
    David


    <%

    'Constants
    Const FOLDER_PATH="e:\web\<site>\htdocs\ContentDownload\<sub directory>" 'full path to the secure folder
    Const adTypeBinary = 1
    Const adTypeText = 2
    Const chunkSize = 2048

    'global variables:
    Dim strFileName 'name of the file to be downloaded
    Dim blnForceDownload 'force the download or allow the file to be opebed in the browser?

    'read file from querystring:
    strFileName=Request("file")

    'execute the function if we got anything:
    If Len(strFileName)>0 Then
    Call DownloadFile (strFileName)
    Response.END
    End If

    Sub DownloadFile(strFileName)
    'local variables:
    Dim fso, objFile, strFilePath
    Dim fileSize, blnBinary, strContentType
    Dim objStream, strAllFile, iSz
    Dim i

    '----------------------
    'first step: verify the file exists
    '----------------------

    'build file path:
    strFilePath=FOLDER_PATH
    ' add backslash if needed:
    If Right(strFilePath, 1)<>"\" Then strFilePath=strFilePath&"\"
    strFilePath=strFilePath&strFileName

    'initialize file system object:
    Set fso=Server.CreateObject("Scripting.FileSystemObject")

    'check that the file exists:
    If Not(fso.FileExists(strFilePath)) Then
    Set fso=Nothing
    Err.Raise 20000, "Download Manager", "Fatal Error: file does not exist: "&strFilePath
    Response.END
    End If

    '----------------------
    'second step: get file size.
    '----------------------
    Set objFile=fso.GetFile(strFilePath)
    fileSize=objFile.Size
    Set objFile=Nothing

    '----------------------
    'third step: check whether file is binary or not and get content type of the file. (according to its extension)
    '----------------------
    blnBinary=GetContentType(strFileName, strContentType)
    strAllFile=""

    '----------------------
    'forth step: read the file contents.
    '----------------------
    Response.AddHeader "Content-Disposition", "attachment; filename="&strFileName

    If blnBinary Then
    Set objStream=Server.CreateObject("ADODB.Stream")

    'Added to breakup chunk
    'Response.Buffer = False

    'this might be long...
    Server.ScriptTimeout = 10000000



    '----------------------
    objStream.Open
    objStream.Type = 1 'adTypeBinary
    objStream.LoadFromFile strFilePath

    'Added to breakup chunk
    iSz = objStream.Size
    Response.AddHeader "Content-Length", iSz
    'Response.Charset = "UTF-8"
    Response.ContentType = strContentType
    For i = 1 To iSz \ chunkSize
    If Not Response.IsClientConnected Then Exit For
    Response.BinaryWrite objStream.Read(chunkSize)
    Next
    If iSz Mod chunkSize > 0 Then
    If Response.IsClientConnected Then
    Response.BinaryWrite objStream.Read(iSz Mod chunkSize)
    End If
    End If
    objStream.Close
    Set objStream = Nothing
    Else
    Set objFile=fso_OpenTextFile(strFilePath,1) 'forReading
    If Not(objFile.AtEndOfStream) Then
    strAllFile=objFile.ReadAll
    End If
    objFile.Close
    Set objFile=Nothing
    Response.Write(strAllFile)
    End If

    'clean up:
    Set fso=Nothing
    Response.Flush
    Response.END
    End Sub

    Function GetContentType(ByVal strName, ByRef ContentType)
    'return whether binary or not, put type into second parameter
    Dim strExtension
    strExtension="."&GetExtension(strName)
    Select Case strExtension
    Case ".asf"
    ContentType = "video/x-ms-asf"
    GetContentType=True
    Case ".avi"
    ContentType = "video/avi"
    GetContentType=True
    Case ".doc"
    ContentType = "application/msword"
    GetContentType=True
    Case ".zip"
    ContentType = "application/x-msdownload"
    'ContentType = "application/zip"
    GetContentType=True
    Case ".xls"
    ContentType = "application/vnd.ms-excel"
    GetContentType=True
    Case ".gif"
    ContentType = "image/gif"
    GetContentType=True
    Case ".jpg", ".jpeg"
    ContentType = "image/jpeg"
    GetContentType=True
    Case ".wav"
    ContentType = "audio/wav"
    GetContentType=True
    Case ".mp3"
    ContentType = "audio/mpeg3"
    GetContentType=True
    Case ".wma"
    ContentType = "audio/wma"
    GetContentType=True
    Case ".mpg", ".mpeg"
    ContentType = "video/mpeg"
    GetContentType=True
    Case ".pdf"
    ContentType = "application/pdf"
    GetContentType=True
    Case ".rtf"
    ContentType = "application/rtf"
    GetContentType=True
    Case ".htm", ".html"
    ContentType = "text/html"
    GetContentType=False
    Case ".asp"
    ContentType = "text/asp"
    GetContentType=False
    Case ".txt"
    ContentType = "text/plain"
    GetContentType=False
    Case Else
    'Handle All Other Files
    ContentType = "application/octet-stream"
    GetContentType=True
    End Select
    End Function

    Function GetExtension(strName)
    Dim arrTmp
    arrTmp=Split(strName, ".")
    GetExtension=arrTmp(UBound(arrTmp))
    End Function
    %>
     
  2. I do have an ASP.NET method that I worked on with some of the Microsoft devs that you can use to provide D/Ls without giving the direct folder.
    Email me at [email protected] and I'll send you a copy to play with.
    All the best,
    Mark
     
Thread Status:
Threads that have been inactive for 5 years or longer are closed to further replies. Please start a new thread.

Share This Page