Would you like the ability to transfer files from your ASP app with the greatest of ease? Forget downloading and installing server-side components, forget spending money. Forget inefficient and/or cryptic coding! This article demonstrates how easy it is to embed file transfer functionality into your application. Just for the record, This concoction more or less saved my life at one point, and I presume it will do no less than the same for you.
Contributed by Justin Cook Rating: / 183 January 21, 2004
A general rule to programming is that virtually no problem is unique. To illustrate: some time ago, I was building a content management system in ASP, and came up against what seemed to be a major barrier. I had all my templates working wonderfully on the content staging server, pulling their content from a MySQL database. But the pages could only be served to the World Wide Web in static HTML format, from a UNIX server somewhere in the States. How on Earth could I publish the content statically, and then get them to their host? Quite the conundrum!
I worked out a method to publish the pages, directory structure and all. Who knows, maybe that will be the subject of a future article. This one however, is written for the sole purpose of explaining how the heck I got those HTML files to move.
It was quickly discerned that I’d best use FTP as the protocol by which to transfer the files (wink wink). A quick search on Google informed me that thousands of other developers were discerning the very same thing, and like me, were looking for the way to do it. Most, like me again, do not want to put out money, or install components, for something they believe they should be able to efficiently code by themselves.
So I’m going to show you how I did it!
Goals
It seems that most people have similar goals as me in the FTP via ASP issue (though that’s where the similarities seem to end!). We all have one or more files, sitting in one or more directories, that we need to transfer to one or more hosts, one or more times. Ok, perhaps a confusingly vague sentence. All I’m saying is that we need to transfer a file (one or more…) and that’s all. We don’t need a GUI, a progress bar, a KB/second indicator, a queue, or anything to resume broken downloads. We just want to take a group of 0’s and 1’s at point A, and get them to point B.
So that’s all I’ve built, a plain-vanilla FTP function. You may prefer chocolate, or even strawberry, but I assure you it works perfectly!
Prerequisites
This article assumes a solid grasp on copying & pasting text, a Microsoft Windows environment in which you’re hosting your ASP files, and some good strong coffee (optional).
The reason for the Windows requirement is that we’ll be using the inbuilt ftp.exe, and some Windows shell scripting in your ASP page.
The very first thing I do is create an ftp.asp file, and all the coding will go in there. Then wherever we need to make use of the wonder-function, we just include the page into whatever file we’re working with. (<!--#include virtual="/includes/ftp.asp"--> )
Let’s start working with ftp.asp. First, we declare our variables:
Most of the variable will be set, but are purposefully variable. This is in case we want to use the scrip for more that one host or file, as I will explain later on.
The only constant is COMMAND_FTP. This is to prevent errors, as we should only ever need to use it with the ‘-i’ switch (disables multiple file transfer prompting) and the ‘–s:’ switch (indicates a text file containing the FTP commands).
Here are some initial values for the other variables:
Now these are just the initial settings, preferably set to provide for your most common use within the application. But chances are you will want to make use of FTP for something uncommon, and in that case it would be an absolute pain in the butt to have to duplicate all the code for one use. So, we would quite simply just reset a variable or two after including the page (they are variables after all!). This would not affect the default values anywhere else the page is included. This means that we could bastardize these variants however we chose, and they’d be right back to their glorious selves the next time the page is requested! Here’s an example:
If you were blessed (ok, cursed) to have the insight and perception to understand what I’m thinking this very moment, you’d understand how perplexed I am. See, I’ve been trying - quite unsuccessfully - to think of some rolling way to pronounce FTP. SQL is pronounced ‘sequel’, C# pronounced ‘See Sharp,’ the humor portion of my brain pronounced it comatose, but FTP has nothing. Not ‘efftup’, not ‘fu-tap’, it’s really disconcerting. Or perhaps no one cares as much as I do. That being most probable, let’s forget I mentioned it, and do some coding!
It is our goal to put together some kind of FTP command(s), which we can send to a function by typing something not too dissimilar to FTP( strCommands ). We will deal with the commands later; let’s worry about the function for now.
'===================== Function FTP( strCMD ) '===================== '=== Build a command script, FTPs with it, deletes it Dim objFSO, strFile, objTempFldr, objFile, objRegExp Dim objShell, WSX, ReturnCode, Output, strLog, strErrorLog
Set objFSO = CreateObject("Scripting.FileSystemObject")
set objTempFldr = objFSO.GetSpecialFolder( 2 ) strFile = objFSO.GetTempName
This sets up our File System Object, Finds the system TEMP folder, and generates a random filename. You’re welcome to change whatever portion of this you don’t agree with of course, it’s merely a good suggestion.
strFile
= objTempFldr & "" & strFile & ".ftp" if not objFSO.FileExists( strFile ) then objFSO.CreateTextFile( strFile ) Set objFile = objFSO.OpenTextFile( strFile, 2, True )
So we’ve created and opened the [randomly named] text file. Now we entirely free to begin throwing our FTP (foo-top?) commands into it, provided that they’re in proper formation of course!
objFile
.WriteLine( strUser ) objFile.WriteLine( strPass ) If LocalDir <> "" Then objFile.WriteLine( "lcd " & LocalDir ) If RemoteDir <> "" Then objFile.WriteLine( "cd " & RemoteDir ) objFile.WriteLine( Mode )
At this point we’ve established our operating environment, by use of our very variable variants. Now all that’s left is to tell the function exactly that we want to transfer.
We’ve finished with the .ftp command file, and now we begin our FTP process by creating a Shell object. If you encounter any mysterious errors at this line (Library not registered), it’s a safe bet you don’t have C:winntsystem32wshom.ocx. It is by default registered, but sometimes removed for... security! (Thanks again, Microsoft.) Let’s execute this sucker!
Set objFile = objFSO.OpenTextFile( strLog, 2, True ) objFile.Write( Output.ReadAll() ) objFile.Close() set objFSO = nothing set objFile = nothing
objFSO.DeleteFile strFile, True set objFSO = nothing
So there we have it. We’ve done it this time, we’ve really done it! And we’ve managed to clean up after ourselves too, logging all the actions within ftpErrors.txt and ftpLog.txt. Just in case you’re wondering, your password is not included in the log file, and the script file has been deleted, so you should be safe there.
Now the next little part is somewhat optional. It’s in case you want to be notified immediately upon encountering an error, which most of us do. Of course if you wish to continue in your state of blissful ignorance, that’s entirely your prerogative. But we have the option of searching through our logs for error messages, and here’s how it goes:
If (objRegExp.Test( Output.ReadAll ) = True ) or (objRegExp.Test( ReturnCode.ReadAll ) ) Then ‘on one line FTP = False Else FTP = True End If Set objRegExp = nothing End Function
And that’s that in its entirety. Oh, and just in case you’re wondering what kind of commands the function is looking for, they would resemble:
This concoction more or less saved my life at one point, and I presume it will do no less than the same for you. Feel free to toy with it! If you come up with some cool add-ons (such as a fancy progress bar) let me know. Yes, even though I blatantly stated I have no need for such contrivances. I love pointless, fancy add-ons.
And to quote a wise man: “that’s all I have to say about that”. Serious, I can think of nothing else to add.
Oh wait, except for ummmm, if you think of anything better than foo-top, please pass it on!