Read POSTed Binary File And Write To a New Binary File

1.2k Views Asked by At

I'm creating a web page that will allow user to upload files to the server.

I was able to save the file on the server, but I notice that the office files (e.g. word, excel) are corrupted and can not be opened.

My UI is fairly simple

<form method="post" enctype="multipart/form-data" action="uploadFile.asp">
  <p>Select a file:<br><input type=File size=30 name="file1"></p>
  <input type=submit value="Upload">
</form>

In my uploadFile.asp, I'm using VBScript. I tried to read and write the binary data and write it directly.

Function SaveBinaryData(FileName, ByteArray)
  Const adTypeBinary = 1
  Const adSaveCreateOverWrite = 2

  'Create Stream object
  Dim BinaryStream
  Set BinaryStream = CreateObject("ADODB.Stream")

  'Specify stream type - we want To save binary data.
  BinaryStream.Type = adTypeBinary

  'Open the stream And write binary data To the object
  BinaryStream.Open
  BinaryStream.Write ByteArray

  'Save binary data To disk
  BinaryStream.SaveToFile FileName, adSaveCreateOverWrite
End Function

Dim biData
biData = Request.BinaryRead(Request.TotalBytes)
SaveBinaryData "C:\Uploads\ww.xlsx", biData

Like I mentioned previously, if I upload a excel or word file, the file is corrupted. However, text files will work just fine.

I tried other solutions I found online such as Pure ASP, ShadowUploader, etc, but couldn't find one that work properly, they all result in corrupt file or doesn't upload at all.

How can I get it to work properly so that I can upload binary files such as microsft word or excel?

Any help is appreciated!

2

There are 2 best solutions below

0
On BEST ANSWER

I don't see how your code would work.

Classic ASP has no way accessing uploaded files like ASP.NET (Request.UploadedFiles) so if you don't use a a COM component then you need to read Request.BinaryStream and parse out the contents, which isn't so easy.

There are several Classic ASP scripts that do this and I would suggest you use one of these. I have used several and haven't had any problems. I suggest you try one of the free ones like: http://freevbcode.com/ShowCode.asp?ID=4596

1
On

the form

<form method="post" action="post.asp" enctype="multipart/form-data">
<input type='file' name='blob' size='80' />
</form>

Then the code of post.asp. First of all asp binary code:

Dim folder
folder = "public"

Response.Expires=0
Response.Buffer = TRUE
Response.Clear

Sub BuildUploadRequest(RequestBin)
    PosBeg = 1
    PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13)))
    boundary = MidB(RequestBin,PosBeg,PosEnd-PosBeg)
    boundaryPos = InstrB(1,RequestBin,boundary)
        Do until (boundaryPos=InstrB(RequestBin,boundary & getByteString("--")))
        Dim UploadControl
        Set UploadControl = CreateObject("Scripting.Dictionary")
        'Get an object name
        Pos = InstrB(BoundaryPos,RequestBin,getByteString("Content-Disposition"))
        Pos = InstrB(Pos,RequestBin,getByteString("name="))
        PosBeg = Pos+6
        PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(34)))
        Name = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
        PosFile = InstrB(BoundaryPos,RequestBin,getByteString("filename="))
        PosBound = InstrB(PosEnd,RequestBin,boundary)
            If  PosFile<>0 AND (PosFile<PosBound) Then
            PosBeg = PosFile + 10
            PosEnd =  InstrB(PosBeg,RequestBin,getByteString(chr(34)))
            FileName = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))


            nomefile=filename
            UploadControl.Add "FileName", FileName
            Pos = InstrB(PosEnd,RequestBin,getByteString("Content-Type:"))
            PosBeg = Pos+14
            PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13)))
            ContentType = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
            UploadControl.Add "ContentType",ContentType
            PosBeg = PosEnd+4
            PosEnd = InstrB(PosBeg,RequestBin,boundary)-2
            Value = MidB(RequestBin,PosBeg,PosEnd-PosBeg)
            Else
            Pos = InstrB(Pos,RequestBin,getByteString(chr(13)))
            PosBeg = Pos+4
            PosEnd = InstrB(PosBeg,RequestBin,boundary)-2
            Value = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
        End If
        UploadControl.Add "Value" , Value   
        UploadRequest.Add name, UploadControl   
        BoundaryPos=InstrB(BoundaryPos+LenB(boundary),RequestBin,boundary)
    Loop
End Sub
Function getByteString(StringStr)
 For i = 1 to Len(StringStr)
    char = Mid(StringStr,i,1)
    getByteString = getByteString & chrB(AscB(char))
 Next
End Function
Function getString(StringBin)
 getString =""
 For intCount = 1 to LenB(StringBin)
    getString = getString & chr(AscB(MidB(StringBin,intCount,1))) 
 Next
End Function

byteCount = Request.TotalBytes

RequestBin = Request.BinaryRead(byteCount)
Dim UploadRequest
Set UploadRequest = CreateObject("Scripting.Dictionary")
BuildUploadRequest  RequestBin

Then the code to request.item from form

blob = UploadRequest.Item("blob").Item("Value")

Finally the code to save the file in server. I rename the name's file for not duplicating name and I create an univoque name with the mix of date and time.

contentType = UploadRequest.Item("blob").Item("ContentType")
    filepathname = UploadRequest.Item("blob").Item("FileName")
    filename = Right(filepathname,Len(filepathname)-InstrRev(filepathname,"\"))
    value = UploadRequest.Item("blob").Item("Value")
    Set ScriptObject = Server.CreateObject("Scripting.FileSystemObject")
    arrayFile = split(filename,".")
    estensioneFile = arrayFile(UBound(ArrayFile))
    namefileuploaded = day(date())& month(date()) & year(date())& hour(time())&minute(time())& second(time())&"a."&estensioneFile
    Set MyFile = ScriptObject.CreateTextFile(Server.mappath(folder)&"\"& namefileuploaded)
    For i = 1 to LenB(value)
        MyFile.Write chr(AscB(MidB(value,i,1)))
    Next
    MyFile.Close