FTP upload via asp?

Helo all,
well I'm stuck trying to figure out how to allow users to upload large files from within the web site...
Have tried using the standard file upload functions but IIS just pings out like crazy if the file size goes over say 20 megs or so.
I know you can set up FTP through asp as I have seen it done before but I just can't find any documentation on it.

All I need is the code for a file browse and upload using FTP.

Any help is greatly appreciated and I mean it.

Thanks in advance guys.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

You can't. Sorry, but you can't.

Here is the deal. ASP is laid over the top of HTTP. When you go to upload some data (or send any data), you are generally performing an HTTP POST. All interaction in ASP is via HTTP. This means you cannot use FTP. As ASP is a server side language it cannot control FTP on the client.

To get an FTP upload system in place you need to be executing code on the client machine. This means an ActiveX control, or an applet. The process would be something like this:

- Fill in some data in the Applet/control and select a file
- FTP the file to the server
- POST (HTTP) the data to the server and an asp page, including telling the server where to find the file.
- Once the POST is complete the upload is done, so exit the applet/control

I have consistantly run into the same problems and this was the best solution I could come up with. The only problem is it involves a fair bit of work, so I never got around to implementing it.

The other question is what are you using for an upload component?  We used to use ASPSmartUpload, but found it was a real performance hog and have moved to ABCUpload.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Rereading your original post, I realise I was answering a slightly different question. I think all you need is one of the many FTP clients floating around the web. Get clients to install it on their PCs.
WeanerschnitzelAuthor Commented:
no you read it right the first time. I actually wrote a vb app for this but my boss doesn't want to have to email it to everyone...especially since if the ip changes then we have to send out another version of the app...and apparently the general consensus is that our clients are too stupid to have to actually enter an ip address:P

well crapola..yeah I have seen the activeX component options(mostly for sale) and I was afraid that since asp is server side that this would be the problem...but was hoping someone knew some fancy trick around it. now I just have to figure out how to write and activeX component lol
don't suppose you would know how to do that eh?
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

No, sorry. I looked at doing this and decided it was all too hard. I was too lazy :-).

The real problem is that ASP limits you to HTTP and to move to a more reliable protocol means you have to be running client side code.
WeanerschnitzelAuthor Commented:
no you read it right the first time. I actually wrote a vb app for this but my boss doesn't want to have to email it to everyone...especially since if the ip changes then we have to send out another version of the app...and apparently the general consensus is that our clients are too stupid to have to actually enter an ip address:P

well crapola..yeah I have seen the activeX component options(mostly for sale) and I was afraid that since asp is server side that this would be the problem...but was hoping someone knew some fancy trick around it. now I just have to figure out how to write and activeX component lol
don't suppose you would know how to do that eh?
To bottom line it for you, David_Cameron is correct.

ASP uses HTTP whereas FTP uses FTP. HTTP and FTP are two completely different protocols.

What you see when you upload files to third-party servers isn't FTP, I'd imagine the binary data was sent through the browser in these situations - but definately over HTTP.

Bear in mind, HTTP is a protocol designed for images and hypertext (HTML and other plain text formats). Although other files can be supported through this protocol, it really isn't recommended because this is the purpose of FTP (File Transfer Protocol).

Are you trying to address something like what yahoo does for example.
1) Let users browse their file system.
2) Upload it to your server.

YOu can do file uploads over http. But as u say the server activity will be greatly increased for large files. If you can throw lot of hardware at it you are cool.

As far as having to use ip's for ftp servers u can use friendly names instead(http://myftpserver.com:portNo) so u dont have to keep changing ip's.

I almost forgot. There is a dll that you can buy that will let you access the FTP server from that asp and transfer the clients file to your server.

good luck
Hi Weanerschnitzel!

Yes, you cannot use FTP through ASP since it runs on top of HTTP.

BUT, you can make a file selection popup using something like:

<input type="file" id="filecontrol" name="filecontrol">

You can then upload the selected file into a database on your server (preferably SQL server) in a blob datatype field. You can use third party components, or you can write something yourself using the Scripting.Dictionary object. I made it myself easy and copied the code from someone else that provided it freely.

The only problem is that I don't find the original source anymore (it was on the internet). If you think this is what you want, reply here and I'll post my whole code, including the source (and author) of the upload class.

You can use it to write your own mp3 server for example ;-)


