Re: File upload in HTML forms

Ernesto Nebel (nebel@xsoft.sd.xerox.com)
Mon, 10 Oct 1994 16:04:30 PDT


Paul,

> File upload is *very* important for the Web and I hope some consensus
> is reached soon! However, I strongly disagree with Ernesto Nebel's
> proposal, and would instead advocate the following alternative
> (combining a number of proposals aired on this list):

My main interest is getting file upload into the WWW. I won't
deadlock the discussion defending my proposal if a better proposal is
suggested and implemented quickly.

> * On the client end, support a FORM field which can accept input of
> arbitrary MIME content (not just text/plain from the keyboard). The
> most natural way would be to upgrade the behavior of TEXTAREA.

It would be useful if you could be more specific. For example, how
would you put a 100MB binary image file into the upgraded TEXTAREA?
Please explain the behavior of the upgraded TEXTAREA in more detail.

> * For the POST submission, support a multipart encoding scheme that
> circumvents the overhead of the current www-url-encoding for large
> inputs.

I agree that a multipart encoding scheme is the best way to encode the
transmission of the files. Several schemes have been suggested
already, including multipart/partial, multipart/mixed, and
aggregate/mixed. I deliberately omitted any mention of the encoding
of the files in my proposal. I suggested encoding the form data as
usual, www-form-urlencoded, because the form only sends the file names
and file sizes (in my proposal).

> Here are the main reasons I am opposed to Ernesto's proposal:
>
> 1. While it's true that the proposal would not alter the syntax of
> HTTP, it would force a drastic change in the semantics: making HTTP
> servers stateful, with all of the problems that entails. Thus,
> during the multiple back and forth transactions would be required to
> completely transmit the data in a FORM, the server would have to
> somehow generate unique "transaction URLs" that allow the client to
> connect back to the correct transaction, and furthermore, it would
> have to manage the partial transaction data for the different clients
> as it accumulates.

Servers would only become stateful iff the writer of the forms chose
to make it stateful. Let me explain with a ficticious example.
Suppose I'm a book editor and I put up a server so that authors can
submit manuscripts for my review. I make a form that includes an
INPUT tag of TYPE "file", where the author will enter the paths to all
the chapters that make up his manuscript. The browser sends the file
names and sizes to a CGI script at the server, all www-form-urlencoded
with the rest of the form data. The browser does not need to remember
anything about the data it just sent. The CGI script responds to this
form submission with data of a new MIME type (as mentioned in the
proposal) that contains the full URL to another CGI script (which will
accept the files) and the paths to all the chapters of the manuscript.
Then, the server can forget about the form submission that just
ocurred. It does NOT need to keep any state information. The
browser, which, again, does NOT need to remember anything about the
form submission, reacts to this new MIME type by showing the author
the paths to the chapters of the manuscript that will be sent to the
editor's server, and it prompts him for confirmation. When the author
confirms, the browser encodes the manuscripts (with a multipart
scheme) and sends them to the CGI script (remember, the server just
told the browser which files to send and which URL to use). This
second CGI script at the server, which again does NOT need to have any
state information, receives the files and stores them in the "incoming
manuscripts" directory of the editor's computer.

Keeping state information is completely optional. (By the way, some
server applications already keep state information with the help of
forms' HIDDEN fields.)

> This would also add serious complications to CGI,
> (for example, requiring global script changes to handle a simple
> change of field from type TEXTAREA to FILE). These are rather large
> issues to stir up for one extra feature (important as it is).

I don't know exactly what you mean. The writer of the forms knows
that he has to write two CGI scripts to handle file input if he
chooses to include one or more INPUT tags of TYPE "file". The first
just accepts www-form-urlencoded information like any form CGI script
does today. The second CGI script will handle unencoding the files
and storing them in the server's file system. A skeleton for the
first kind of CGI script is already widely available, and a skeleton
for the second kind of CGI script could be made widely available as
soon as the file encoding is decided.

The only remaining issue I can think of is: how does a CGI script (the
one that accept the form data, including file names and sizes)
distinguish between form data supplied by a browser which supports
file upload and one which does not? What I suggested in the proposal
is to check the name/value pairs. A browser with supports file upload
will send at least two name/value pairs associated with the TYPE
"file" INPUT tag: the first will contain the number of file names and
the rest will contain the file paths and file sizes. A browser which
does not support file upload will only send one name/value pair
corresponding to the text field it created in place of the file field
(text fields are the default in the HTML DTD). If a form writer
included an INPUT tag of TYPE "file" with NAME "fileinput" and a
client entered two valid file names, a browser with file upload
support could send:

name = fileinput value = 2
name = c:\project\chapter1.wp value = 3452
name = c:\project\chapter2.wp value = 5234

(This is only an example. The browser could also send two name/value
pairs per file, one for the path and one for the size, or something
else. The format of these name/value pairs can be settled later).

A browser without file upload support would send:

name = fileinput value = c:\project\chapter1.wp c:\project\chapter2.wp

The CGI script would only have to examine the name in the name/value
pair that follows the "fileinput" name/value pair. If there is no
other name/value pair or if the name matches the name of the next
field in the form, then the CGI script knows that the browser does not
support file upload. If the CGI script finds another name/value pair
and the name does not match the name of the next form field in the
form, then the CGI script knows that the browser supports file upload
and that the value of the "fileinput" pair contains the number of
files names sent. I don't think this is very complicated. One string
compare is all it takes.

> 2. Having a special "FILE" INPUT type deprives users of the choice
> to enter small amounts of ASCII data directly into the FORM, if they
> so choose. Even for small input, they would instead have to prepare
> an external file with the data, and then use a file browser to
> register that file with the FORM.

I don't think this argument is sufficiently strong to invalidate my
proposal. The form writer should make an educated guess as to the
data it will get from the client. If he expects multiple, huge image
files, he will definitely use TYPE "file" INPUT tags. If he expects a
single text file, he might choose to use a TEXTAREA instead.


All comments appreciated.

Sincerely,

Ernesto Nebel

XSoft
nebel.sd@xerox.com
nebel@xsoft.sd.xerox.com