ABCUpload Reference Guide

ABCUpload lets you upload files to Internet Information Server (IIS) using standard HTML forms. ABCUpload offers a number of advanced features such as Pure HTML Progress Bar support, Unicode Compliance, MacBinary Compatible and BLOB Aware. WebSupergoo - sticking the web together.

© 2005 WebSupergoo

Every effort has been made to ensure that the information in this manual is accurate. However WebSupergoo makes no guarantees about the accuracy or quality of this manual or any software it describes.

Windows, Windows NT, Windows 95, Windows 2000, Windows XP, Windows 2003, Internet Information Server, Visual Basic and Visual Studio are trademarks of Microsoft Corporation.


What is ABCUpload?

ABCUpload is an ActiveX component that allows you to upload files from a web browser to your IIS web server. It requires no client side software and operates on the server via standard multipart HTML forms as defined in RFC 1867.

You can use ABCUpload from any Active Server Page (ASP) scripting language that supports the Microsoft ActiveX Scripting interfaces. These include VBScript (Visual Basic Scripting Edition), JScript, PERLScript, PScript, and Python.


Who is this document for?

This document is written as a guide to and reference material for the ABCUpload component. It assumes basic knowledge of Active Server Pages (ASP) and VBScript. It also assumes you know how to set up and configure Microsoft's Internet Information Server (IIS).


What do I need to use it?

At a minimum you need a PC running Windows NT 4.0, Windows 2000, Windows XP, Windows 2003 or later.

A copy of Microsoft's Internet Information Server (IIS) running Active Server Pages (ASP).

Finally you'll need ABCUpload itself.


What's New?

We've done a radical overhaul of the core upload engine. It was always fast and efficient but now it's even more so - if you want to do simultaneous 100 MB uploads you can do them using ABCUpload.

We now support self referential forms. This means you can combine your form and your form processing page into one rather than having one HTML page for the form and one ASP page for the form processing.

We've added support for normal forms as well as the multipart encoded forms that you need for file upload. So you can use ABCUpload throughout your web site whenever you want to reference a form.

We've been working around bugs in international versions of browsers. There's a new CodePage property that allows you to set a default language code for character conversions in cases where no other information is available.

We've updated the version so if you were using a previous version of ABCUpload you will need to change your XForm object creation code to.

Set myForm = Server.CreateObject("ABCUpload4.XForm")

Plus of course we've made lots of other minor improvements that we won't bother you with here.


Pure HTML Progress Bar

File uploads are great because they are so compatible. Because they use standard HTTP virtually every web browser can do them and firewalls don't get in the way. If your user is on a fast connection or is uploading small files the process is instantaneous. You choose a file - you hit submit - your file arrives on the server.

Problems only start to arise when you want to upload large files or your users are on slow connections. When they submit their file it may take seconds or minutes to send to the server. Because browsers don't display progress bars your users may get confused or frustrated and give up rather than completing their upload. The obvious solution to this would be to give the user a dedicated progress bar but using Java or ActiveX brings in all the problems of incompatibility that we were trying to avoid in the first place.

ABCUpload utilizes a Pure HTML Progress Bar. It keeps track of every upload and allows you to watch how much of your file has been uploaded with absolutely no components installed on the client. If you can upload; you can use our progress bar - it's Pure HTML.


Unicode Compliant

The Internet is international. You are as likely to get uploads from people in Japan as you are from people in the United States. Different countries use different character systems and your upload component has to be able to handle both Japanese and English characters.

ABCUpload handles all this for you transparently via Unicode support. For example a visitor uploads a file with a Japanese name - all the file details will arrive intact. You can decide whether you want to convert the name into something more URL friendly or if you want to use the Japanese name or a derivation of it.

Of course ABCUpload isn't specific to Japanese. Unicode covers every character system in the world.


120% MacBinary Compatible

So what is MacBinary and why is important? You have to handle MacBinary to allow uploads from most Macintosh browsers. Many other upload components claim to be able to support MacBinary but their support consists of stripping out what they consider relevant and then throwing away everything else.

So how come we're 120% MacBinary compatible? Well we're the only people to use all the information available. If you upload a Macintosh file to a server running Services for Macintosh (SFM) your Mac file will appear just like it left your client - icons, previews and file name completely intact. We're the only people to do this so we gave ourselves an extra 10%. Additionally while we were doing this we discovered that Internet Explorer sometimes incorrectly codes the MacBinary so we had to read the incorrect file. As this happens about 10% of the time we gave ourselves another 10%. ABCUpload - 120% MacBinary compatible.

So let's be more specific...

Macintosh files are different from Windows or Unix files in three main ways:

  • Every file consists of two separate streams or forks. The data fork holds the basic file information that you would find in a Windows file. The resource fork contains a database of other associated information such as picture previews, notes and icons. So a BMP image might contain the BMP in the data fork and a icon, preview and copyright note in the resource fork.
  • Macintosh files do not contain a file type extension. Instead they have a hidden type and creator code.
  • Macintosh file names can contain almost any character except for the colon character. This means that it is common to have Macintosh files containing slashes, question marks and asterisks.

