|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- <!--METADATA
- TYPE="TypeLib"
- NAME="Microsoft ActiveX Data Objects 2.5 Library"
- UUID="{00000205-0000-0010-8000-00AA006D2EA4}"
- VERSION="2.5"
- -->
-
-
- <%
- ' For examples, documentation, and your own free copy, go to:
- ' http://www.freeaspupload.net
- ' Note: You can copy and use this script for free and you can make changes
- ' to the code, but you cannot remove the above comment.
-
- 'Changes:
- 'Aug 2, 2005: Add support for checkboxes and other input elements with multiple values
- 'Jan 6, 2009: Lars added ASP_CHUNK_SIZE
-
- const DEFAULT_ASP_CHUNK_SIZE = 200000
-
- Class FreeASPUpload
- Public UploadedFiles
- Public FormElements
-
- Private VarArrayBinRequest
- Private StreamRequest
- Private uploadedYet
- Private internalChunkSize
-
- Private Sub Class_Initialize()
- Set UploadedFiles = Server.CreateObject("Scripting.Dictionary")
- Set FormElements = Server.CreateObject("Scripting.Dictionary")
- Set StreamRequest = Server.CreateObject("ADODB.Stream")
- StreamRequest.Type = 2 ' adTypeText
- StreamRequest.Open
- uploadedYet = false
- internalChunkSize = DEFAULT_ASP_CHUNK_SIZE
- End Sub
-
- Private Sub Class_Terminate()
- If IsObject(UploadedFiles) Then
- UploadedFiles.RemoveAll()
- Set UploadedFiles = Nothing
- End If
- If IsObject(FormElements) Then
- FormElements.RemoveAll()
- Set FormElements = Nothing
- End If
- StreamRequest.Close
- Set StreamRequest = Nothing
- End Sub
-
- Public Property Get Form(sIndex)
- Form = ""
- If FormElements.Exists(LCase(sIndex)) Then Form = FormElements.Item(LCase(sIndex))
- End Property
-
- Public Property Get Files()
- Files = UploadedFiles.Items
- End Property
-
- Public Property Get Exists(sIndex)
- Exists = false
- If FormElements.Exists(LCase(sIndex)) Then Exists = true
- End Property
-
- Public Property Get FileExists(sIndex)
- FileExists = false
- if UploadedFiles.Exists(LCase(sIndex)) then FileExists = true
- End Property
-
- Public Property Get chunkSize()
- chunkSize = internalChunkSize
- End Property
-
- Public Property Let chunkSize(sz)
- internalChunkSize = sz
- End Property
-
- 'Calls Upload to extract the data from the binary request and then saves the uploaded files
- Public Sub Save(path)
- Dim streamFile, fileItem
-
- if Right(path, 1) <> "\" then path = path & "\"
-
- if not uploadedYet then Upload
-
- For Each fileItem In UploadedFiles.Items
- Set streamFile = Server.CreateObject("ADODB.Stream")
- streamFile.Type = 1
- streamFile.Open
- StreamRequest.Position=fileItem.Start
- StreamRequest.CopyTo streamFile, fileItem.Length
- streamFile.SaveToFile path & fileItem.FileName, 2
- streamFile.close
- Set streamFile = Nothing
- fileItem.Path = path & fileItem.FileName
- Next
- End Sub
-
- public sub SaveOne(path, num, byref outFileName, byref outLocalFileName)
- Dim streamFile, fileItems, fileItem, fs
-
- set fs = Server.CreateObject("Scripting.FileSystemObject")
- if Right(path, 1) <> "\" then path = path & "\"
-
- if not uploadedYet then Upload
- if UploadedFiles.Count > 0 then
- fileItems = UploadedFiles.Items
- set fileItem = fileItems(num)
-
- outFileName = fileItem.FileName
- outLocalFileName = GetFileName(path, outFileName)
-
- Set streamFile = Server.CreateObject("ADODB.Stream")
- streamFile.Type = 1
- streamFile.Open
- StreamRequest.Position = fileItem.Start
- StreamRequest.CopyTo streamFile, fileItem.Length
- streamFile.SaveToFile path & outLocalFileName, 2
- streamFile.close
- Set streamFile = Nothing
- fileItem.Path = path & filename
- end if
- end sub
-
- Public Function SaveBinRequest(path) ' For debugging purposes
- StreamRequest.SaveToFile path & "\debugStream.bin", 2
- End Function
-
- Public Sub DumpData() 'only works if files are plain text
- Dim i, aKeys, f
- response.write "Form Items:<br>"
- aKeys = FormElements.Keys
- For i = 0 To FormElements.Count -1 ' Iterate the array
- response.write aKeys(i) & " = " & FormElements.Item(aKeys(i)) & "<BR>"
- Next
- response.write "Uploaded Files:<br>"
- For Each f In UploadedFiles.Items
- response.write "Name: " & f.FileName & "<br>"
- response.write "Type: " & f.ContentType & "<br>"
- response.write "Start: " & f.Start & "<br>"
- response.write "Size: " & f.Length & "<br>"
- Next
- End Sub
-
- Public Sub Upload()
- Dim nCurPos, nDataBoundPos, nLastSepPos
- Dim nPosFile, nPosBound
- Dim sFieldName, osPathSep, auxStr
- Dim readBytes, readLoop, tmpBinRequest
-
- 'RFC1867 Tokens
- Dim vDataSep
- Dim tNewLine, tDoubleQuotes, tTerm, tFilename, tName, tContentDisp, tContentType
- tNewLine = String2Byte(Chr(13))
- tDoubleQuotes = String2Byte(Chr(34))
- tTerm = String2Byte("--")
- tFilename = String2Byte("filename=""")
- tName = String2Byte("name=""")
- tContentDisp = String2Byte("Content-Disposition")
- tContentType = String2Byte("Content-Type:")
-
- uploadedYet = true
-
- on error resume next
- readBytes = internalChunkSize
- VarArrayBinRequest = Request.BinaryRead(readBytes)
- VarArrayBinRequest = midb(VarArrayBinRequest, 1, lenb(VarArrayBinRequest))
- for readLoop = 0 to 300000
- tmpBinRequest = Request.BinaryRead(readBytes)
- if readBytes < 1 then exit for
- VarArrayBinRequest = VarArrayBinRequest & midb(tmpBinRequest, 1, lenb(tmpBinRequest))
- next
- if Err.Number <> 0 then
- response.write "<br><br><B>System reported this error:</B><p>"
- response.write Err.Description & "<p>"
- response.write "The most likely cause for this error is the incorrect setup of AspMaxRequestEntityAllowed in IIS MetaBase. Please see instructions in the <A HREF='http://www.freeaspupload.net/freeaspupload/requirements.asp'>requirements page of freeaspupload.net</A>.<p>"
- Exit Sub
- end if
- on error goto 0 'reset error handling
-
- nCurPos = FindToken(tNewLine,1) 'Note: nCurPos is 1-based (and so is InstrB, MidB, etc)
-
- If nCurPos <= 1 Then Exit Sub
-
- 'vDataSep is a separator like -----------------------------21763138716045
- vDataSep = MidB(VarArrayBinRequest, 1, nCurPos-1)
-
- 'Start of current separator
- nDataBoundPos = 1
-
- 'Beginning of last line
- nLastSepPos = FindToken(vDataSep & tTerm, 1)
-
- Do Until nDataBoundPos = nLastSepPos
-
- nCurPos = SkipToken(tContentDisp, nDataBoundPos)
- nCurPos = SkipToken(tName, nCurPos)
- sFieldName = ExtractField(tDoubleQuotes, nCurPos)
-
- nPosFile = FindToken(tFilename, nCurPos)
- nPosBound = FindToken(vDataSep, nCurPos)
-
- If nPosFile <> 0 And nPosFile < nPosBound Then
- Dim oUploadFile
- Set oUploadFile = New UploadedFile
-
- nCurPos = SkipToken(tFilename, nCurPos)
- auxStr = ExtractField(tDoubleQuotes, nCurPos)
- ' We are interested only in the name of the file, not the whole path
- ' Path separator is \ in windows, / in UNIX
- ' While IE seems to put the whole pathname in the stream, Mozilla seem to
- ' only put the actual file name, so UNIX paths may be rare. But not impossible.
- osPathSep = "\"
- if InStr(auxStr, osPathSep) = 0 then osPathSep = "/"
- oUploadFile.FileName = Right(auxStr, Len(auxStr)-InStrRev(auxStr, osPathSep))
-
- if (Len(oUploadFile.FileName) > 0) then 'File field not left empty
- nCurPos = SkipToken(tContentType, nCurPos)
-
- auxStr = ExtractField(tNewLine, nCurPos)
- ' NN on UNIX puts things like this in the stream:
- ' ?? python py type=?? python application/x-python
- oUploadFile.ContentType = Right(auxStr, Len(auxStr)-InStrRev(auxStr, " "))
- nCurPos = FindToken(tNewLine, nCurPos) + 4 'skip empty line
-
- oUploadFile.Start = nCurPos+1
- oUploadFile.Length = FindToken(vDataSep, nCurPos) - 2 - nCurPos
-
- If oUploadFile.Length > 0 Then UploadedFiles.Add LCase(sFieldName), oUploadFile
- End If
- Else
- Dim nEndOfData
- nCurPos = FindToken(tNewLine, nCurPos) + 4 'skip empty line
- nEndOfData = FindToken(vDataSep, nCurPos) - 2
- If Not FormElements.Exists(LCase(sFieldName)) Then
- FormElements.Add LCase(sFieldName), Byte2String(MidB(VarArrayBinRequest, nCurPos, nEndOfData-nCurPos))
- else
- FormElements.Item(LCase(sFieldName))= FormElements.Item(LCase(sFieldName)) & ", " & Byte2String(MidB(VarArrayBinRequest, nCurPos, nEndOfData-nCurPos))
- end if
-
- End If
-
- 'Advance to next separator
- nDataBoundPos = FindToken(vDataSep, nCurPos)
- Loop
- StreamRequest.WriteText(VarArrayBinRequest)
- End Sub
-
- Private Function SkipToken(sToken, nStart)
- SkipToken = InstrB(nStart, VarArrayBinRequest, sToken)
- If SkipToken = 0 then
- Response.write "Error in parsing uploaded binary request. The most likely cause for this error is the incorrect setup of AspMaxRequestEntityAllowed in IIS MetaBase. Please see instructions in the <A HREF='http://www.freeaspupload.net/freeaspupload/requirements.asp'>requirements page of freeaspupload.net</A>.<p>"
- Response.End
- end if
- SkipToken = SkipToken + LenB(sToken)
- End Function
-
- Private Function FindToken(sToken, nStart)
- FindToken = InstrB(nStart, VarArrayBinRequest, sToken)
- End Function
-
- Private Function ExtractField(sToken, nStart)
- Dim nEnd
- nEnd = InstrB(nStart, VarArrayBinRequest, sToken)
- If nEnd = 0 then
- Response.write "Error in parsing uploaded binary request."
- Response.End
- end if
- ExtractField = Byte2String(MidB(VarArrayBinRequest, nStart, nEnd-nStart))
- End Function
-
- 'String to byte string conversion
- Private Function String2Byte(sString)
- Dim i
- For i = 1 to Len(sString)
- String2Byte = String2Byte & ChrB(AscB(Mid(sString,i,1)))
- Next
- End Function
-
- 'Byte string to string conversion
- Private Function Byte2String(bsString)
- Dim i
- dim b1, b2, b3, b4
- Byte2String =""
- For i = 1 to LenB(bsString)
- if AscB(MidB(bsString,i,1)) < 128 then
- ' One byte
- Byte2String = Byte2String & ChrW(AscB(MidB(bsString,i,1)))
- elseif AscB(MidB(bsString,i,1)) < 224 then
- ' Two bytes
- b1 = AscB(MidB(bsString,i,1))
- b2 = AscB(MidB(bsString,i+1,1))
- Byte2String = Byte2String & ChrW((((b1 AND 28) / 4) * 256 + (b1 AND 3) * 64 + (b2 AND 63)))
- i = i + 1
- elseif AscB(MidB(bsString,i,1)) < 240 then
- ' Three bytes
- b1 = AscB(MidB(bsString,i,1))
- b2 = AscB(MidB(bsString,i+1,1))
- b3 = AscB(MidB(bsString,i+2,1))
- Byte2String = Byte2String & ChrW(((b1 AND 15) * 16 + (b2 AND 60)) * 256 + (b2 AND 3) * 64 + (b3 AND 63))
- i = i + 2
- else
- ' Four bytes
- b1 = AscB(MidB(bsString,i,1))
- b2 = AscB(MidB(bsString,i+1,1))
- b3 = AscB(MidB(bsString,i+2,1))
- b4 = AscB(MidB(bsString,i+3,1))
- ' Don't know how to handle this, I believe Microsoft doesn't support these characters so I replace them with a "^"
- 'Byte2String = Byte2String & ChrW(((b1 AND 3) * 64 + (b2 AND 63)) & "," & (((b1 AND 28) / 4) * 256 + (b1 AND 3) * 64 + (b2 AND 63)))
- Byte2String = Byte2String & "^"
- i = i + 3
- end if
- Next
- End Function
- End Class
-
- Class UploadedFile
- Public ContentType
- Public Start
- Public Length
- Public Path
- Private nameOfFile
-
- ' Need to remove characters that are valid in UNIX, but not in Windows
- Public Property Let FileName(fN)
- nameOfFile = fN
- nameOfFile = SubstNoReg(nameOfFile, "\", "_")
- nameOfFile = SubstNoReg(nameOfFile, "/", "_")
- nameOfFile = SubstNoReg(nameOfFile, ":", "_")
- nameOfFile = SubstNoReg(nameOfFile, "*", "_")
- nameOfFile = SubstNoReg(nameOfFile, "?", "_")
- nameOfFile = SubstNoReg(nameOfFile, """", "_")
- nameOfFile = SubstNoReg(nameOfFile, "<", "_")
- nameOfFile = SubstNoReg(nameOfFile, ">", "_")
- nameOfFile = SubstNoReg(nameOfFile, "|", "_")
- End Property
-
- Public Property Get FileName()
- FileName = nameOfFile
- End Property
-
- 'Public Property Get FileN()ame
- End Class
-
-
- ' Does not depend on RegEx, which is not available on older VBScript
- ' Is not recursive, which means it will not run out of stack space
- Function SubstNoReg(initialStr, oldStr, newStr)
- Dim currentPos, oldStrPos, skip
- If IsNull(initialStr) Or Len(initialStr) = 0 Then
- SubstNoReg = ""
- ElseIf IsNull(oldStr) Or Len(oldStr) = 0 Then
- SubstNoReg = initialStr
- Else
- If IsNull(newStr) Then newStr = ""
- currentPos = 1
- oldStrPos = 0
- SubstNoReg = ""
- skip = Len(oldStr)
- Do While currentPos <= Len(initialStr)
- oldStrPos = InStr(currentPos, initialStr, oldStr)
- If oldStrPos = 0 Then
- SubstNoReg = SubstNoReg & Mid(initialStr, currentPos, Len(initialStr) - currentPos + 1)
- currentPos = Len(initialStr) + 1
- Else
- SubstNoReg = SubstNoReg & Mid(initialStr, currentPos, oldStrPos - currentPos) & newStr
- currentPos = oldStrPos + skip
- End If
- Loop
- End If
- End Function
-
- Function GetFileName(strSaveToPath, FileName)
- 'This function is used when saving a file to check there is not already a file with the same name so that you don't overwrite it.
- 'It adds numbers to the filename e.g. file.gif becomes file1.gif becomes file2.gif and so on.
- 'It keeps going until it returns a filename that does not exist.
- 'You could just create a filename from the ID field but that means writing the record - and it still might exist!
- 'N.B. Requires strSaveToPath variable to be available - and containing the path to save to
- Dim Counter
- Dim Flag
- Dim strTempFileName
- Dim FileExt
- Dim NewFullPath
- dim objFSO, p
- Set objFSO = CreateObject("Scripting.FileSystemObject")
- Counter = 0
- p = instrrev(FileName, ".")
- FileExt = mid(FileName, p+1)
- strTempFileName = left(FileName, p-1)
- NewFullPath = strSaveToPath & "\" & FileName
- Flag = False
-
- Do Until Flag = True
- If objFSO.FileExists(NewFullPath) = False Then
- Flag = True
- GetFileName = Mid(NewFullPath, InstrRev(NewFullPath, "\") + 1)
- Else
- Counter = Counter + 1
- NewFullPath = strSaveToPath & "\" & strTempFileName & Counter & "." & FileExt
- End If
- Loop
- End Function
- %>
|