WeanerschnitzelAuthor Commented:
I am very interested prohacx. Please share that.
And if this doesn't work then I'll look at a third party add-on as I obviously don't have the skills to build custom dll's yet.

None of this deals with the original problem, that uploading is inefficient and unreliable. It doesn't matter whether you are loading the files into the database or to the file system, uploading with HTTP is slow and inefficient.

Added to that, it is not reccommended that you store BLOBs in the SQL Server. They bloat the database, making it slow, and are harder to manage. The accepted practice is to save the files to disk and store a path in the database.

When using SQL Server there are some things that shouldn't be allowed: cursors, dynamic SQL and storing BLOBS.


The question with this is the level of intergration with ASP code. The problem is that I imagine Weanerschnitzel want to do more than just run an FTP server. That means probably storing some information about the files and providing access to the files via an ASP interface. The second part of that means that at least the minimum requirement is that the asp pages need to know where to find the file. If this tool is no more than an FTP client in an control that is no more useful than say cuteFTP or any other FTP tool. It needs to be able to post some info to an ASP page as well as FTPing the file to the server. Reading the details on this tool, thsi feature doesn't appear in the list.
Hi Weanerschnitzel and David Cameron!

Yes, David is right, uploading over HTTP is not so efficient, but it does work! Storing blobs into a db maybe isn't the best way to go, but sometimes you just do it. We wrote our own internet based frontpage here for example and it combines both: we store asp files in thedb, but to speed things up, we publish them on a webserver so the db is only used for administration. All this just to demonstrate such things are possible.

Anyways, here an example of an ASP page with a file prompt:


<%@ Language=VBScript %>
<%option explicit%>
<%Response.Expires = -1%>



      <title>Upload demo (fileselector.asp)</title>

      <meta http-equiv="expires" content="-1">

      <meta NAME="Author" CONTENT="Maarten De Ridder">
      <meta NAME="Keywords" CONTENT="upload demo">
      <meta NAME="Description" CONTENT="demonstrating how to upload a file over HTTP">


<form id="frmFileUpload" name="frmFileUpload" enctype="multipart/form-data" method="post" action="uploadFile.asp">

      File:<input type="file" id="txtFile" name="txtFile" value="">



And here the page that will do the upload into the DB:


<%@ Language=VBScript %>
<%Option Explicit%>

<!-- #include file="upload.asp" -->


'         OR LATER.

' Create the FileUploader
Dim Uploader, File
Set Uploader = New FileUploader

' This starts the upload process

' Use [FileUploader object].Form to access
' additional form variables submitted with
' the file upload(s). (used below)

' Check if any files were uploaded
If Uploader.Files.Count = 0 Then
      Response.Write "File(s) not uploaded."

      dim objConn
      dim objRs, strSQL
      set objConn = server.CreateObject("ADODB.Connection")

      objConn.Open Application("yourConnectionString")

      ' Loop through the uploaded files
      For Each File In Uploader.Files.Items
            ' Open the table you are saving the file to
            Set objRs = Server.CreateObject("ADODB.Recordset")
            strSQL = "SELECT fileID FROM filesTable WHERE 1=2 "
            objRs.Open strSQL, objConn
            dim actionToDoIsInsert, filterID
            if objRs.EOF then
                  actionToDoIsInsert = true
                  filterID = -1
                  actionToDoIsInsert = false
                  filterID = objRs.Fields("fileID")
            end if
            objRs.Filter = "id = " & filterID
            objRs.CursorLocation = adUseClient
            objRs.Open "filesTable", objConn, 2, 2
            if objRs.EOF then
            end if
            objRs.Fields("fileName") = File.FileName
            objRs.Fields("fileSize") = File.FileSize
            objRs.Fields("fileContentType") = File.ContentType
            ' Save the file to the database
            File.SaveToDatabase objRs.Fields("fileData")
            ' Commit the changes and close
            set objRs = nothing

      set objConn = nothing
End If

set Uploader = nothing

session("remark") = "<li>File uploaded</li>"
session("errorOccured") = false

Response.Redirect "../fileSelector.asp"


