I have a Classic ASP application which allows users to download excel documents provided by a 3rd party vendor. Below is sample code. If the document size is greater than 4mb, I get an error "Response buffer limit exceeded".
I did some research and tried different things. Only increasing the buffer limit in IIS resolved my issue. But my systems team is reluctant to make this change on production.
Is there an alternate solution? Is there a solution available in ASP.Net?
set objDoc = Server.createobject("Some.Object")
objDoc.DocId doc_id
bin_obj = objDoc.Binary
set objDoc = Nothing
Response.buffer = TRUE
Response.ContentType = "application/msexcel"
Response.AddHeader "Cache-Control", "public"
Response.AddHeader "Pragma", "public"
Response.AddHeader "Content-Disposition", "attachment;filename=test.xls"
Response.BinaryWrite bin_obj
Response.Flush
Response.End
You need push content part by part, ex. by 1Mb per block. If your COM object ("Some.Object") dosn't allow read by block, you can make it using ADODB.Stream object with method stream.Read(count).
UPDATE:
Option Explicit
Dim streamS, streamB
Set streamS = Server.CreateObject("ADODB.Stream")
streamS.Type = 1 'Binary stream
streamS.Open
streamS.LoadFromFile Server.MapPath("/Nissan_Qashqai_IDTR.rar")
Set streamB = Server.CreateObject("ADODB.Stream")
streamB.Type = 1
streamB.Open
Dim blockSize
blockSize = 1024 ' block size is 1 KB
Response.AddHeader "Content-Disposition", "attachment;filename=MyTestBinryFile.bin"
Response.AddHeader "Content-Length", streamS.Size
Response.ContentType = "application/octet-stream"
Dim i
For i = 0 To streamS.Size - 1 Step blockSize
streamB.Position = 0
streamS.CopyTo streamB, blockSize
streamB.Position = 0
Response.BinaryWrite(streamB.Read)
Response.Flush
Next
streamS.Close
Set streamS = Nothing
streamB.Close
Set streamB = Nothing
Response.Flush
Related
In an .asp classic page I´m getting a POST send to me(a JSON string) and it is send in the request.body, says the guy how send it.
But if I just have theresponse=request.form I am not getting anything?
So how do I get the value from a request.body?
Some payment gateway API's I've used in the past have sent responses in this fashion. The data (JSON) is sent as a binary body post.
To read it you need to use Request.BinaryRead with Request.TotalBytes, then use Adodb.Stream to convert the binary to UTF8 text:
Response.ContentType = "application/json"
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "utf-8"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
' You shouldn't really be receiving any posts more than a few KB,
' but it might be wise to include a limit (200KB in this example),
' Anything larger than that is a bit suspicious. If you're dealing
' with a payment gateway the usual protocol is to post the JSON
' back to them for verification before processing.
if Request.TotalBytes > 0 AND Request.TotalBytes <= 200000 then
Dim postBody
postBody = BytesToStr(Request.BinaryRead(Request.TotalBytes))
Response.Write(postBody) ' the JSON... hopefully
end if
I have a website written in Classic ASP
One page creates a .CSV file from a SQL database and stores it in the root directory along with a "Click Here" link to download it to the users PC
It has been working fine for many years and is still working fine when downloading small files, but now it comes up with a "THIS PAGE CAN'T BE DISPLAYED" error when downloading a .csv file (in this example) of some 785 records
The code is pretty short as below with the one Private Sub that does the download
<%#Language="VBScript"%>
<%Reponse.Buffer = True%>
<%
On Error Resume Next
Dim strPath
strPath = CStr(Request.QueryString("File"))
'-- do some basic error checking for the QueryString
If strPath = "" Then
Response.Clear
Response.Write("No file specified.")
Response.End
ElseIf InStr(strPath, "..") > 0 Then
Response.Clear
Response.Write("Illegal folder location.")
Response.End
ElseIf Len(strPath) > 1024 Then
Response.Clear
Response.Write("Folder path too long.")
Response.End
Else
Call DownloadFile(strPath)
End If
Private Sub DownloadFile(file)
'--declare variables
Dim strAbsFile
Dim strFileExtension
Dim objFSO
Dim objFile
Dim objStream
'-- set absolute file location
strAbsFile = Server.MapPath(file)
'-- create FSO object to check if file exists and get properties
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
'-- check to see if the file exists
If objFSO.FileExists(strAbsFile) Then
Set objFile = objFSO.GetFile(strAbsFile)
'-- first clear the response, and then set the appropriate headers
Response.Clear
'-- the filename you give it will be the one that is shown
' to the users by default when they save
Response.AddHeader "Content-Disposition", "attachment; filename=" & objFile.Name
Response.AddHeader "Content-Length", objFile.Size
Response.ContentType = "application/octet-stream"
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
'-- set as binary
objStream.Type = 1
Response.CharSet = "UTF-8"
'-- load into the stream the file
objStream.LoadFromFile(strAbsFile)
'-- send the stream in the response
Response.BinaryWrite(objStream.Read)
objStream.Close
Set objStream = Nothing
Set objFile = Nothing
Else 'objFSO.FileExists(strAbsFile)
Response.Clear
Response.Write("No such file exists.")
End If
Set objFSO = Nothing
End Sub
%>
So something has changed in recent months
Ay advice much appreciated
Thanks in advance
Your IIS version and configuration might be needed to help but I know IIS6 introduced a 4MB limit to BinaryWrite. Try sending your file in chunks instead.
<% Response.Buffer = False %>
...
With Server.CreateObject("ADODB.Stream")
.Open
.Type = 1
.LoadFromFile strPath
' Send 256K chunks...
Const intChunkSize = 262144
Do While Response.IsClientConnected And (.Position < .Size)
Response.BinaryWrite .Read(intChunkSize)
Loop
.Close
End With
I'm creating a download manager, and everything seems to work. But the file that I get downloaded can not be opened. The file has the correct name and the extension .pdf - but my Mac says that the file cannot be opened (the file on the server works).
if request.querystring("downloadFile") <> "" then
strFilePath = Server.MapPath("/_customerFiles/"& session("URLmapping") &"/documents/"& request.querystring("downloadFile"))
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFilePath) Then
Set objFile = objFSO.GetFile(strFilePath)
intFileSize = objFile.Size
Set objFile = Nothing
strFileName = request.querystring("filename")
strFileName = replace(request.querystring("downloadFile")," ","-")
Response.AddHeader "Content-Disposition","attachment; filename=" & strFileName
Response.ContentType = "application/octet-stream"
Response.AddHeader "Content-Length", intFileSize
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1 'adTypeBinary '
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS And Response.IsClientConnected
Response.BinaryWrite objStream.Read(1024)
Response.Flush()
Loop
objStream.Close
Set objStream = Nothing
End if
Set objFSO = Nothing
end if
Have you considered that the output stream is having a Byte Order Mark (BOM) added (or maybe removed)? I would open both files in a hex editor and look for 3 bytes added at the start (and everything else moved along).
I know I'm late getting to this question, but I was just dealing with something similar and wanted share my observations to try to clear it up.
I have read (sorry I dont have a source) that the ADODB.Stream has to have its .Type specified prior to calling .Open
I also set the Stream .Mode property to 3 (meaning "open file for Reading") to prevent file access lock errors if multiple people try to access the file at the same time -- Also must be done before calling .Open
I have had varying success with Response.ContentType "application/octet-stream", and after some problems there, I changed mine to Response.ContentType "xxx/xxx". The browser will accept it as an unknown file type and then prompt the user to open it based on the registered program for that file extension.
Before you start adding Response Headers, you should call Response.Clear (just to be sure you're not sending extra markup)
After closing your FileSystemObject, you should call Response.End (again, just to be sure)
You needs to add the Response.Clear before Response.AddHeader and change the Response.ContentType, so the code is like below:
if request.querystring("downloadFile") <> "" then
strFilePath = Server.MapPath("/_customerFiles/"& session("URLmapping") &"/documents/"& request.querystring("downloadFile"))
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFilePath) Then
Set objFile = objFSO.GetFile(strFilePath)
intFileSize = objFile.Size
Set objFile = Nothing
strFileName = request.querystring("filename")
strFileName = replace(request.querystring("downloadFile")," ","-")
Response.Clear
Response.AddHeader "Content-Disposition","attachment; filename=" & strFileName
Response.ContentType = "xxx/xxx"
Response.AddHeader "Content-Length", intFileSize
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1 'adTypeBinary '
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS And Response.IsClientConnected
Response.BinaryWrite objStream.Read(1024)
Response.Flush()
Loop
objStream.Close
Set objStream = Nothing
End if
Set objFSO = Nothing
End if
I'm trying to create a simple video gallery that pulls the videos from the recorded shows of a specific Ustream user with ASP.net. I've been doing some research and looking at the API Documentation but can't seem to figure it out all example are in PHP.
Can anyone help me on it..if possible then give me some Code or Blogs links for Asp.net with Ustream.
Thanks
Simply! Look here http://msdn.microsoft.com/en-us/library/ms525208(v=vs.90).aspx
You can use ADODB.Stream in Classic ASP (works in ASP.Net too)
Write this in asp:
'Set the content type to the specific type that you are sending.
Response.ContentType = "video/mp4"
Const adTypeBinary = 1
Dim strFilePath
strFilePath = server.mappath("stream.mp4")
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile strFilePath
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
I think this will help you very much.
I am having an issue with writing a file to the response object. The file is Base64 encoded and is being sent to the ASP code via a web service.
dim contentType, fileName
filename = request("FileName")
contentType = request("ContentType")
If Not Response.isClientConnected Then
Response.end
End If
Response.buffer = true
Response.Clear
Response.Addheader "Content-Disposition", "attachment; filename=" & filename
Response.contenttype = contentType
dim oSoapClient
Set oSoapClient = Server.CreateObject("MSSOAP.SoapClient")
oSoapClient.ClientProperty("ServerHTTPRequest") = True
oSoapClient.mssoapinit "http://myWS/test.asmx?WSDL"
dim sRequest, sResponse
sRequest = "<Root><Attachment id=""" & Request("ID") & """/></Root>"
sResponse = oSoapClient.GetAttachment(sRequest)
Dim oXML: Set oXML = LoadXMLString(sResponse)
Dim oAttachment
set oAttachment = oXML.SelectSingleNode("/Root/Attachment")
if not oAttachment is nothing then
Response.Binarywrite(Base64Decode(oAttachment.attributes.getNamedItem("BinaryData").value))
End if
Response.End
The BinaryWrite is adding extra null characters every other byte. Change it to response.write and it does not put the nulls but terminates the string if a null character is found.
I'm looking for a method to use the binarywrite without it adding the extra nulls. Is it a charset issue?
Thanks
BinaryWrite is doing the correct thing here. What is the return type for your Base64Decode function? Extra null characters between every byte are a symptom of improper handling of UTF-16/UCS-16 unicode data.
Ideally, you should send a VARIANT to BinaryWrite that represents an object exposing IStream, or a SAFEARRAY. If you send in a VARIANT that is a string, it will be received by BinaryWrite as a BSTR, which is 16 bits wide and will exhibit nulls/zeroes every other byte for english/latin charset data.