When Internet Explorer uploads a file from a Macintosh it chooses to put all this information together into one big stream encoded as MacBinary. You can just rip out the data fork and this is what most MacBinary compatible upload components do. However if you do this you loose all sense of what type of file was uploaded (remember it won't have a file name extension) and any other associated information. In particular some types of files such as EPSFs and QuickTime movies can be completely destroyed by this process.

At a basic level we use the creator and type properties to infer the file type. Then we took this one step further. Microsoft has given us the ability to handle this kind of file completely correctly. So if you use ABCUpload to save a MacBinary file to an NTFS formatted disk you can maintain complete integrity of data fork, resource fork, file type and creator. If you look at such a file from Windows it will look like a standard file (e.g. JPEG, DOC etc.) but if you serve this file to Macintosh users using Services for Macintosh (SFM) they will see the original file completely intact.


Microsoft Form Behavior

When we started designing ABCUpload we didn't want to forget that file upload is just another form operation. Microsoft should have supported file upload within their standard Form object. Given that they didn't, our replacement should be as similar as possible to the original, just adding in new file fields in a sensible way. We've been very fussy about this issue because often it's the smallest differences that lead to confusion. There are some surprisingly complicated parts to these seemingly simple objects and many developers cut corners.

So our XForm object is designed to be used in exactly the same way as a standard Request.Form object. Any code you write to access fields within a standard form should transfer directly to accessing fields within a multipart form. Obviously we've had to add some extra functionality to allow special file operations but this is added functionality and doesn't affect the basic operations in any way.

The upshot of this is that it is easy to learn how to use ABCUpload. You can move between standard forms and upload forms with minimal changes in code. For example the following code writes out the contents of all the fields in a form using the standard Microsoft Form object.

Set theForm = Request.Form
For Each Item In theForm
  Response.Write Item & "<br>"
  For Each subitem In theForm(Item)
    Response.Write " - " & subitem & "<br>"
  Next
Next

While the following is the equivalent code using ABCUpload.

Set theForm= Server.CreateObject("ABCUpload4.XForm")
For Each Item In theForm
  Response.Write Item & "<br>"
  For Each subitem In theForm(Item)
    Response.Write " - " & subitem & "<br>"
  Next
Next


BLOB Aware for Database Access

All the data within the upload can be saved to disk but is also available as Binary data for insertion into a database. Binary data is a Variant representation consisting of a SafeArray of Bytes. It is the standard form required for access to BLOB data.


Advanced Technical Design

When we create server side controls we do it properly. We code in Visual C++ under ATL for high speed, minimal dependencies and a small footprint.

ABCUpload is Both threaded which means it runs as both Free threaded and Apartment threaded. Both threading allows the fastest access times possible.

Uploads are only copied to memory when required. This means that even for large uploads ABCUpload will typically use only a small amount of memory. Caching on disk is invisible to the user and uses advanced Windows techniques to ensure that the division of data between disk and memory is handled optimally.

We use Structured Exception Handling and Event Logging throughout. You can also configure ABCUpload to write all VBScript errors to the Event Log if this is required for debugging purposes. In the unlikely event that a internal inconsistency arises the problem will be caught and an error message written to the Application Event Log. If the problem is severe the system will either attempt to recover or abort depending on registry settings and platform.

It is often difficult to isolate misbehaving components within the IIS process and many component developers hide behind this fact. While we don't expect you to have any problems ABCUpload is committed to being a good team member - if it has any problems it will tell you about them.


File Upload Backgrounder

So what is File Upload and how does it work? File Upload or HTTP upload allows your visitors to send files to your web server using standard forms. In the same way that there are form elements that allow you to enter text and others that allow you to choose items from a list there is a form element that allows you to choose a file.

So what does a File Upload form element look like? Well here's a small and non-functional form containing a file input field.

Like many useful elements of HTML, File Upload was not supported in Internet Explorer 3.0 but was soon afterwards added in version 3.02. It is available in Netscape Navigator from version 2.02 onwards. So the great advantage of HTTP upload is that upload facilities are standard on virtually any browser that will come to your web site.

So what does the HTML look like? Well, much like any other piece of form HTML. Here's the code for the above.

<form method="post" action="file-upload-1.htm"
name="submit" enctype="multipart/form-data">
<input type="file" name="fileField"><br><br>
<input type="submit" name="submit" value="submit"><br>
</form>

There are only a couple of real differences. The input type of the upload is 'file' rather than 'text'. The 'enctype' of the form is 'multipart/form-data'. Multipart form data is an Internet standard (covered by RFC 1867) for sending lots of different types of information over the Internet as one bundle.

After the upload form has been submitted to the server we have to get the server to extract the file from the upload. We would expect to be able to do this using standard ASP. Although Microsoft browsers have supported multipart encoding from the moment that Microsoft got interested in the web, the standard form components they supply for web serving do not. This means you have to use a third-party component to do it for you.

When choosing your solution you should bear in mind that file upload is not as simple as it might seem. Just as one example, some browsers encode files before transmitting them! Internet Explorer on MacOS uploads files encoded as MacBinary to allow special Mac specific features to be transmitted. While Mac browsers will normally make up only 10% of your visitors, you should bear in mind your audience. In some picture related industries like publishing you may find that this proportion approaches 100%.

A related issue is that you can't really rely on either the file name or the mime type of the file as provided to you. Because of the cross platform nature of the industry a text file may be named 'readme' or 'readme.txt' or even 'readme 10\10\99'. Because the mime type is determined by the browser it could be anything from 'text/plain' to 'application/x-macbinary' to something completely meaningless. You have to make decisions on a case by case basis depending on what you are trying to do.

ABCUpload is designed to work around these problems invisibly so that you don't have to worry about them.


Event Logging

ABCUpload uses the Application Event Log to report important information.

  • When the component is successfully registered or unregistered it will report this via an information event.
  • If VBScript error logging is enabled (see Registry Settings) these will be logged as warnings.
  • Serious errors or inconsistencies in the environment will be logged as errors.

For example if the component is unable to create a temporary file for caching uploads it will log an error "Unable to create Binary Read Cache". This kind of error will affect server performance but is not fatal.


Script Settings

A number of ASP settings become very relevant when performing uploads. These can be changed using IIS settings or by editing the registry or IIS Metabase. However it is often easier and safer to alter them using the simple scripting commands given here.

The script time-out refers to the number of seconds an Active Server Page is given before the script is assumed to have failed and the page terminated. If you are uploading a large file the script that is receiving the transfer may time out before the file has been completely uploaded. To alter this setting you should insert the following code into your uploading page prior to creating any ABCUpload objects.

Server.ScriptTimeout = 300 ' five minutes

The session time-out is similar to the script time-out but refers to the number of minutes before the user session is aborted. Again if a large file is being uploaded it is desirable to maintain the session state. The session time-out should always be longer than the script time-out. Note that this value is only relevant if you have session state enabled. To alter this setting you should insert the following code into your uploading page prior to creating any ABCUpload objects.

Session.Timeout = 20 ' twenty minutes

The UploadReadAheadSize property determines the number of bytes a Web server will read into a buffer and pass to IIS. For large uploads a greater value may increase the speed of uploads at the cost of increased memory use. This can be altered within the IIS Metabase using Microsoft MetaEdit which is supplied as part of the Windows Resource Kits. If you are not familiar with the IIS Metabase and MetaEdit we suggest you do not alter this value.


Registry Settings

A number of ABCUpload settings can be overridden using settings in the registry. If you are not familiar with the precautions you should take when using RegEdit we suggest you do not change these settings.

Key Name | Type
LogErrors | DWORD
AutoRecover | DWORD
EnableImpersonation | DWORD
ReadChunkSize | DWORD

All ABCUpload keys are stored under the following Registry Path.

HKEY_LOCAL_MACHINE\SOFTWARE\WebSupergoo\ABCUpload\4.0

If LogErrors is set to 1 then all VBScript errors raised will also be put into the Application Event Log.

The AutoRecover key determines what happens if a potentially fatal error is caught. By default we automatically recover if running on Windows NT 4.0 since the alternative is to stop the entire web server. On Windows 2000 we stop the web server because we know that Reliable Restart will handle the problem. You can override this behavior by altering the AutoRecover key. Setting it to 1 will always attempt to automatically recover. Whatever action is taken an error will be logged in the Application Event Log.

We consider impersonation such a security risk that we ship ABCUpload with impersonation disabled. If you wish to enable it you must do so via the EnableImpersonation registry key. This should be set to 1.

The ReadChunkSize determines how much upload data is read at one time. It effectively determines the granularity of the progress bar. Smaller values allow greater precision in keeping track of progress but place a greater overhead on the server. The default value is 2048 (0x0800) bytes which means that the progress bar will increment in chunks 2 KB in size.


Manual Installation

Under most circumstances you will want to install ABCUpload using the standard installer and register it using the ABCSettings control panel.

Occasionally you may wish to install ABCUpload manually. To do this you will need the files listed below. We suggest that all DLLs are installed in the System32 directory.

File Name Notes
ABCUpload4.dll

The core DLL used by ASP.

Because the DLL is a COM component it needs to be registered using regsvr32 or equivalent. It can also be registered using MTS or Component Services.
ABCUploadUtils4.dll

A utilities DLL for licensing ABCUpload.

Because the DLL is a COM component it needs to be registered using regsvr32 or equivalent. It can also be registered using MTS or Component Services.

This DLL is only required for entering a license key. If you do not enter a license key then the ABCUpload installation will expire after 30 days. After entering a license key this DLL can be unregistered and removed if required.

To enter a license key create a simple VBS script. Copy the following into a text file and then rename the file mytest.vbs.

Set st = CreateObject("ABCUploadUtils4.Settings")
MsgBox "Current License: " & st.License
st.License = "change this text to your key"
MsgBox "New License: " & st.License

Double click on the script to run it.


Troubleshooting

We don't expect you to have any problems with our software but if you do we offer a full level of support as standard. However if you need an extra level of security we offer a Platinum Level Support program offering a priority channel through to our engineers.

Your first port of call should be to check out the FAQ on our website. If it doesn't cover your particular query please mail us. We prefer queries via email as technical issues are often complicated and require some thought on our side as well as yours. However if you need to telephone then numbers are listed on our web site.

Remember to tell us what Operating System you're on and what version of ABCUpload you're using. You can get the exact version of ABCUpload by getting properties on the ABCUpload4.DLL file.

If the problem is occurring in code you've written we'll probably start by asking you if it occurs in the example web pages which were installed with ABCUpload. This is so we can separate out installation and configuration issues from coding issues. You may wish to try the example pages out so that you can tell us in advance. Just create a new virtual directory and select the folder which contains the example code.

Please give us a precise description of what's gone wrong. If something's working partially please tell us what parts are working and what parts are not. If you have any theories or suspicions about what's going on please do tell us. Also tell us about any unusual software or configuration that might be relevant.

If the problem appears to be due to a corrupt or nonstandard upload you may wish to save a dump of the upload using the XForm.Save method and then send it through to us for analysis.


Basic Upload Example

Basic Upload

This example shows how a basic upload works.
HTML
basicupload.htm

To start with you need an HTML form with a file field in it. Note that only multipart forms support file upload - hence enctype="multipart/form-data". If you try to upload a file from a form that isn't multipart encoded you will not receive any data. This page submits data to basicupload.asp.

<html>
<body>
<form method="post" action="basicupload.asp" enctype="multipart/form-data">
<input type="file" name="filefield"><br>
<input type="submit" name="submit" value="submit">
</form>
<body>
</html>

ASP
basicupload.asp

The Active Server Page simply creates an XForm object and saves the uploaded file out as myupload.dat.

By default the filename is virtual - a URL relative to the current page - so the file will be saved in the same directory as the basicupload pages. You can specify absolute pathnames if you set the XForm AbsolutePathname property to True.

Before we save we set the XForm Overwrite property to True. This ensures that we overwrite any existing file we may have previously uploaded. We also check that the user has selected a file to upload.

<% @Language="VBScript" %>
<%
Set theForm = Server.CreateObject("ABCUpload4.XForm")
theForm.Overwrite = True
If theForm.Files("filefield").FileExists Then
   theForm.Files("filefield").Save "myupload.dat"
End If
%>
<html>
<body>
File uploaded...
</body>
</html>


Two Image Upload Example

Two Image Upload

This example shows how to upload two image files.
HTML
imageupload.htm

All we need is a multipart HTML form with two file fields in it. This page submits data to imageupload.asp.

<html>
<body>
<form method="post" action="imageupload.asp" enctype="multipart/form-data">
<input type="file" name="image1"><br>
<input type="file" name="image2"><br>
<input type="submit" name="submit" value="submit">
</form>
<body>
</html>
ASP
imageupload.asp

We create an XForm object and specify some preferences. By default ABCUpload will throw an error if you try to overwrite a file that already exists. This is done for safety reasons but is not always the behavior we desire. To force ABCUpload to overwrite any files that already exist we set the Overwrite property of the XForm object to True.

As a shortcut we create a reference to the image field and store it in a variable called theField. Now we can use this as shorthand to check each of the fields. Each field is checked. If a file has been uploaded then it is saved out. This avoids saving zero length files in cases where no file was uploaded by the client.

Note that we preserve the original name of the file as uploaded from the client. The FileName property of the XField object is a URL safe version of the original client file name.

<% @Language="VBScript" %>
<%
Set theForm = Server.CreateObject("ABCUpload4.XForm")
theForm.Overwrite = True
Set theField = theForm.Files("image1")
If theField.FileExists Then theField.Save theField.FileName
Set theField = theForm.Files("image2")
If theField.FileExists Then theField.Save theField.FileName
%>
<html>
<body>
Images uploaded...
</body>
</html>


Mixed Field Upload Example

Mixed Field Upload

This example shows how to upload a form containing a mix of standard form and file input fields.
HTML
mixedupload.htm

Our multipart HTML form contains one file field and an assortment of other fields. It asks the visitor to upload their favorite picture, type in the name of their favorite color and click a number of checkboxes to choose what kinds of ice cream they like. This page then submits data to mixedupload.asp.

<html>
<body>
<form method="post" action="mixedupload.asp" enctype="multipart/form-data">
What is your favorite picture?<br>
<input type="file" name="file"><br>
What is your favorite color?<br>
<input type="text" name="color" value="purple"><br>
What types of ice cream do you like?<br>
<input type="checkbox" name="flavor" value="chocolate">Chocolate<br>
<input type="checkbox" name="flavor" value="butterscotch">Butterscotch<br>
<input type="checkbox" name="flavor" value="vanilla">Vanilla<br>
<input type="submit" name="submit" value="submit">
</form>
<body>
</html>
ASP
mixedupload.asp

We create an XForm object. To start with we want to report the color that our visitor chose. We simply reference our XForm object, passing in the name of the field we want.

Next we want to write out the flavors chosen. Because all the checkboxes have the same name we have to loop through all the fields named "flavor" getting the value of each and writing it out.

Finally we deal with the file upload. If a file was uploaded we save it into a directory called "images" (the virtual path is relative to the location of the current page). We use the FileName property to give it a URL safe name, identical or similar to the original name of the file.

<% @Language="VBScript" %>
<html>
<body>
<%
Set theForm = Server.CreateObject("ABCUpload4.XForm")

Response.Write "Your favorite color is "
Response.Write theForm("color") & "<br>"

Response.Write "You like these types of ice cream<br>"
For i = 1 to theForm("flavor").Count
  Response.Write theForm("flavor")(i) & "<br>"
Next

Set theField = theForm.Files("file")
If theField.FileExists Then
  theField.Save "images/" & theField.FileName
  Response.Write "File " & theField.FileName & " uploaded"
Else
  Response.Write "No file uploaded"
End If
%>
</body>
</html>


Upload to File Server Example

Upload to File Server

This example shows how to upload a file to a file server preserving any Macintosh or Unicode attributes of the original file.
HTML
sfmupload.htm

Our multipart HTML form contains one file field for upload. This page then submits data to sfmupload.asp.

<html>
<body>
<form method="post" action="sfmupload.asp" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" name="submit" value="submit">
</form>
<body>
</html>
ASP
sfmupload.asp

We create an XForm object and tell it that we will be using absolute pathnames rather than virtual ones. If a file has been uploaded we save it out to an absolute path that we specify. Here we are using SafeFileName to name the file - this is a Windows safe version of the original file name in Unicode format.

If the file came from a Macintosh the SafeFileName will contain the name of the file converted into the format used by Windows NT Services For Macintosh (SFM). If the file was uploaded by Internet Explorer and is saved to a SFM volume Macintosh users will see a file identical to the original uploaded file with both resource and data forks intact.

<% @Language="VBScript" %>
<html>
<body>
<%
Set theForm = Server.CreateObject("ABCUpload4.XForm")
theForm.AbsolutePath = True
Set theField = theForm.Files("file")
If theField.FileExists Then
  theField.Save "C:\" & theField.SafeFileName
  Response.Write "File uploaded..."
Else
  Response.Write "No file uploaded..."
End If
%>
</body>
</html>


Pure HTML Progress Bar Upload Example

Pure HTML Progress Bar Upload

This example shows how to show a Pure HTML Progress Bar during an upload.

Please note that iIf you have ASP script debugging enabled the progress bar will not work. When debugging is enabled the script engine locks IIS down to one page at a time per session. This means that the progress bar cannot update. So if you want the progress bar to work you need to disable debugging.
HTML
progressupload.htm

Our multipart HTML form contains one file field for upload. When the form is submitted we will need to submit both the data in the main window and also spawn off a separate window to track progress. So instead of using a standard submit button we have to use a normal button with a client side JavaScript action attached to it.

When the submit button is clicked the DoUpload client side function takes over. It creates a unique ID which will be used to identify the transfer. It spawns a progress window (progressbar.asp) and puts the ID into the URL so that it can be retrieved using QueryString. Finally it submits the form to progressupload.asp, again putting the ID into the URL so that it is easily available via QueryString.

This is an unusual use of HTTP and worth reiterating. The progressbar.asp page has an ID supplied to it via the URL (i.e. a GET request). The progressupload.asp page has the content of the form submitted to it via a standard POST and also has an ID supplied via the URL.

<html>
<body>

<script language="javascript">
<!--
function DoUpload() {
  theFeats =   "height=120,width=500,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no";
  theUniqueID = (new Date()).getTime() % 1000000000;
  window.open("progressbar.asp?ID=" + theUniqueID, theUniqueID, theFeats);
  document.myform.action = "progressupload.asp?ID=" + theUniqueID;
  document.myform.submit();
}
//-->
</script>

<form name="myform" method="post" action="progressupload.asp" enctype="multipart/form-data">
<input type="file" name="filefield1"><br>
<input type="button" name="dosubmit" value="Upload" OnClick="DoUpload()"><br>
</form>

</body>
</html>

ASP
progressupload.asp

The upload page is simple. First we set some preferences such as the ScriptTimeOut to avoid IIS timing out long uploads. However the key aspect of this page is that before we reference any fields we set the XForm ID to the one supplied to us in the URL. This ID will be used by the XForm object to log the progress of the upload as data is received.

<%
Response.Expires = -10000
Server.ScriptTimeOut = 300

Set theForm = Server.CreateObject("ABCUpload4.XForm")
theForm.Overwrite = True
theForm.MaxUploadSize = 8000000
theForm.ID = Request.QueryString("ID")
Set theField = theForm.Files("filefield1")
If theField.FileExists Then
  theField.Save theField.FileName
End If
%>

<html>
<body>
Upload Complete...
</body>
</html>

ASP
progressbar.asp

The progress bar is slightly more complicated.

Because data will be being uploaded at the same time as the progress bar page is being refreshed we have to disable session state via an ASP processing directive on the first line.

We insert meta-tags to ensure that the page refreshes itself every couple of seconds. We create an XProgress object and set the ID to the unique ID we were passed in the URL. This synchronizes the XProgress object with the matching XForm object.

We want to close the progress window once the transfer has been completed so we put in a simple piece of client side JavaScript to do this. The rest of the form simply reports to the user the information retrieved via the XProgress object. The progress bar itself is simply a table containing a colored cell of a particular width.

<%@EnableSessionState=False%>
<html>
<head>
<title>Progress...</title>
<meta http-equiv="expires" content="Tue, 01 Jan 1981 01:00:00 GMT">
<meta http-equiv=refresh content="2,progressbar.asp?ID=<%=Request.QueryString("ID")%>">

<%
On Error Resume Next
Set theProgress = Server.CreateObject("ABCUpload4.XProgress")
theProgress.ID = Request.QueryString("ID")
%>

<script language="javascript">
<!--
if (<% =theProgress.PercentDone %> == 100) top.close();
//-->
</script>

</head>
<body bgcolor="#CCCCCC">

<table border="0" width="100%">
<tr>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>Uploading:</b></font></td>
</tr>
<tr bgcolor="#999999">
<td>
<table border="0" width="<%=theProgress.PercentDone%>%" cellspacing="1" bgcolor="#0033FF">
<tr>
<td><font size="1">&nbsp;</font></td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table border="0" width="100%">
<tr>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="1">Estimated time left:</font></td>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="1">
<%=Int(theProgress.SecondsLeft / 60)%> min
<%=theProgress.SecondsLeft Mod 60%> secs
(<%=Round(theProgress.BytesDone / 1024, 1)%> KB of
<%=Round(theProgress.BytesTotal / 1024, 1)%> KB uploaded)</font></td>
</tr>
<tr>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="1">
Transfer Rate:</font></td>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="1">
<%=Round(theProgress.BytesPerSecond/1024, 1)%> KB/sec</font></td>
</tr>
<tr>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="1">Information:</font></td>
<td><font face="Verdana, Arial, Helvetica, sans-serif" size="1"><%=theProgress.Note%></font></td>
</tr>
</table>
</td>
</tr>
<tr></tr>
</table>

</body>
</html>


Upload to Database Example

Upload to Database

This example shows how to upload an image and insert it into a database.
HTML
dbupload.htm

Our multipart HTML form contains one file field for upload.

<html>
<body>
<form method="post" action="dbupload.asp" enctype="multipart/form-data">
<input type="file" name="filefield"><br>
<input type="submit" name="submit" value="submit">
</form>
<body>
</html>

ASP
dbupload.asp

We installed SQLServer 7 on our CC2 server. We created a database called "mydbase" and inserted a table called "mytable" with an Image column called "myimage". Finally we created a user "myuser" with password "password" and read/write access to the database.

In the code below we first check to see that an image file has been uploaded. If it has we connect to the database and then open a RecordSet. We add a new record and put the field data from the upload into the "myimage" column. Finally we update the RecordSet and close our connection.

<% @Language="VBScript" %>
<%
Set theForm = Server.CreateObject("ABCUpload4.XForm")
Set theField = theForm("filefield")(1)

If theField.FileExists and theField.ImageType <> 0 Then
  Set cn = Server.CreateObject("ADODB.Connection")
  theConn = "Provider=SQLOLEDB;Data Source=CC2;Initial Catalog=mydbase;User Id=myuser;Password=password"
  cn.Open theConn
  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.Open "mytable", cn, 1, 3
  rs.AddNew
  rs("myimage").Value = theField.Data
  rs.Update
  rs.Close
  cn.Close
End If

%>
<html>
<body>
File uploaded...
</body>
</html>


Single Page Upload

This example shows how to combine the form and form processing pages into one.
ASP
selfref.asp

This page contains both the upload form and the form upload processing routines. The first time the page is visited no file will be saved because no data has been posted - hence the item count is zero. When the submit button is pressed the page will post the contents to itself and this time a file will be saved.

<% @Language="VBScript" %>
<%
Set theForm = Server.CreateObject("ABCUpload4.XForm")
If theForm.Count > 0 Then
  theForm.Overwrite = True
  Set theField = theForm.Files("filefield")
  If theField.FileExists Then
    theField.Save "myupload.dat"
  End If
End If
%>
<html>
<body>
<form method="post" action="selfref.asp" enctype="multipart/form-data">
<input type="file" name="filefield"><br>
<input type="submit" name="submit" value="submit">
</form>
<body>
</html>


XForm Object

This object is an upload capable replacement for the standard Microsoft Request.Form object. It handles forms encoded in multipart format as defined in RFC 1867.

Method | Description
Read | Read in raw uploaded data from a file.
Save | Save the raw uploaded data.
SetUser | Impersonate a different user.

Property | Default | Description
Files | No | A collection of all the file upload fields.
Item | Yes | A set of fields referenced by name or number.
Count | No | The number of field sets available.
ID | No | The form unique ID.
AbsolutePath | No | Whether to use absolute or virtual paths.
Overwrite | No | Whether to overwrite existing files.
MaxUploadSize | No | The maximum size of uploads to allow.
User | No | The current identity being used by ABCUpload.
Domain | No | The domain which the user belongs to.
CodePage | No | The character set codepage to use.
Multipart | No | Whether multipart data was submitted.
Streams | No | Whether to use NTFS streams.
Form | No | A reference to this XForm object.


Read Method

Allows you to read in raw uploaded data from a file.
Syntax

XForm.Read inPathString
Notes

You are only likely to use this method for debugging. It allows you to read raw upload data saved in a file rather than getting the data posted from a form. This allows you to recreate an upload with all files and form contents intact.

Whether the path is treated as a virtual path or an absolute path is determined by the AbsolutePath property.
See Also

Save method. AbsolutePath property.


Save Method

Allows you to save the raw uploaded data.

Syntax

XForm.Save inPathString
Notes

You are only likely to use this method for debugging. It allows you to save out the raw data as uploaded by the browser. You can then use the Read method to recreate the upload at a later date complete with all files and form contents intact.

Whether the path is treated as a virtual path or an absolute path is determined by the AbsolutePath property.

Whether other files are automatically overwritten is determined by the Overwrite property.
See Also

Read method. AbsolutePath property. Overwrite property.


SetUser Method

Allows you to impersonate a different user.
Syntax

XForm.SetUser inName, inPassword [,inDomain ]
Notes

To determine what resources are accessible to IIS and ASP every session runs in a security context. This context is a particular user impersonated by IIS (typically IUSR_machinename). SetUser allows you to impersonate a different user so that you can access resources in a different context.

Impersonation is a security risk so we recommend avoiding it if possible. Indeed we consider it such a security risk that we ship ABCUpload with impersonation disabled. If you wish to enable it you must enable it via a registry key (see registry keys for details). Impersonation is also difficult to configure correctly so if you must use it we recommend running your virtual directory in the IIS Process (Low Application Protection).

For further details of Windows security see Microsoft's "Windows NT Security". If you want to run IIS in an isolated process see "Server Reliability Through Process Isolation". Please note that security works differently when running in an isolated process. This is fully covered in the above articles.

If you have problems configuring impersonation you should bear in mind that the Microsoft recommended solution to this is to create a Microsoft Transaction Server (MTS) or COM+ package to host ABCUpload. This will handle the security context switching for you.

The user you are trying to impersonate must have the privilege 'Log on as a batch job'. If you try to impersonate and do not have the correct privileges you will receive one of these errors:

A required privilege is not held by the client. (1314)
Access is denied. (5)

When your virtual directory is running in the IIS Process (Low Application Protection) IIS runs as SYSTEM and then impersonates the Anonymous User. You can change the identity of the Anonymous User but it is typically IUSR_machinename.

When your virtual directory is running at part of MTS or COM+ (Medium - Pooled or High - Isolated Application Protection) it will run as IWAM_machinename and again impersonate the IUSR_machinename user.

On Windows NT 4 the IUSR_machinename user does not have the privileges to do impersonation. On Windows 2000 neither the IUSR_machinename nor the IWAM_machinename has the required privileges. To enable impersonation ABCUpload must drop back into the base user (SYSTEM or IWAM_machinename).

Under Windows NT 4.0

You will be able to impersonate if you do not have "Run in separate memory space" checked. If you do have this option checked you must enable "Act as Part of Operating System" for the IWAM_machinename user.

Under Windows 2000

You will be able to impersonate if your Application Protection is set to Low. If your Application Protection is set to Medium or High you will not be able to impersonate.

To change user privileges on Windows NT 4.0

  1. Open "User Manager" in "Administrative Tools"
  2. Choose "User Rights" from the "Policies" Menu
  3. You many need to check "Show Advanced User Rights"
  4. Change user rights as required
  5. After changing User Rights we advise rebooting

To change user privileges on Windows 2000

  1. Open "Local Security Settings"
  2. Select "Local Policies/User Rights Assignment"
  3. Double click on the required policy
  4. Add or remove users as appropriate
  5. After changing User Rights we advise rebooting

If you need to change back to the IUSR_machinename after impersonating another user you should do so by calling SetUser again. You will need to obtain the Anonymous User name and password from the Metabase. Note that you must be impersonating a user such as SYSTEM which has access to the Metabase.

Set theObj = GetObject("IIS://LocalHost/W3SVC")
theUser = theObj.Get("AnonymousUserName")
thePass = theObj.Get("AnonymousUserPass")
theForm.SetUser theUser , thePass

See Also

User property. Domain property.


Files Property

Type | Default Value | Read Only | Description
Variant | N/A | Yes | A collection of all the file upload fields.
Notes

The Files property contains a collection of all the file upload fields from the current form. Items within the collection can be referenced by name or number. Each item is an XField object.

Note that this collection contains all file input fields. If your client did not select a file to upload, some of these fields may be empty. You can use the XField.FileExists property to check whether a file was selected or not.

Saving an uploaded file

Given the following form.

<form method="post" action="myup.asp"
              enctype="multipart/form-data">
<input type="file" name="upload"><br>
<input type="submit" name="submit" value="submit">
</form>

You might use the following code to save your uploaded file.

Set theForm = Server.CreateObject("ABCUpload4.XForm")
If theForm.Files("upload").FileExists Then
theForm.Overwrite = True ' overwrite existing files
theForm.AbsolutePath = True ' save using
              absolute path
theForm.Files("upload").Save "c:\upload.dat"
End If

Saving all uploaded files

If you are uploading multiple files you might like to save them using a slightly different method. Given the following form.

<form method="post" action="myup.asp"
              enctype="multipart/form-data">
<input type="file" name="upload_1"><br>
<input type="file" name="upload_2"><br>
...
<input type="file" name="upload_N"><br>
<input type="submit" name="submit" value="submit">
</form>

You might use the following code ...

Set theForm = Server.CreateObject("ABCUpload4.XForm")
theForm.Overwrite = True ' overwrite existing files
For Each theFile in theForm.Files
  If theFile.FileExists Then
    ' save in virtual directory
    theFile.Save theFile.SafeFileName
  End If
Next

Or alternatively ...

Set theForm = Server.CreateObject("ABCUpload4.XForm")
theForm.Overwrite = True ' overwrite existing files
For i = 1 To theForm.Files.Count
  Set theFile = theForm.Files(i)
  If theFile.FileExists Then
    ' save in virtual directory
    theFile.Save theFile.SafeFileName
  End If
Next
See Also

XField object.


Item Property

Type | Default Value | Read Only | Description
Long | N/A | Yes | A set of matching fields from the upload. This is the default property of the XForm object.
Notes

The Item property contains a collection of matching fields from the current upload. The precise behavior of the Item property is complicated but all that is normally required is that you copy what you would normally do using a standard Request.Form object.

The Item property allows you to access both form input fields and file upload fields. However for ease of use you will normally use the Files collection for accessing file upload fields.

You must not refer to the Request.Form object on any page which uses an XForm object. If you do so an error will result as both try to obtain exclusive access to shared resources.

Getting the Text of a Field

If you want to get the content of a particular field you might use code like this.

Set theForm = Server.CreateObject("ABCUpload4.XForm")
Response.Write theForm("flavor")

Given the following form.

<form method="post" action="myup.asp"
              enctype="multipart/form-data">
<input type="text" name="flavor" value="chocolate"><br>
<input type="submit" name="submit" value="submit">
</form>

This might produce the following output.

chocolate

Getting an XField object for a Field

The normal behavior of the XForm object is identical to that of the standard Form.Request object. This means that text is the normal return value. For file upload fields you will want to reference an XField object. To do this use code like this.

Set theForm = Server.CreateObject("ABCUpload4.XForm")
Set theField = theForm("myupload")(1) ' see note below
Response.Write "File Name = " & theField.FileName
              & "<br>"
Response.Write "File Type = " & theField.FileType
              & "<br>"

Given the following form.

<form method="post" action="myup.asp"
              enctype="multipart/form-data">
<input type="file" name="myupload"><br>
<input type="submit" name="submit" value="submit">
</form>

This might produce the following output.

File Name = mypic.jpg
File Type = jpg

Note that when you request the object you must specify both the name of the field ("myupload") and also the index of the field (1). The index will always be one unless there are two or more identically named fields. If you do not specify an index or do not use the keyword Set the content of the file will be returned as a text string - probably not what you want.

Getting the Text of Fields with the Same Name

If you have multiple fields with the same name (something that is common if you are using checkboxes) you may want to iterate through all the boxes which were checked. You might want to use code like this.

For i = 1 To Request.Form("color").Count
  Response.Write Request.Form("color")(i) & "<br>"
Next

Given the following form.

<form method="post" action="myup.asp" enctype="multipart/form-data">
<input type="checkbox" name="color" value="red" checked>Red<br>
<input type="checkbox" name="color" value="purple" checked>Purple<br>
<input type="checkbox" name="color" value="green" checked>Green<br>
<input type="checkbox" name="color" value="blue" checked>Blue<br>
<input type="submit" name="submit" value="submit">
</form>

This might produce the following output.

red
purple
green
blue

Getting the Text of all Fields

If you want to return the contents of every field in a form you might use the following code.

Set theForm = Server.CreateObject("ABCUpload4.XForm")
For Each theItem In theForm
  Response.Write "<br>" & theItem & "<br>"
  For Each theSubitem In theForm(theItem)
    Response.Write " - " & theSubitem
  Next
Next

Given the following form.

<form method="post" action="myup.asp"
              enctype="multipart/form-data">
<input type="text" name="flavor"
              value="chocolate"><br>
<input type="checkbox" name="color" value="red"
              checked>Red<br>
<input type="checkbox" name="color" value="purple"
              checked>Purple<br>
<input type="checkbox" name="color" value="green"
              checked>Green<br>
<input type="checkbox" name="color" value="blue"
              checked>Blue<br>
<input type="submit" name="submit" value="submit">
</form>

This might produce the following output.

flavor
- chocolate
color
- red - purple - green - blue
submit
- submit

Full Description

The precise behavior of the Item property is complicated but for completeness is documented here. To understand it fully you must bear in mind that each form may be associated with many field names and each field name may be associated with many fields (though normally forms contain a unique name for each field).

If you do not pass an index the Item property returns a collection of all the field names available. This is a collection of Strings. If you pass in a String the Item property returns a collection of all fields with that name. This is a collection of XField objects. If you pass in a Number the Item property returns a collection of all fields with that index. Again this is a collection of XField objects.

The collection of XField objects also implements an Item property with an optional index parameter. A form may contain many fields with the same name so this index allows you to choose the one you are interested in. If you do not specify an index the property returns a comma delimited string of the contents of all the matching fields.
See Also

Count property. XField object.


Count Property

Type | Default Value | Read Only | Description
Long | N/A | Yes | The number of unique field names in the form.
Notes

This property tells you how many unique field names are held in the form. You can use the count instead of the default enumerator. For example the following code...

Set theForm = Server.CreateObject("ABCUpload4.XForm")
For Each theItem In theForm
  Response.Write "<br>" & theItem & "<br>"
Next

is functionally equivalent to ....

Set theForm = Server.CreateObject("ABCUpload4.XForm")
For i = 1 To theForm.Count
  Response.Write "<br>" & theForm(i) & "<br>"
Next

Given the following form...

<form method="post" action="myup.asp" enctype="multipart/form-data">
<input type="text" name="flavor" value="peach"><br>
<input type="text" name="color" value="blue"><br>
<input type="submit" name="submit" value="submit">
</form>

they both might produce the following output...

flavor
color
submit
See Also

Item property.


ID Property

Type | Default Value | Read Only | Description
Long | Random | No | A unique ID for the upload.
Notes

Every form object is assigned a unique ID to allow other dependent objects such as the XProgress object to keep track of the current status of an upload. You can change the unique ID at any time before the upload starts (this typically occurs when the item collection is first referenced).

Once the upload has started the form object keeps track of the current status of the upload and enters the information into the upload database. The upload database is publicly available and so other objects can obtain information as long as they know the appropriate ID.

IDs are generally random numbers and must range between 1 and 2,147,483,647.

See Also

XProgress object.


AbsolutePath Property

Type | Default Value | Read Only | Description
Boolean | False | No | Whether paths should be interpreted as absolute or virtual.
Notes

To ease development you can specify whether the paths you supply to any ABCUpload method are absolute or virtual. An absolute pathname is a physical path to a file location. For example:

C:\inetpub\wwwroot\mysite\images\mypic.jpg

A virtual pathname is a URL specifying a pathname relative to the current page being processed. For example:

../images/mypic.jpg

Because most uploaded files are saved out into a virtual directory the default behavior is to treat pathnames as virtual. You can change this by changing the value of the AbsolutePath property.

The following code:

theForm.AbsolutePath = False
theForm.Save "../dumps/myupload.dat"

... is functionally equivalent to:

theForm.AbsolutePath = True
theForm.Save Server.MapPath("../dumps/myupload.dat")
See Also

Save method. Read method. Overwrite property. XField.Save method.


Overwrite Property

Type | Default Value | Read Only | Description
Boolean | False | No | Whether saved files should overwrite existing files.
Notes

For safety reasons saved files will not normally overwrite existing files. If you try to save a file to a location which already contains an existing file an error will be raised. You can trap this error using the standard 'on error...' methods.

If you wish to overwrite files you must change the Overwrite property to be True. If you do this then no error will be raised and any existing file will be overwritten.
See Also

Save method. XField.Save method.


MaxUploadSize Property

Type | Default Value | Read Only | Description
Long | 8,388,608 | No | The maximum number of bytes which will be accepted in an upload.
Notes

This property is used to limit the size of uploads. The limit here refers to the total size of the HTTP upload in bytes (approximately equal to the sum of all the files being upload). Because the entire content of the HTTP upload must be stored either on disk or in memory you may wish to limit the MaxUploadSize.

At the point that field values are returned the upload has already taken place. So if you wish to change the value of the MaxUploadSize you should do so before any form fields are referenced.

The server will check the size of data it needs to process and if it is too large will refuse to accept it. Because the server is refusing the request the uploading browser will report that the submission page is not available. This means you cannot provide an error message to the user via that page.

If you believe that visitors may attempt to perform uploads greater than the MaxUploadSize you should report error messages back via a progress window. The Progress.Note field will hold a message describing why the transfer was aborted.

Suppose you have three pages - your form page (form.asp) which submits uploaded files to another page (upload.asp) and reports progress via progress.asp. If a user attempts to make an oversize upload from form.asp then upload.asp will reject the transfer. The client browser will report that upload.asp is unavailable. However the reason why the request was refused will be available via the XProgress object in progress.asp and so an error message can be reported to the user.

Other upload components use different understandings of maximum upload size. Some take it to mean the maximum size of files that can be saved out of the upload. By the time that you know the files are too big you have already uploaded them so it seems irrelevant to fail a transfer at this point. If you want to limit the size of saved files then check the XField.Length property before saving. Other upload components terminate an upload when they reach the maximum set upload size. This means the user has to wait for the upload to complete before being informed of a problem and the server is left with a partially complete upload.

See Also

None.


User Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The name of the current user.
Notes

To determine what resources are accessible to IIS and ASP every session runs in a security context. This context is a particular user impersonated by IIS (typically IUSR_machinename). The User property allows you to determine what user is currently being impersonated.

For further details of Windows security see Microsoft's "Windows NT Security". If you want to run IIS in an isolated process see "Server Reliability Through Process Isolation". Please note that security works differently when running in an isolated process. This is fully covered in the above articles.
See Also

Domain property. SetUser method.


Domain Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The domain the current user belongs to.
Notes

To determine what resources are accessible to IIS and ASP every session runs in a security context. This context is a particular user impersonated by IIS (typically IUSR_machinename). The Domain property allows you to determine name of the domain to which the current user belongs.

For further details of Windows security see Microsoft's "Windows NT Security". If you want to run IIS in an isolated process see "Server Reliability Through Process Isolation". Please note that security works differently when running in an isolated process. This is fully covered in the above articles.

See Also

User property. SetUser method.


CodePage Property

Type | Default Value | Read Only | Description
Long | 0 | No | The CodePage for expected uploads
Notes

Some browsers do not support Unicode and instead upload raw Multi Byte Character Set (MBCS) text. In these cases there is no way that ABCUpload can know what what kind of language conversion to apply. By using the CodePage property you can hint at how at how ABCUpload should do this conversion process.

For example if you are expecting uploads to be coming from Korean clients you should set the CodePage property to the Korean CodePage ID (949). For Japanese you would use the Japanese CodePage (932).

You should set the code page immediately after creating your XForm objects and before any form fields are referenced.
See Also

None.


Multipart Property

Type | Default Value | Read Only | Description
Boolean | N/A | Yes | Whether multipart encoded data was found.
Notes

ABCUpload supports both normal and multipart form encoding. If multipart data was submitted then this property will be true. If no fields were submitted or non-multipart data was submitted then the property will be false.
See Also

None.


Streams Property

Type | Default Value | Read Only | Description
Boolean | True | No | Whether to write NTFS Streams.
Notes

By default ABCUpload saves uploaded files in Services For Macintosh (SFM) compatible format. This is accomplished by writing multiple NTFS streams. If you wish to disable this feature you can do so setting the Streams property to false.
See Also

XField.MacBinary property.


Form Property

Type | Default Value | Read Only | Description
Variant | N/A | Yes | A reference to this XForm object.
Notes

This property holds a reference to the current XForm object. It is provided to ease transition to and from existing code that references the standard ASP Request object.

Hence code that refers to Request.Form can easily be rewritten. So the following code...

Set theReq = Request ' standard ASP Request object
Response.Write theReq.Form("name") & "<br>"
Response.Write theReq.Form("address") & "<br>"

is functionally identical to ....

Set theReq = Server.CreateObject("ABCUpload4.XForm")
Response.Write theReq.Form("name") & "<br>"
Response.Write theReq.Form("address") & "<br>"

or alternatively ....

Set theForm = Server.CreateObject("ABCUpload4.XForm")
Response.Write theForm("name") & "<br>"
Response.Write theForm("address") & "<br>"
See Also

None.


XField Object

This object represents the data uploaded within a particular HTML form field. It allows you to examine the data (e.g. to determine if a file was uploaded) and perform operations on it (e.g. save the data to disk).

Method | Description
Save | Allows you to save the contents of a field.

Property | Default | Description
Name | No | The name of the HTML field.
Content | Yes | The content of the field as a string.
Length | No | The size of the data held in the field.
FileExists | No | If a file was uploaded.
FileName | No | The URL safe uploaded filename.
FileType | No | The inferred file name extension of the file.
MIMEType | No | The MIME type of the uploaded file.
MacBinary | No | If the file was encoded as MacBinary.
SafeFileName | No | The Windows safe filename.
RawFileName | No | The uploaded filename.
RawFileType | No | The file name extension of the file.
RawFilePath | No | The uploaded filepath.
Data | No | The data within the uploaded file.
Resource | No | The resource data within the uploaded file.
RawData | No | The raw uploaded file data.
RawLength | No | The raw uploaded file length.
ImageType | No | The type of image file uploaded.
ImageWidth | No | The width of image file uploaded.
ImageHeight | No | The height of image file uploaded.


Save Method

Allows you to save the contents of a field.
Syntax

XField.Save inPath
Notes

This method allows you to save an uploaded file to a location in your web site or on your disk. All you need to do is to specify a valid path.

If you use the Save method and no file has been uploaded a zero length file will be saved. To avoid saving zero length files check the FileExists property before using the Save method.

If you save to an NTFS volume and the upload was in MacBinary format then the the complete file will be saved with data fork, resource fork and other file information completely intact. Windows users will see only the data fork but Macintosh users accessing the volume using Services for Macintosh (SFM) will see the complete file as uploaded from the client browser.

Whether the path is treated as a virtual path or an absolute path is determined by the XForm AbsolutePath property.

Whether other files are automatically overwritten is determined by the XForm Overwrite property.
See Also

FileExists property. MacBinary property. XForm.AbsolutePath property. XForm.Overwrite property. XForm.Streams property.


Name Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The name of the uploaded field.
Notes

This contains the name of the HTML field (as entered into the name attribute of the HTML input tag).

See Also

None.


Content Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The content of the uploaded field.
Notes

This is the default property of the Field object. It contains the content of the uploaded field as a string.

If the field was a file upload field this property will contain the content of the uploaded file as a string. If the uploaded file was encoded in MacBinary it will contain the data fork only.

See Also

MacBinary property.


Length Property

Type | Default Value | Read Only | Description
Long | N/A | Yes | The size of the data held in the field.
Notes

This is the size of the data held in the field. If the field contains an uploaded file the size is the same as the size of the uploaded file. The size is measured in bytes and will be equal to zero if no data is present.

If the uploaded file was encoded in MacBinary this refers to the length of the data fork only.

See Also

MacBinary property.


FileExists Property

Type | Default Value | Read Only | Description
Boolean | N/A | Yes | Whether the field contains an uploaded file.
Notes

If the field is a file upload field and a file was uploaded then this property will be true. If not it will be false.
See Also

None.


FileName Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The file name of the uploaded file.
Notes

This contains the name of the uploaded file translated into a format that can be used in a URL. The file name includes the file name extension (e.g. "myfile.htm").

This property contains only lower case alphanumeric characters and minimal punctuation such as period, dash and underscore characters.

See Also

RawFileName property.


FileType Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The inferred file name extension of the uploaded file.
Notes

This contains the file name extension of the file uploaded. If a file name extension is not available it may be derived from other information. The file name extension is typically a three character value (e.g. "txt") after the terminating period of a file name - the FileType property does not start with a period character.

Not all platforms use file name extensions so in these cases other information may be used to identify the type of file.

If files are uploaded from MacBinary capable Macintosh browsers (Internet Explorer but not Netscape Navigator) the upload contains information on the Macintosh file Creator and Type. This information may be used to infer the file type of the uploaded document. The inference is based firstly on the Services for Macintosh (SFM) settings which can be altered using MacFile. If SFM is not installed or does not provide a suitable match then a heuristic approach is used.

In some cases no file type information will be available. In these cases an empty string will be returned.

See Also

MacBinary property. RawFileType property.


MIMEType Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The MIME type of the uploaded file .
Notes

This contains the MIME type of the uploaded file as reported by the uploading browser. This MIME type is not reliable as different Browsers on different Operating Systems may report different MIME types for the same file. Treat with caution.
See Also

None.


MacBinary Property

Type | Default Value | Read Only | Description
Boolean | N/A | Yes | If the uploaded file was encoded in MacBinary.
Notes

This property is true if the raw data of the field contains a valid MacBinary encoding.

So what is MacBinary and why is it relevant?

Macintosh files are different from Windows or Unix files in a number of ways. Firstly every file consists of two separate streams or forks. The data fork holds the basic file information that you would find in a Windows file. The resource fork contains a small database of other associated information such as picture previews, notes and icons. So a BMP image might contain the BMP in the data fork and a icon, preview and copyright note in the resource fork. Secondly Macintosh files do not contain a file type extension - instead they have a hidden type and creator code.

When Internet Explorer uploads a file from a Macintosh it chooses to put all this information together into one big stream encoded as MacBinary. At a basic level ABCUpload uses the creator and type properties to infer the file type. However Microsoft has given us the ability to handle this kind of file completely correctly and so this is what we do.

Using ABCUpload you can save a MacBinary file to an NTFS formatted disk maintaining complete integrity of data fork, resource fork, file type and creator. This gives you the best of both worlds. If you look at such a file from Windows it will look like a standard file (e.g. JPG, DOC etc.) but if you serve this file to Macintosh users using Services for Macintosh (SFM) they will see the original Macintosh file completely intact. Through named stream support available on NTFS the data fork, resource fork and other information is maintained as a package and moves with the file.
See Also

None.


SafeFileName Property

Type | Default Value | Read Only | Description
String | N/A | Yes | A Windows friendly version of the file name.
Notes

This contains the name of the uploaded file translated into a format that can be used to save the file. The SafeFileName includes any file name extension but does not include any directory information. In general you should only use the SafeFileName for saving the file when the original name is essential to the upload. In other cases you should assign a new name to your file to allow you to maintain control over the names of files saved on your server.

Note that the fact that the file name is safe for saving does not mean that it is safe to use in a URL. For instance it may contain spaces or Unicode characters. If you need a URL safe name you should use the FileName property.

You should not use the SafeFileName property in virtual pathnames. Active Server Pages cannot resolve virtual paths containing Unicode characters into physical pathnames. If you wish to write a Unicode file into a virtual directory you should use code of the following form.

theForm.AbsolutePath = True
thePath = Server.MapPath("mydirectory\") & theForm(inName)(1).SafeFileName
theForm(inName)(1).Save thePath

The translation is done for two purposes. Firstly some platforms allow characters such as question marks and slashes to be used in the name of files. When these types of files are uploaded the file cannot be saved using these characters and they must be removed or translated into some other form.

If files containing illegal characters are uploaded from Macintosh browsers the names will be translated into the standard Services for Macintosh (SFM) Unicode format so that they can be saved intact. To a Windows user the file may appear to contain unusual characters but to a Macintosh user the name will appear as it was when uploaded.

In other cases when uploaded file names contain illegal characters these are deleted so that the file name can be used as part of a save name.

See Also

None.


RawFileName Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The file name of the file uploaded.
Notes

This contains the file name of the file uploaded. It is directly derived from the RawFilePath property.

Depending on the source Operating System and Browser this property may contain characters such as question marks and slashes which are illegal in file names on Windows. It may also contain Unicode characters.

See Also

RawFilePath property. FileName property.


RawFileType Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The file name extension of the file uploaded.
Notes

This contains the file name extension of the file uploaded. It is directly derived from the RawFilePath property. The file name extension is typically a three character value (e.g. "txt") after the terminating period of a file name - the RawFileType property does not start with a period character.

Depending on the source Operating System and Browser this property may contain characters such as question marks and slashes which are illegal in file names on Windows. It may also contain Unicode characters.

See Also

RawFilePath property. FileType property.


RawFilePath Property

Type | Default Value | Read Only | Description
String | N/A | Yes | The client file path of the file uploaded.
Notes

This contains the file path as reported by the uploading client browser. This is typically the path to the file as exists on the client computer.

  • Windows Browsers upload a path name - e.g. "c:\mydirectory\myfile.ext"
  • Macintosh Browsers upload the file name only - e.g. "Picture of Mum?"
  • UNIX users upload a path name - e.g. "mydrive:\mydir\\myfile.ext"

This property may contain Unicode characters depending on the locale of the uploading operating system, the name of the file and the type of browser being used to perform the upload. In general Internet Explorer browsers support Unicode uploads while Netscape Navigator browsers do not.

Depending on the source Operating System and Browser the RawFilePath property may contain characters such as question marks and slashes which are illegal in file names on Windows.

See Also

RawFileType property. RawFileName property.


Data Property

Type | Default Value | Read Only | Description
Variant | N/A | Yes | The binary data within the uploaded file.
Notes

This contains the data within the uploaded file. The representation of the file is a Variant containing a SafeArray of Bytes. This binary format is frequently required when inserting a BLOB into a database.

For most uploads the Data property will be identical to the RawData property. However if files have been uploaded from MacBinary capable Macintosh browsers (Internet Explorer but not Netscape Navigator) this property will contain only the uploaded data fork of the file.

The lower bound of this array is always zero and the upper bound is equal to the size of the data minus one. If no data has been uploaded the upper bound will be minus one.

See Also

MacBinary property. Resource property. RawData property.


Resource Property

Type | Default Value | Read Only | Description
Variant | N/A | Yes | The resource fork data within the uploaded file.
Notes

This contains the resource fork of the uploaded file. The representation of the data is a Variant containing a SafeArray of Bytes. This binary format is frequently required when inserting a BLOB into a database.

Unless the upload was encoded in MacBinary this property will contain an empty array.

The lower bound of this array is always zero and the upper bound is equal to the size of the data minus one. If no data has been uploaded the upper bound will be minus one.

See Also

MacBinary property. Data property. RawData property.


RawData Property

Type | Default Value | Read Only | Description
Variant | N/A | Yes | The raw binary data within the uploaded file.
Notes

This contains the raw binary data uploaded by the client browser. It may be encoded in a format such as MacBinary which is why it is not generally useful. For most uploads the RawData property will be identical to the Data property. The representation of the data is a Variant containing a SafeArray of Bytes.

The lower bound of this array is always zero and the upper bound is equal to the size of the data minus one. If no data has been uploaded the upper bound will be minus one.

See Also

MacBinary property. Resource property. Data property.


RawLength Property

Type | Default Value | Read Only | Description
Long | N/A | Yes | The size of the raw data held in the field.
Notes

This is the size of the raw data held in the field. If the field contains an uploaded file the size is the same as the size of the uploaded file. The size is measured in bytes and will be equal to zero if no data is present.
See Also

Length property.


ImageType Property

Type | Default Value | Read Only | Description
Enum | N/A | Yes | The type of image uploaded.
Notes

This gives you the type of image that was uploaded. The possible return values are:

  • 0 - abcUnknown
  • 1 - abcJPEGgray
  • 2 - abcJPEG
  • 3 - abcJPEGcmyk
  • 4 - abcGIF
  • 5 - abcPNG
  • 6 - abcBMP

If the ImageType is recognized then the ImageHeight and ImageWidth properties will contain the dimensions of the image.

Note the distinction between different types of JPEG image. A full validation of the JPEG data is carried out (this is very fast) to determine firstly if the image is complete and secondly the exact type of JPEG data. If the image is incomplete then the the type will be abcUnknown.

Only standard JPEG images (type abcJPEG) are guaranteed viewable by web browsers. There are no web browsers that we are aware of that allow viewing of CMYK JPEG images. Grayscale JPEG images are viewable using many browsers but you may not wish to rely on this.
See Also

ImageWidth property. ImageHeight property.


ImageWidth Property

Type | Default Value | Read Only | Description
Long | N/A | Yes | The width of the uploaded image in pixels.
Notes

This gives you the width, in pixels, of the image that was uploaded. If the upload is not of a recognized image type the value will be zero.
See Also

ImageType property. ImageHeight property.


ImageHeight Property

Type | Default Value | Read Only | Description
Long | N/A | Yes | The height of the uploaded image in pixels.
Notes

This gives you the height, in pixels, of the image that was uploaded. If the upload is not of a recognized image type the value will be zero.
See Also

ImageType property. ImageWidth property.


XProgress Object

This object allows access to the central upload database. Each XForm object has an ID which it uses to log upload status in the database. If you know the ID of an XForm object you can synchronize your XProgress object with it and so obtain information on the status of an upload.

Method | Description
None |

Property | Default | Description
ID | No | The unique ID of the upload.
Note | No | The current state of the upload.
Started | No | Whether the transfer has started.
PercentDone | No | The amount of upload completed.
BytesDone | No | The number of bytes uploaded.
BytesTotal | No | The total number of bytes to upload.
BytesPerSecond | No | The upload speed.
ElapsedSeconds | No | The number of seconds elapsed.
SecondsLeft | No | The estimated time to completion.


ID Property

Type | Default Value | Read Only | Description
Long | Random | No | A unique ID for the upload.
Notes

Every XForm object is assigned a unique ID to allow other dependent objects such as the XProgress object to keep track of the current status of an upload. You should change the ID property of your XProgress object to match the ID of the XForm object you are interested in. At this point the XForm and XProgress objects will both be accessing the same record in the central database and so will be synchronized.

After the ID has been changed, properties of the XProgress object will reflect the status of the current upload. These are read only with the exception of the Note property which can be used to pass information in either direction.

See Also

XForm.ID property.


Note Property

Type | Default Value | Read Only | Description
String | "" | No | Any note from the upload.
Notes

The note property is typically used to pass information from the XForm object to the XProgress object. It will be updated as the status of the transfer changes.

You can change the value of the note if you want to pass messages between XProgress objects.

See Also

None.


Started Property

Type | Default Value | Read Only | Description
Boolean | False | Yes | If the transfer has started.
Notes

This value reflects whether the transfer has started. The transfer is regarded as started when the XForm object first updates the central database.
See Also

None.


PercentDone Property

Type | Default Value | Read Only | Description
Long | 0 | Yes | The percentage of the transfer that has been completed.
Notes

This value reflects the percentage of the total amount of data that has been transferred.
See Also

None.


BytesDone Property

Type | Default Value | Read Only | Description
Long | 0 | Yes | The total number of bytes uploaded.
Notes

The total number of bytes uploaded.

See Also

BytesTotal property.


BytesTotal Property

Type | Default Value | Read Only | Description
Long | 0 | Yes | The total number of bytes to be uploaded.
Notes

The total number of bytes to be uploaded. This value has to be transmitted from the client browser to the server and so is not immediately available. During this connecting period the value will default to zero.
See Also

BytesDone property.


BytesPerSecond Property

Type | Default Value | Read Only | Description
Long | 0 | Yes | The number of bytes uploaded per second.
Notes

The number of bytes uploaded per second during this transfer.
See Also

None.


ElapsedSeconds Property

Type | Default Value | Read Only | Description
Long | 0 | Yes | The number of seconds the transfer has been in progress.
Notes

The number of seconds that the transfer has been in progress.
See Also

SecondsLeft property.


SecondsLeft Property

Type | Default Value | Read Only | Description
Long | 0 | Yes | The estimated number of seconds of transfer left.
Notes

This value reflects the estimated number of seconds of transfer left. It is based on the amount of data transferred and the average data transfer rate. Because data transfer rates may vary the SecondsLeft property is an estimate - it may increase or decrease as network conditions change.

If the sum of ElapsedSeconds and SecondsLeft exceeds Server.ScriptTimeOut you may wish to inform the client that their transfer is likely to time out.

See Also

ElapsedSeconds property.