All we need now is to give you the include file with the core code (remember, this one is not my own programming work, I don't take any credits for this)


' File:        Upload.asp
' Author: Jacob "Beezle" Gilley
' Email:  avis7@airmail.net
' Date:   12/07/2000
' Comments: The code for the Upload, CByteString,
'                  CWideString      subroutines was originally
'                  written by Philippe Collignon...or so
'                  he claims. Also, I am not responsible
'                  for any ill effects this script may
'                  cause and provide this script "AS IS".
'                  Enjoy!

Class FileUploader
      Public  Files
      Private mcolFormElem

      Private Sub Class_Initialize()
            Set Files = Server.CreateObject("Scripting.Dictionary")
            Set mcolFormElem = Server.CreateObject("Scripting.Dictionary")
      End Sub
      Private Sub Class_Terminate()
            If IsObject(Files) Then
                  Set Files = Nothing
            End If
            If IsObject(mcolFormElem) Then
                  Set mcolFormElem = Nothing
            End If
      End Sub

      Public Property Get Form(sIndex)
            Form = ""
            If mcolFormElem.Exists(LCase(sIndex)) Then Form = mcolFormElem.Item(LCase(sIndex))
      End Property

      Public Default Sub Upload()
            Dim biData, sInputName
            Dim nPosBegin, nPosEnd, nPos, vDataBounds, nDataBoundPos
            Dim nPosFile, nPosBound

            biData = Request.BinaryRead(Request.TotalBytes)
            nPosBegin = 1
            nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))
            If (nPosEnd-nPosBegin) <= 0 Then Exit Sub
            vDataBounds = MidB(biData, nPosBegin, nPosEnd-nPosBegin)
            nDataBoundPos = InstrB(1, biData, vDataBounds)
            Do Until nDataBoundPos = InstrB(biData, vDataBounds & CByteString("--"))
                  nPos = InstrB(nDataBoundPos, biData, CByteString("Content-Disposition"))
                  nPos = InstrB(nPos, biData, CByteString("name="))
                  nPosBegin = nPos + 6
                  nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(34)))
                  sInputName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
                  nPosFile = InstrB(nDataBoundPos, biData, CByteString("filename="))
                  nPosBound = InstrB(nPosEnd, biData, vDataBounds)
                  If nPosFile <> 0 And  nPosFile < nPosBound Then
                        Dim oUploadFile, sFileName
                        Set oUploadFile = New UploadedFile
                        nPosBegin = nPosFile + 10
                        nPosEnd =  InstrB(nPosBegin, biData, CByteString(Chr(34)))
                        sFileName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
                        oUploadFile.FileName = Right(sFileName, Len(sFileName)-InStrRev(sFileName, "\"))

                        nPos = InstrB(nPosEnd, biData, CByteString("Content-Type:"))
                        nPosBegin = nPos + 14
                        nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))
                        oUploadFile.ContentType = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
                        nPosBegin = nPosEnd+4
                        nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2
                        oUploadFile.FileData = MidB(biData, nPosBegin, nPosEnd-nPosBegin)
                        If oUploadFile.FileSize > 0 Then Files.Add LCase(sInputName), oUploadFile
                        nPos = InstrB(nPos, biData, CByteString(Chr(13)))
                        nPosBegin = nPos + 4
                        nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2
                        If Not mcolFormElem.Exists(LCase(sInputName)) Then mcolFormElem.Add LCase(sInputName), CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
                  End If

                  nDataBoundPos = InstrB(nDataBoundPos + LenB(vDataBounds), biData, vDataBounds)
      End Sub

      'String to byte string conversion
      Private Function CByteString(sString)
            Dim nIndex
            For nIndex = 1 to Len(sString)
               CByteString = CByteString & ChrB(AscB(Mid(sString,nIndex,1)))
      End Function

      'Byte string to string conversion
      Private Function CWideString(bsString)
            Dim nIndex
            CWideString =""
            For nIndex = 1 to LenB(bsString)
               CWideString = CWideString & Chr(AscB(MidB(bsString,nIndex,1)))
      End Function
End Class

Class UploadedFile
      Public ContentType
      Public FileName
      Public FileData
      Public Property Get FileSize()
            FileSize = LenB(FileData)
      End Property

      Public Sub SaveToDisk(sPath)
            Dim oFS, oFile
            Dim nIndex
            If sPath = "" Or FileName = "" Then Exit Sub
            If Mid(sPath, Len(sPath)) <> "\" Then sPath = sPath & "\"
            Set oFS = Server.CreateObject("Scripting.FileSystemObject")
            If Not oFS.FolderExists(sPath) Then Exit Sub
            Set oFile = oFS.CreateTextFile(sPath & FileName, True)
            For nIndex = 1 to LenB(FileData)
                oFile.Write Chr(AscB(MidB(FileData,nIndex,1)))

      End Sub
      Public Sub SaveToDatabase(ByRef oField)
            If LenB(FileData) = 0 Then Exit Sub
            If IsObject(oField) Then
                  oField.AppendChunk FileData
            End If
      End Sub

