freeASPUpload.asp unicode and file overwriting

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • larsjohanson
    New Member
    • Dec 2007
    • 1

    freeASPUpload.asp unicode and file overwriting

    Hello!

    I have used freeASPUpload.a sp (from http://www.freeaspupload.net/ ) to upload files to my server. However, there where two problems:
    1. It doesn't support Unicode (I use UTF-8)
    2. Already existing files are overwritten


    So I made some changes. I would like to submit at least the Unicode part to the authors, but I cannot find out who they are. Does anybody know??

    Any way, I'll just post the code here if someone else runs into the same problem. Changes to the original code:
    • I modified the function String2Byte to support requests made in UTF-8
    • added an internal function GetFileName(str SaveToPath, FileName) that finds out if a file already exists and in that case finds a unique file name
    • added a function "public sub SaveOne(path, num, byref outFileName, byref outLocalFileNam e)" that saves one file (for example number 0 would be the first file in the request) and returns the original filename and the local file name since it may be renamed if the file already exists in the path specified on the server


    So a typical call if you only have uploaded one file might be

    Code:
        Dim Upload, fileName, localFileName, localDocumentPath
    
        localDocumentPath = Server.MapPath("/documents")
        Set Upload = New FreeASPUpload
        Upload.SaveOne localDocumentPath, 0, fileName, localFileName
    I attach the asp-file as .txt
    Attached Files
    Last edited by larsjohanson; Dec 21 '07, 10:41 PM. Reason: Adding a point
  • jhardman
    Recognized Expert Specialist
    • Jan 2007
    • 3405

    #2
    Thanks, Lars,

    I was going to say that it was made by Persits software, but now I think that's a different package.

    Jared

    Comment

    • Sammy07
      New Member
      • Jan 2008
      • 2

      #3
      Originally posted by larsjohanson
      Hello!

      I have used freeASPUpload.a sp (from http://www.freeaspupload.net/ ) to upload files to my server. However, there where two problems:
      1. It doesn't support Unicode (I use UTF-8)
      2. Already existing files are overwritten


      So I made some changes. I would like to submit at least the Unicode part to the authors, but I cannot find out who they are. Does anybody know??

      Any way, I'll just post the code here if someone else runs into the same problem. Changes to the original code:
      • I modified the function String2Byte to support requests made in UTF-8
      • added an internal function GetFileName(str SaveToPath, FileName) that finds out if a file already exists and in that case finds a unique file name
      • added a function "public sub SaveOne(path, num, byref outFileName, byref outLocalFileNam e)" that saves one file (for example number 0 would be the first file in the request) and returns the original filename and the local file name since it may be renamed if the file already exists in the path specified on the server


      So a typical call if you only have uploaded one file might be

      Code:
          Dim Upload, fileName, localFileName, localDocumentPath
      
          localDocumentPath = Server.MapPath("/documents")
          Set Upload = New FreeASPUpload
          Upload.SaveOne localDocumentPath, 0, fileName, localFileName
      I attach the asp-file as .txt

      Hi larsjohanson,

      Pls can you post the new functions you added. GetFileName and public sub SaveOne. I have the same problem of overwriting existing files.

      Thanks

      Comment

      • Sammy07
        New Member
        • Jan 2008
        • 2

        #4
        Hi larsjohanson,

        I have seen the new functions in the ammended code. But it doesn't work. existing files can is still be overwritten when files of the same name are uploaded.

        Is there something am missing?

        Comment

        • kessa
          New Member
          • Feb 2008
          • 2

          #5
          Hi,

          I'm having the same problem and so would like to know how to rename files so that they are unique.

          Also: larsjohanson - I believe this is the website for the guy who created freeaspupload: http://www.mmartins.com/
          Email: (martins@mmartin s.com)

          Cheers,
          Kessa

          Comment

          • markrawlingson
            Recognized Expert Contributor
            • Aug 2007
            • 346

            #6
            I just did this, except I used SoftArtisans FileUp. Should be fairly similar, save for a couple keywords etc.

            I used the File System Object to check to see if the file name which was being uploaded exists already within the folder i'm trying to dump the new file into. If it did, I simply tell the user a file with that name already exists and if they want to upload this file they will need to rename it and try again. I also provided a rename tool right on the website for them to rename any file within their "document bank".

            [code=asp]
            sPath = "/path/to/document/upload/folder/"
            Set oFSO = Server.CreateOb ject("Scripting .FileSystemObje ct")
            Set oFolder = Server.MapPath( sPath )
            Set oFileUp = Server.CreateOb ject("SoftArtis ans.FileUp")
            oFileUp.Path = Server.MapPath( sPath & "documents" )
            For Each oFile In oFolder.Files
            If oFile.Name = oFileUp.FileNam e
            sError = "Sorry, a file with the name " & oFileUp.FileNam e & " already exists. Please rename the file and try to upload the file again."
            End If
            Next
            [/code]

            note that oFileUp.FileNam e is not SoftArtisans FileUp - looking at Free ASP Upload, it looks like this is the way that file names are retrieved with that module but I've never used this module so I can't say for certain.

            The documentation for Free ASP Upload is poor to say the least, so you'll have to play around with it and perhaps find some further examples of their code online.. but a lot of these modules do have overwrite "switches" so perhaps if you can find some good documentation of the methods and properties of this object you may find one, which should provide an easy solution for the problem. For instance, Persits Upload has a method called "OverWriteFiles " - set to false, it will upload the file with a (1) at the end.

            Hope this helps.

            Sincerely,
            Mark

            Comment

            • jakfill
              New Member
              • Oct 2014
              • 1

              #7
              Hi all,

              Has anyone taken larsjohanson's code and modified it for freeasp's multiple file upload? It's working well for one, but on multiple uploads - where attach1, attach2, attach3 & attach4 are in use for example - all files are being uploaded with the returned 'outlocalfilena me' for attach1.

              The necessary code mod is probably staring me in the face, but it's eluded me for 2 days now! Any advice appreciated.

              Jackie

              Comment

              • hb2017
                New Member
                • Jan 2017
                • 1

                #8
                Thanks Lars,

                especially the Unicode part was of high value and it's working perfectly.

                Heinz

                Comment

                • Alan Judin
                  New Member
                  • Jun 2020
                  • 2

                  #9
                  @jhardman Can you help with overwriting a file name with FreeAspUpload

                  Originally posted by hb2017
                  Thanks Lars,

                  especially the Unicode part was of high value and it's working perfectly.

                  Heinz
                  I have tried to use the amended code but still my files gets overwritten

                  Comment

                  • Alan Judin
                    New Member
                    • Jun 2020
                    • 2

                    #10
                    <%
                    ' 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
                    'Sep 3, 2010: Enforce UTF-8 everywhere; new function to convert byte array to unicode string

                    const DEFAULT_ASP_CHU NK_SIZE = 200000

                    const adModeReadWrite = 3
                    const adTypeBinary = 1
                    const adTypeText = 2
                    const adSaveCreateOve rWrite = 2

                    Class FreeASPUpload
                    Public UploadedFiles
                    Public FormElements

                    Private VarArrayBinRequ est
                    Private StreamRequest
                    Private uploadedYet
                    Private internalChunkSi ze

                    Private Sub Class_Initializ e()
                    Set UploadedFiles = Server.CreateOb ject("Scripting .Dictionary")
                    Set FormElements = Server.CreateOb ject("Scripting .Dictionary")
                    Set StreamRequest = Server.CreateOb ject("ADODB.Str eam")
                    StreamRequest.T ype = adTypeText
                    StreamRequest.O pen
                    uploadedYet = false
                    internalChunkSi ze = DEFAULT_ASP_CHU NK_SIZE
                    End Sub

                    Private Sub Class_Terminate ()
                    If IsObject(Upload edFiles) Then
                    UploadedFiles.R emoveAll()
                    Set UploadedFiles = Nothing
                    End If
                    If IsObject(FormEl ements) Then
                    FormElements.Re moveAll()
                    Set FormElements = Nothing
                    End If
                    StreamRequest.C lose
                    Set StreamRequest = Nothing
                    End Sub

                    Public Property Get Form(sIndex)
                    Form = ""
                    If FormElements.Ex ists(LCase(sInd ex)) Then Form = FormElements.It em(LCase(sIndex ))
                    End Property

                    Public Property Get Files()
                    Files = UploadedFiles.I tems
                    End Property

                    Public Property Get Exists(sIndex)
                    Exists = false
                    If FormElements.Ex ists(LCase(sInd ex)) Then Exists = true
                    End Property

                    Public Property Get FileExists(sInd ex)
                    FileExists = false
                    if UploadedFiles.E xists(LCase(sIn dex)) then FileExists = true
                    End Property

                    Public Property Get chunkSize()
                    chunkSize = internalChunkSi ze
                    End Property

                    Public Property Let chunkSize(sz)
                    internalChunkSi ze = 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, filePath

                    if Right(path, 1) <> "\" then path = path & "\"

                    if not uploadedYet then Upload

                    For Each fileItem In UploadedFiles.I tems
                    filePath = path & fileItem.FileNa me
                    Set streamFile = Server.CreateOb ject("ADODB.Str eam")
                    streamFile.Type = adTypeBinary
                    streamFile.Open
                    StreamRequest.P osition=fileIte m.Start
                    StreamRequest.C opyTo streamFile, fileItem.Length
                    streamFile.Save ToFile filePath, adSaveCreateOve rWrite
                    streamFile.clos e
                    Set streamFile = Nothing
                    fileItem.Path = filePath
                    Next
                    End Sub

                    public sub SaveOne(path, num, byref outFileName, byref outLocalFileNam e)
                    Dim streamFile, fileItems, fileItem, fs

                    set fs = Server.CreateOb ject("Scripting .FileSystemObje ct")
                    if Right(path, 1) <> "\" then path = path & "\"

                    if not uploadedYet then Upload
                    if UploadedFiles.C ount > 0 then
                    fileItems = UploadedFiles.I tems
                    set fileItem = fileItems(num)

                    outFileName = fileItem.FileNa me
                    outLocalFileNam e = GetFileName(pat h, outFileName)

                    Set streamFile = Server.CreateOb ject("ADODB.Str eam")
                    streamFile.Type = adTypeBinary
                    streamFile.Open
                    StreamRequest.P osition = fileItem.Start
                    StreamRequest.C opyTo streamFile, fileItem.Length
                    streamFile.Save ToFile path & outLocalFileNam e, adSaveCreateOve rWrite
                    streamFile.clos e
                    Set streamFile = Nothing
                    fileItem.Path = path & filename
                    end if
                    end sub

                    Public Function SaveBinRequest( path) ' For debugging purposes
                    StreamRequest.S aveToFile path & "\debugStream.b in", 2
                    End Function

                    Public Sub DumpData() 'only works if files are plain text
                    Dim i, aKeys, f
                    response.write "Form Items:<br>"
                    aKeys = FormElements.Ke ys
                    For i = 0 To FormElements.Co unt -1 ' Iterate the array
                    response.write aKeys(i) & " = " & FormElements.It em(aKeys(i)) & "<BR>"
                    Next
                    response.write "Uploaded Files:<br>"
                    For Each f In UploadedFiles.I tems
                    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("fi lename=""")
                    tName = String2Byte("na me=""")
                    tContentDisp = String2Byte("Co ntent-Disposition")
                    tContentType = String2Byte("Co ntent-Type:")

                    uploadedYet = true

                    on error resume next
                    ' Copy binary request to a byte array, on which functions like InstrB and others can be used to search for separation tokens
                    readBytes = internalChunkSi ze
                    VarArrayBinRequ est = Request.BinaryR ead(readBytes)
                    VarArrayBinRequ est = midb(VarArrayBi nRequest, 1, lenb(VarArrayBi nRequest))
                    Do Until readBytes < 1
                    tmpBinRequest = Request.BinaryR ead(readBytes)
                    if readBytes > 0 then
                    VarArrayBinRequ est = VarArrayBinRequ est & midb(tmpBinRequ est, 1, lenb(tmpBinRequ est))
                    end if
                    Loop
                    StreamRequest.W riteText(VarArr ayBinRequest)
                    StreamRequest.F lush()
                    if Err.Number <> 0 then
                    response.write "<br><br><B>Sys tem reported this error:</B><p>"
                    response.write Err.Description & "<p>"
                    response.write "The most likely cause for this error is the incorrect setup of AspMaxRequestEn tityAllowed in IIS MetaBase. Please see instructions in the <A HREF='http://www.freeaspuplo ad.net/freeaspupload/requirements.as p'>requirements page of freeaspupload.n et</A>.<p>"
                    Exit Sub
                    end if
                    on error goto 0 'reset error handling

                    nCurPos = FindToken(tNewL ine,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(VarArrayBi nRequest, 1, nCurPos-1)

                    'Start of current separator
                    nDataBoundPos = 1

                    'Beginning of last line
                    nLastSepPos = FindToken(vData Sep & tTerm, 1)

                    Do Until nDataBoundPos = nLastSepPos

                    nCurPos = SkipToken(tCont entDisp, nDataBoundPos)
                    nCurPos = SkipToken(tName , nCurPos)
                    sFieldName = ExtractField(tD oubleQuotes, nCurPos)

                    nPosFile = FindToken(tFile name, nCurPos)
                    nPosBound = FindToken(vData Sep, nCurPos)

                    If nPosFile <> 0 And nPosFile < nPosBound Then
                    Dim oUploadFile
                    Set oUploadFile = New UploadedFile

                    nCurPos = SkipToken(tFile name, nCurPos)
                    auxStr = ExtractField(tD oubleQuotes, 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.Fil eName = Right(auxStr, Len(auxStr)-InStrRev(auxStr , osPathSep))

                    if (Len(oUploadFil e.FileName) > 0) then 'File field not left empty
                    nCurPos = SkipToken(tCont entType, nCurPos)

                    auxStr = ExtractField(tN ewLine, nCurPos)
                    ' NN on UNIX puts things like this in the stream:
                    ' ?? python py type=?? python application/x-python
                    oUploadFile.Con tentType = Right(auxStr, Len(auxStr)-InStrRev(auxStr , " "))
                    nCurPos = FindToken(tNewL ine, nCurPos) + 4 'skip empty line

                    oUploadFile.Sta rt = nCurPos+1
                    oUploadFile.Len gth = FindToken(vData Sep, nCurPos) - 2 - nCurPos

                    If oUploadFile.Len gth > 0 Then UploadedFiles.A dd LCase(sFieldNam e), oUploadFile
                    End If
                    Else
                    Dim nEndOfData, fieldValueUniSt r
                    nCurPos = FindToken(tNewL ine, nCurPos) + 4 'skip empty line
                    nEndOfData = FindToken(vData Sep, nCurPos) - 2
                    fieldValueuniSt r = ConvertUtf8Byte sToString(nCurP os, nEndOfData-nCurPos)
                    If Not FormElements.Ex ists(LCase(sFie ldName)) Then
                    FormElements.Ad d LCase(sFieldNam e), fieldValueuniSt r
                    else
                    FormElements.It em(LCase(sField Name))= FormElements.It em(LCase(sField Name)) & ", " & fieldValueuniSt r
                    end if

                    End If

                    'Advance to next separator
                    nDataBoundPos = FindToken(vData Sep, nCurPos)
                    Loop
                    End Sub

                    Private Function SkipToken(sToke n, nStart)
                    SkipToken = InstrB(nStart, VarArrayBinRequ est, 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 AspMaxRequestEn tityAllowed in IIS MetaBase. Please see instructions in the <A HREF='http://www.freeaspuplo ad.net/freeaspupload/requirements.as p'>requirements page of freeaspupload.n et</A>.<p>"
                    Response.End
                    end if
                    SkipToken = SkipToken + LenB(sToken)
                    End Function

                    Private Function FindToken(sToke n, nStart)
                    FindToken = InstrB(nStart, VarArrayBinRequ est, sToken)
                    End Function

                    Private Function ExtractField(sT oken, nStart)
                    Dim nEnd
                    nEnd = InstrB(nStart, VarArrayBinRequ est, sToken)
                    If nEnd = 0 then
                    Response.write "Error in parsing uploaded binary request."
                    Response.End
                    end if
                    ExtractField = ConvertUtf8Byte sToString(nStar t, nEnd-nStart)
                    End Function

                    'String to byte string conversion
                    Private Function String2Byte(sSt ring)
                    Dim i
                    For i = 1 to Len(sString)
                    String2Byte = String2Byte & ChrB(AscB(Mid(s String,i,1)))
                    Next
                    End Function

                    Private Function ConvertUtf8Byte sToString(start , length)
                    StreamRequest.P osition = 0

                    Dim objStream
                    Dim strTmp

                    ' init stream
                    Set objStream = Server.CreateOb ject("ADODB.Str eam")
                    objStream.Chars et = "utf-8"
                    objStream.Mode = adModeReadWrite
                    objStream.Type = adTypeBinary
                    objStream.Open

                    ' write bytes into stream
                    StreamRequest.P osition = start+1
                    StreamRequest.C opyTo objStream, length
                    objStream.Flush

                    ' rewind stream and read text
                    objStream.Posit ion = 0
                    objStream.Type = adTypeText
                    strTmp = objStream.ReadT ext

                    ' close up and return
                    objStream.Close
                    Set objStream = Nothing
                    ConvertUtf8Byte sToString = strTmp
                    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(name OfFile, "\", "_")
                    nameOfFile = SubstNoReg(name OfFile, "/", "_")
                    nameOfFile = SubstNoReg(name OfFile, ":", "_")
                    nameOfFile = SubstNoReg(name OfFile, "*", "_")
                    nameOfFile = SubstNoReg(name OfFile, "?", "_")
                    nameOfFile = SubstNoReg(name OfFile, """", "_")
                    nameOfFile = SubstNoReg(name OfFile, "<", "_")
                    nameOfFile = SubstNoReg(name OfFile, ">", "_")
                    nameOfFile = SubstNoReg(name OfFile, "|", "_")
                    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(init ialStr, oldStr, newStr)
                    Dim currentPos, oldStrPos, skip
                    If IsNull(initialS tr) 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(currentPo s, 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(str SaveToPath, 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("S cripting.FileSy stemObject")
                    Counter = 0
                    p = instrrev(FileNa me, ".")
                    FileExt = mid(FileName, p+1)
                    strTempFileName = left(FileName, p-1)
                    NewFullPath = strSaveToPath & "\" & FileName
                    Flag = False

                    Do Until Flag = True
                    If objFSO.FileExis ts(NewFullPath) = False Then
                    Flag = True
                    GetFileName = Mid(NewFullPath , InstrRev(NewFul lPath, "\") + 1)
                    Else
                    Counter = Counter + 1
                    NewFullPath = strSaveToPath & "\" & strTempFileName & Counter & "." & FileExt
                    End If
                    Loop
                    End Function

                    %>

                    Comment

                    Working...