Se avete bisogno di sparare il contenuto di un intero file come output ad una richiesta HTTP, nel caso di vecchi script ASP è necessario tenere in considerazione alcune limitazioni:
- Response non è disposto a ricevere stecche di byte troppo grandi (anche attraverso il metodo BinaryWrite)
- Il buffer è acceso per default, quindi la risposta completa potrebbe non gradire "troppi" byte anche durante l'accumulo
Vi consiglio pertanto di procedere in questo modo, se i vostri parametri sono i seguenti:
outFileName è il nome del file che volete che compaia all'utente quando il browser gli chiederà di salvare da qualche parte sul suo disco locale
fileSize è la dimensione in byte del file da travasare
fullPath è il percorso completo nel web server che individua il file da mandare all'utente
Response.Clear()
Response.Buffer = False
Response.AddHeader "Content-Transfer-Encoding", "binary"
Response.AddHeader "Content-Disposition", "attachment; Filename=" & outFileName
Response.AddHeader "Content-Length", CStr(fileSize)
Response.ContentType = "application/octet-stream; name=" & outFileName
AttachFileContentToResponse fullPath
Response.End()
Ora il codice della funzione AttachFileContentToResponse, che non fa altro che attaccare il contenuto del file alla risposta HTTP:
Sub AttachFileContentToResponse(FileName)
Const adTypeBinary = 1
Const clChunkSize = 1048576
Dim oStream, i
Set oStream = Server.CreateObject("ADODB.Stream")
oStream.Type = adTypeBinary
oStream.Open
oStream.LoadFromFile FileName
For i = 1 To oStream.Size \ clChunkSize
Response.BinaryWrite oStream.Read(clChunkSize)
Next
If ((oStream.Size Mod clChunkSize) <> 0) Then
Response.BinaryWrite oStream.Read(oStream.Size Mod clChunkSize)
End If
oStream.Close
End Sub
Sostanzialmente la funzione non fa altro che salvare il contenuto del file in byte "a pezzetti", semplicemente perché Response.BinaryWrite non è in grado di deglutire stecche troppo grosse. Ho letto in giro che IIS Server 6.0/7.0/7.5 ha un limite predefinito di 4 MB, anche se lo potete sapere interrogandolo attraverso la seguente linea di comando:
cscript.exe adsutil.vbs GET w3svc/aspbufferinglimit
Potete comunque modificare tale limite attraverso la SET sullo stesso file adsutil.vbs, collocato generalmente nella cartella ROOTFOLDER/inetpub/AdminScript.
cscript.exe adsutil.vbs SET w3svc/aspbufferinglimit LimitSize
Una piccola finezza che ho curato nel mio script è quella di prendersi cura di specificare la dimensione totale del file in arrivo nell'header della risposta.
Response.AddHeader "Content-Length", CStr(fileSize)
Questa finezza consente al browser del visitatore di poter stimare e visualizzare la progressione del download, perché sa a priori quanti byte arriveranno in totale. Se non si specifica il campo Content-Length, il browser non riuscirà a fare tale stima e l'utente avrà una cattiva esperienza, perché non sa quanto aspettare se il file è di svariati MB.