File upload script class
File upload script class
Door Wouter Boevink
en Michiel van Otegem
20 april 2001
You don't need a component to upload files. You can in fact use Request.BinaryRead to read the
entire request as a binary stream and parse it yourself. This however is a
cumbersome task. To make this task as easy as working with a normal form, we
have created a VBScript class that takes care of the complex logic, as a
replacement for Request.Form.
The code below consists of two parts, one being the script class with all the
upload logic. Because it is just script, you don't need to register it on the
server, just upload and use! Also, as it is a script class it works nearly the
same as a normal component.
Wouter wrote all the logic to put the binairy data in the Dictionary object,
which serves as the Request.Form collection. Michiel made the whole thing into a
class for easy use and reusability. The result is the clsFileUpload.asp file at
the bottom, which you need to include in the scripts that do the upload.
Examples
The code below reads the values from the form (including the uploaded file) and
shows the file in the browser (if you do this with an image, your browser will
show the image).
uploadscript1.asp
<%
Option Explicit
Dim oUpload
Set oUpload = New FileUpload
Response.ContentType = oUpload.ContentType("file")
Response.BinaryWrite oUpload.Value("file")
Set oUpload = Nothing
%>
<!--#include file="clsFileUpload.asp"-->
You can also request the values in the form and save the file.
uploadscript2.asp
<%
Option Explicit
Dim oUpload
Dim oFSO, oFile
Dim lngPathEnd
Dim strPath, strFile
Dim i
Set oUpload = New FileUpload
lngPathEnd = Len(Server.MapPath(Request.ServerVariables("PATH_INFO"))) - 14
strPath = Left(Server.Mappath(Request.ServerVariables("PATH_INFO")), lngPathEnd)
strFile = "uploaded" & oUpload.FileName("file")
Set oFSO = Server.CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.CreateTextFile(strPath & strFile)
For i = 1 To LenB(oUpload.Value("file"))
oFile.Write Chr(AscB(MidB(oUpload.Value("file"), i, 1)))
Next
oFile.Close
Set oFile = Nothing
Set oFSO = Nothing
Response.Write "Thank you " & oUpload.Value("name") & ".<br>"
Response.Write "The file has been saved as" & strPath & strFile
Set oUpload = Nothing
%>
<!--#include file="clsFileUpload.asp"-->
You can use the examples with the forms below. Note that the forms specifically
use ENCTYPE="multipart/form-data"
to show that a file is being sent along.
uploadform.asp
<HTML>
<BODY>
<FORM METHOD="Post" ENCTYPE="multipart/form-data" ACTION="uploadscript1.asp">
name: <INPUT TYPE="Text" NAME="name"><BR>
file: <INPUT TYPE="file" NAME="file"><BR>
<INPUT TYPE="submit" Value="Send to uploadscript1.asp">
</FORM>
<HR>
<FORM METHOD="Post" ENCTYPE="multipart/form-data" ACTION="uploadscript2.asp">
name: <INPUT TYPE="Text" NAME="name"><BR>
file: <INPUT TYPE="file" NAME="file"><BR>
<INPUT TYPE="submit" Value="Send to uploadscript2.asp">
</FORM>
</BODY>
</HTML>
clsFileUpload.asp
<%
Class FileUpload
Private pvObjUploadRequest
Private Sub Class_Initialize
Dim RequestBin, Boundary, Value
Dim lngPosBegin, lngPosEnd, lngBoundaryPos
Dim lngPos, lngPosFile, lngPosBound
Dim strName, strFileName, strContentType
Dim objUploadControl
Set pvObjUploadRequest = Server.CreateObject("Scripting.Dictionary")
RequestBin = Request.BinaryRead(Request.TotalBytes)
lngPosBegin = 1
lngPosEnd = InStrB(lngPosBegin, RequestBin, GetByteString(Chr(13)))
Boundary = MidB(RequestBin, lngPosBegin, lngPosEnd - lngPosBegin)
lngBoundaryPos = InStrB(1, RequestBin, Boundary)
Do Until (lngBoundaryPos = InStrB(RequestBin, Boundary & getByteString("--")))
Set objUploadControl = Server.CreateObject("Scripting.Dictionary")
lngPos = InStrB(lngBoundaryPos, RequestBin, GetByteString("Content-Disposition"))
lngPos = InStrB(lngPos, RequestBin, GetByteString("name="))
lngPosBegin = lngPos + 6
lngPosEnd = InStrB(lngPosBegin, RequestBin, GetByteString(Chr(34)))
strName = LCase(GetString(MidB(RequestBin, lngPosBegin, lngPosEnd - lngPosBegin)))
lngPosFile = InStrB(lngBoundaryPos, RequestBin, GetByteString("filename="))
lngPosBound = InStrB(lngPosEnd, RequestBin, Boundary)
If lngPosFile <> 0 And lngPosFile < lngPosBound Then
lngPosBegin = lngPosFile + 10
lngPosEnd = InStrB(lngPosBegin, RequestBin, GetByteString(Chr(34)))
strFileName = GetString(MidB(RequestBin, lngPosBegin, lngPosEnd - lngPosBegin))
objUploadControl.Add "FileName", strFileName
lngPos = InStrB(lngPosEnd, RequestBin, GetByteString("Content-Type:"))
lngPosBegin = lngPos + 14
lngPosEnd = InStrB(lngPosBegin, RequestBin, GetByteString(Chr(13)))
strContentType = GetString(MidB(RequestBin, lngPosBegin, lngPosEnd - lngPosBegin))
objUploadControl.Add "ContentType", strContentType
lngPosBegin = lngPosEnd + 4
lngPosEnd = InStrB(lngPosBegin, RequestBin, Boundary) - 2
Value = MidB(RequestBin, lngPosBegin, lngPosEnd - lngPosBegin)
Else
lngPos = InStrB(lngPos, RequestBin, GetByteString(Chr(13)))
lngPosBegin = lngPos + 4
lngPosEnd = InStrB(lngPosBegin, RequestBin, Boundary) - 2
Value = GetString(MidB(RequestBin, lngPosBegin, lngPosEnd - lngPosBegin))
End If
objUploadControl.Add "Value" , Value
pvObjUploadRequest.Add strName, objUploadControl
lngBoundaryPos = InStrB(lngBoundaryPos + LenB(Boundary), RequestBin, Boundary)
Loop
End Sub
Private Sub Class_Terminate
Dim objDictionary
For Each objDictionary In pvObjUploadRequest.Items
objDictionary.RemoveAll
Set objDictionary = Nothing
Next
pvObjUploadRequest.RemoveAll
Set pvObjUploadRequest = Nothing
End Sub
Private Function GetByteString(strString)
Dim Char
Dim i
For i = 1 To Len(strString)
Char = Mid(strString, i , 1)
GetByteString = GetByteString & ChrB(AscB(Char))
Next
End Function
Private Function GetString(strBin)
|