End Class

And to get a file out of the db (do this in a popup window):


<%@ Language=VBScript %>
<%option explicit%>
<%Response.Expires = -1%>


dim strFileID
strFileID = Request.QueryString("fileID")



      server.ScriptTimeout = 1800

      if strFileID = "" then
            Response.Write "File not found<br><br><a href=""javascript: history.go(-1);"">&lt;&lt;&nbsp;back</a>"
      end if
      dim objConn
      dim objRs, strSQL
      set objConn = server.CreateObject("ADODB.Connection")
      set objRs = server.CreateObject("ADODB.Recordset")

      'Get the file out of the DB...
      strSQL = "SELECT fileName, fileSize, fileContentType, fileData FROM filesTable WHERE id = " & strFileID & " "

      objConn.Open Application("yourConnectionString")

      objRs.Open strSQL, objConn ', adOpenForwardOnly, adLockReadOnly, adCmdText

      if not objRs.EOF then
            if not(isnull(objRs.Fields("fileContentType"))) and not(isnull(objRs.Fields("fileData"))) and not(isnull(objRs.Fields("fileName"))) then

                  Response.Buffer = True
                  'Do NOT forget the attachment word since it will cause browsers to
                  'not display the contents of binary files...
                  Response.AddHeader "Content-Disposition","attachment; filename=" & objRs.Fields("fileName")
                  Response.AddHeader "Content-Length", objRs.Fields("fileSize")
                  Response.CharSet = "UTF-8"
                  Response.ContentType = objRs.Fields("fileContentType")

                  dim stm
                  Set stm = server.CreateObject("ADODB.Stream")
                  stm.Type = adTypeBinary
                  stm.Write objRs.Fields("fileData").Value
                  stm.Position = 0
                  Response.BinaryWrite stm.Read
                  set stm = nothing
            end if
      end if
      set objRs = nothing
      set objConn = nothing

That's all folks!

Of course you will have to adapt this code a little bit here and there. Insert your own connectionstring, and use your own table structure, these are just examples. But it is nice to store filenames, lengths, ...

Happy programming!


1) I still agree with David large files over HTTP spells BAD IDEA. (We do it on a very beefy solaris box and still it is very slow. That is why we have FTP.)

2) The ftp tool I suggested will log into the FTP server and alsp give you file listings
Check this link out. http://dotnet.dart.com/ftp/ftp.aspx

Best Regards

And this is different from any normal client FTP program in what way?

So you know that I am not just spouting off, I've spent the last few years working on a project management site where one of the major sections is a document management program. When storing documents people typically want to do more than just store the files. In my case the minimum would be the date stored, the person who stored the document and a list of people notified about the document upload. FTP cannot provide this.

The issue is how to link up this data with an FTP upload. There aren't a while lot of options there and they either involve forcing users into a two step process (please upload the file, then fill out the form), or to running custom code client side.
WeanerschnitzelAuthor Commented:
yeah, nice page Syd108 :)

And yeah HTTP wont work since in many cases the files will be roughly 500 megs to 10 gigs :( can you imagine the IIS timeout settings that would need to be implimented?

probably higher then the max whatever that is(it's not documented anywhere but it's a weird number...had a client set it to like I don't know 20,000 or something once cause she was tired of getting timeouts when running long sql backed .asp pages and fubar'ed the site till we figured out what she had done.)

Wish one of you guys had an example of the client side code...that wouldnt be so bad if it was like an activeX object I could have em just click yes to once...

I'm gonna go ahead and accept the answer that this ain't gonna happen and award the points for that. But if anyone runs across like I said an ActiveX component that can do this let me know I'll start up a different question and make sure you get your props :)

WeanerschnitzelAuthor Commented:
Not what I wanted to hear but it's 100% true so Excellent answer my friend...just wish you'd gotten around to writing that ActiveX component so I could stop lookin ;)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.