RFC 1867
Form-based File Upload in HTML
RFC 1867 π Form-based File Upload in HTML π
okay bestie, the title block is giving Network Working Group πΈ. The authors are E. Nebel and L. Masinter from Xerox Corporation π , the category is Experimental π§ͺ, and the date is November 1995 π . The title block doesn't list anything this RFC obsoletes or updates. It's a whole proposal for letting web forms upload files π€β¨
Status of this Memo π
This memo defines an Experimental Protocol for the Internet community π§ͺ. It does not specify an Internet standard of any kind. Discussion and suggestions for improvement are requested π¬. Distribution of this memo is unlimited π¦.
1. Abstract β¨
okay so HTML forms are already amazing for asking the user for info π. But there was one big gap π: forms had no way to ask the user to send over a file π. Service providers who needed files ended up building their own custom user applications just to get them π οΈ. (Some examples of those custom browsers were posted on the www-talk mailing list π.)
So this proposal extends HTML so information providers can ask for file uploads in a uniform way π. It also describes a MIME-compatible representation for the file upload responses π¦. And there's a backward compatibility strategy so new servers can still work with current HTML user agents π«Ά. Not me being impressed by that last part π₯.
The proposal doesn't depend on which version of HTML it ends up being part of π¦.
2. HTML forms with file submission π
the current HTML spec gives the TYPE attribute of <INPUT> eight possible values: CHECKBOX, HIDDEN, IMAGE, PASSWORD, RADIO, RESET, SUBMIT, and TEXT π. It also sets the default ENCTYPE attribute of <FORM> when using the POST method to "application/x-www-form-urlencoded" π.
This proposal makes two changes to HTML π:
- Add a
FILEoption for theTYPEattribute of<INPUT>π. - Allow an
ACCEPTattribute on the<INPUT>tag, which is a list of media types or type patterns allowed for the input π―.
It also defines a brand new MIME media type, multipart/form-data π, and spells out how HTML user agents should behave when they see a form with ENCTYPE="multipart/form-data" and/or <INPUT type="file"> tags π§.
These changes could be looked at separately, but honestly they're all needed for file upload to be reasonable π«Ά.
Say a form author wants to ask a user for one or more files. They'd write something like this π:
<FORM ENCTYPE="multipart/form-data" ACTION="_URL_" METHOD=POST>
File to process: <INPUT NAME="userfile1" TYPE="file">
<INPUT TYPE="submit" VALUE="Send File">
</FORM>
For the DTD change π§©, you just add one item to the entity InputType. And the INPUT tag gets an ACCEPT attribute, which is a list of comma-separated media types π.
... (other elements) ...
<!ENTITY % InputType "(TEXT | PASSWORD | CHECKBOX |
RADIO | SUBMIT | RESET |
IMAGE | HIDDEN | FILE )">
<!ELEMENT INPUT - 0 EMPTY>
<!ATTLIST INPUT
TYPE %InputType TEXT
NAME CDATA #IMPLIED -- required for all but submit and reset
VALUE CDATA #IMPLIED
SRC %URI #IMPLIED -- for image inputs --
CHECKED (CHECKED) #IMPLIED
SIZE CDATA #IMPLIED --like NUMBERS,
but delimited with comma, not space
MAXLENGTH NUMBER #IMPLIED
ALIGN (top|middle|bottom) #IMPLIED
ACCEPT CDATA #IMPLIED --list of content types
>
... (other elements) ...
3. Suggested implementation π οΈ
user agents that read HTML get a lot of freedom to pick whatever mechanism fits their context π¦. This section just suggests how one class of user agent, WWW browsers, could do file upload π.
3.1 Display of FILE widget π
When the browser hits an <INPUT> tag of type FILE, it might show any file names that were already picked, plus a "Browse" button or some other way to select files π. Pressing "Browse" would send the browser into a file selection mode that fits the platform π». Window-based browsers might pop up a file selection window, for example β¨. In that dialog, the user could replace the current selection, add a new file, and so on π§Ί. Implementers might also let the list of file names be edited by hand βοΈ.
If an ACCEPT attribute is present, the browser might limit the file patterns it prompts for so they match the appropriate file extensions for the platform π―.
3.2 Action on submit π
When the user finishes the form and presses the SUBMIT element, the browser should send the form data and the contents of the selected files π€. The application/x-www-form-urlencoded encoding is inefficient for sending large amounts of binary data or text with non-ASCII characters π©. So a new media type, multipart/form-data, is proposed as an efficient way to send the values from a filled-out form from client to server π.
3.3 use of multipart/form-data π§©
The definition of multipart/form-data shows up in section 7 π. A boundary gets picked that doesn't appear in any of the data π. (Sometimes that choice is made probabilistically π².) Every field of the form gets sent in the order it appears in the form, as one part of the multipart stream π. Each part identifies the INPUT name from the original HTML form π·οΈ. Each part should be labelled with an appropriate content-type if the media type is known (for example, inferred from the file extension or the operating system's typing info) π§ . If it isn't known, it gets labelled as application/octet-stream π¦.
If several files are selected, they should be transferred together using the multipart/mixed format ποΈ.
HTTP can carry arbitrary BINARY data πͺ. But for mail transport (say, when the ACTION is a mailto: URL) the default encoding is 7BIT π§. If a part's value doesn't fit that default encoding, the value may need to be encoded and the content-transfer-encoding header supplied π. [See section 5 of RFC 1521 for more details.]
The original local file name can be supplied too π. You can put it in a filename parameter on the content-disposition: form-data header, or, when there are several files, in a content-disposition: file header on the subpart π. The client application should make its best effort to supply the file name πͺ. If the client's operating system file name isn't US-ASCII, the name might be approximated, or encoded using the method of RFC 1522 π. This is handy when uploaded files reference each other, like a TeX file and its .sty auxiliary style description πβ¨.
On the server end, the ACTION might point to an HTTP URL that implements the form's action through CGI π₯οΈ. In that case, the CGI program would notice that the content-type is multipart/form-data and parse the various fields π. That includes checking they're valid and writing the file data to local files for later processing ποΈ.
3.4 Interpretation of other attributes π
The VALUE attribute might be used with <INPUT TYPE=file> tags to set a default file name π. That's probably platform dependent π₯οΈ. It could still be useful in a sequence of several transactions, for example so the user isn't asked for the same file name over and over π€.
The SIZE attribute might be given as SIZE=width,height π. Here width is the default for file name width, and height is the expected size of the list of selected files π. This helps form designers who expect to get several files and want a multiline file input field in the browser, ideally with a "browse" button next to it π. When no height is given (the designer expects just one file), the browser should show a one-line text field π«§. When the height is greater than 1 (the designer expects multiple files), it should show a multiline text area with scrollbars ππ.
4. Backward compatibility issues π
It isn't required for this enhancement to the current WWW form mechanism to get adopted successfully π. Still, it's useful to plan a migration strategy πΊοΈ. That way, people with older browsers can still take part in file upload dialogs by using a helper application π§.
Most current web browsers treat <INPUT TYPE=FILE> as <INPUT TYPE=TEXT> and give the user a text box π. The user can type a file name into that box π. Current browsers also seem to ignore the ENCTYPE parameter on <FORM> and always send the data as application/x-www-form-urlencoded π.
So the server CGI can be written to notice when the returned form data has content-type application/x-www-form-urlencoded instead of multipart/form-data. From that it knows the user is on a browser that doesn't implement file upload π΅οΈββοΈ.
In that situation, instead of replying with a text/html response, the CGI can send back a data stream that a helper application can process π. This stream has the type application/x-please-send-files and contains:
- The (fully qualified) URL to which the actual form data should be posted (terminated with CRLF)
- The list of field names that were supposed to be file contents (space separated, terminated with CRLF)
- The entire original
application/x-www-form-urlencodedform data as originally sent from client to server.
In this case, the browser needs to be configured to handle application/x-please-send-files by launching a helper application π§.
The helper reads the form data and notes which fields held 'local file names' that need to be swapped out for their data content π. It might also prompt the user to change or add to the list of files π. Then it repackages the data and file contents as multipart/form-data to send back to the server π¦.
The helper basically generates the kind of data a 'new' browser should have sent in the first place π . The URL it goes to should match the original ACTION URL π―. The point is that the server can use the same CGI to handle both old and new browsers π«Άβ¨.
The helper doesn't need to display the form data π. But it should make sure the user actually gets prompted about whether it's okay to send the files requested π¨. That's there to prevent a security problem with malicious servers asking for files the user never actually agreed to share π«£. It would also be useful to show the status of the file transfer while it's happening π.
β οΈ Security note, babe: the prompt is the thing standing between the user and a malicious server quietly asking for files nobody promised to send. Don't skip it ππ.
5. Other considerations π
(to be continuedβ¦) π¦
5.1 Compression, encryption β¨
okay so this scheme doesn't deal with compressing files at all π After thinking it over, the optimization stuff for file compression felt way too complex to have browsers automatically decide when files should get compressed. Lots of link-layer transport mechanisms (like high-speed modems) already do data compression over the link, so optimizing for compression at that layer might not even be appropriate π«Ά
It might be possible for browsers to optionally send a content-transfer-encoding of x-compress for file data, and for servers to decompress the data before processing if they want to. We just left that out of the proposal π
Encryption isn't in here either π The proposal doesn't have a mechanism for encrypting the data. That should be handled by whatever other mechanisms are already in place for secure transmission of data, whether that's secure HTTP or mail π
5.2 Deferred file transmission π¦
Sometimes it's a good idea for the server to check parts of the form data (like a user name or account) before it even gets ready to receive the data. But after thinking it through, we decided that servers who want this should build it as a series of forms instead. Some of the data that already got validated can be sent back to the client as 'hidden' fields, or the form can be arranged so the stuff that needs validating comes first. This puts the job of keeping track of a transaction's state only on servers building complex apps, while simple input stays simple π
HTTP might require a content-length for the whole transmission. Even if it didn't, HTTP clients are encouraged to supply a content-length for the overall file input π so a busy server can tell if the file is too big to process reasonably. Then it can just return an error code and close the connection without waiting for all the incoming data. Some current CGI implementations require a content-length in every POST transaction π
If the INPUT tag includes the attribute MAXLENGTH, the user agent should consider its value to represent the maximum Content-Length (in bytes) that the server will accept for transferred files. That's how servers can hint to the client how much room they have for a file upload before the upload happens π§ Just know it's only a hint, because the server's actual requirements might change between when the form was created and when the file gets submitted π
Also, an HTTP server may abort a file upload in the middle of the transaction if the file being received is too large βοΈ
5.3 Other choices for return transmission of binary data π
Various people have suggested using a new MIME top-level type called "aggregate", like aggregate/mixed, or a content-transfer-encoding of "packet", to express indeterminate-length binary data instead of relying on multipart-style boundaries. We're not opposed to that, but it would need additional design and standardization work to get "aggregate" accepted π Meanwhile, the multipart mechanisms are super established, simple to implement on both the sending client and the receiving server, and just as efficient as other methods of dealing with multiple combinations of binary data β¨
5.4 Not overloading <INPUT> π
Some people wondered if it's smart to overload 'INPUT' for this function instead of just making a totally different FORM element. Among other considerations, the migration strategy you're allowed to use with <INPUT> matters a lot π Also, the <INPUT> field is already overloaded to hold most kinds of data input, so instead of making a bunch of new <INPUT> tags, it felt way more reasonable to enhance <INPUT> π
The 'type' of INPUT isn't the content-type of what gets returned. It's the 'widget-type', aka the interaction style with the user. The description was carefully written so that <INPUT TYPE=FILE> works for text browsers or audio-markup too π§
5.5 Default content-type of field data π
Lots of input fields in HTML are typed in by the user, and there was some ambiguity about how form data should be sent back to servers π€· Making the content-type of <INPUT> fields be text/plain clearly disambiguates that the client should properly encode the data before sending it back to the server, with CRLFs π«Ά
5.6 Allow form ACTION to be "mailto:" π¬
Totally separate from this proposal, it would be super useful for HTML user agents to let a form's ACTION be a "mailto:" URL. It's a good idea with or without this proposal π Similarly, the ACTION for an HTML form received via mail should probably default to the "reply-to:" of the message. Together, these two ideas let HTML forms be served over HTTP but sent back via mail, or let forms be sent by mail, filled out by HTML-aware mail recipients, and the results mailed back π
5.7 Remote files with third-party transfer π
Sometimes the user operating the client might want to specify a URL for remote data instead of a local file. So is there a way to let the browser send the server a pointer to the external data instead of the entire contents? One option: the client could send the server data of type message/external-body with access-type set to, say, uri, and the URL of the remote data in the body of the message πͺ
5.8 File transfer with ENCTYPE=x-www-form-urlencoded π
If a form has <INPUT TYPE=file> elements but no ENCTYPE in the enclosing <FORM>, the behavior is not specified π€· It's probably not a great idea to try URN-encoding big chunks of data for servers that don't expect it.
5.9 CRLF used as line separator π
Like with all MIME transmissions, CRLF is the separator for lines in a POST of the data in multipart/form-data.
5.10 Relationship to multipart/related π
The MIMESGML group is proposing a new type called multipart/related π§© It has similar features to multipart/form-data, but the use and application of form-data is different enough that form-data is described separately. It might be possible at some point to encode the results of HTML forms (including files) in a multipart/related body part, and that's not incompatible with this proposal β¨
5.11 Non-ASCII field names π
Heads up: MIME headers are generally required to consist only of 7-bit data in the US-ASCII character set π€ So field names should be encoded according to the prescriptions of RFC 1522 if they contain characters outside that set. In HTML 2.0 the default character set is ISO-8859-1, but non-ASCII characters in field names should still be encoded π
6. Examples π
Okay, let's do an example π§ Say the server supplies the following HTML:
<FORM ACTION="http://server.dom/cgi/handle"
ENCTYPE="multipart/form-data"
METHOD=POST>
What is your name? <INPUT TYPE=TEXT NAME=submitter>
What files are you sending? <INPUT TYPE=FILE NAME=pics>
</FORM>
Then the user types "Joe Blow" in the name field, and selects a text file "file1.txt" for the answer to 'What files are you sending?'
The client might send back the following data:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
If the user also picks an image file "file2.gif" for the answer to 'What files are you sending?', the client might send back the following data:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y
--BbC04y
Content-disposition: attachment; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--BbC04y
Content-disposition: attachment; filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--BbC04y--
--AaB03x--
7. Registration of multipart/form-data π
The media-type multipart/form-data follows the rules of all multipart MIME data streams as outlined in RFC 1521. It's intended for returning the data that comes out of filling out a form. In a form (in HTML, although other applications may also use forms), there's a series of fields to be supplied by the user who fills out the form. Each field has a name, and within a given form, the names are unique π
multipart/form-data contains a series of parts. Each part is expected to contain a content-disposition header where the value is "form-data", and a name attribute that specifies the field name within the form, e.g., content-disposition: form-data; name="xxxxx", where xxxxx is the field name corresponding to that field. Field names originally in non-ASCII character sets may be encoded using the method outlined in RFC 1522 πΈ
As with all multipart MIME types, each part has an optional Content-Type, which defaults to text/plain. If the contents of a file are returned by filling out a form, then the file input is identified as application/octet-stream or the appropriate media type, if known. If multiple files are returned as the result of a single form entry, they can be returned as multipart/mixed embedded within the multipart/form-data ποΈ
Each part may be encoded, and the "content-transfer-encoding" header supplied, if the value of that part does not conform to the default encoding π§
File inputs may also identify the file name. The file name may be described using the 'filename' parameter of the "content-disposition" header. This isn't required, but it's strongly recommended in any case where the original filename is known, since it's useful or even necessary in many applications π«Ά
8. Security Considerations π
It is important that a user agent not send any file that the user has not explicitly asked to be sent. So HTML interpreting agents are expected to confirm any default file names that might be suggested with <INPUT TYPE=file VALUE="yyyy">. Never have any hidden fields be able to specify any file. π¨
This proposal does not contain a mechanism for encryption of the data. That should be handled by whatever other mechanisms are in place for secure transmission of data, whether via secure HTTP, or by the security provided by MOSS (described in RFC 1848) π‘οΈ
Once the file is uploaded, it is up to the receiver to process and store the file appropriately πΎ
9. Conclusion β¨
Okay bestie, the whole design is giving flexibility π
. The client decides how many files it sends and what types they are, the server still gets to decide whether to accept them π, and servers get a chance to talk to browsers that don't support INPUT TYPE "file" at all π«Ά.
The change to the HTML DTD is super simple but sooo powerful π. It opens the door to a way bigger range of services on the World-Wide Web than we can build right now, since there's no proper file submission facility yet. Honestly, this would be an extremely valuable addition to what the Web can do π.
Authors' Addresses π
Larry Masinter
Xerox Palo Alto Research Center
3333 Coyote Hill Road
Palo Alto, CA 94304
Phone: (415) 812-4365
Fax: (415) 812-4333
EMail: masinter@parc.xerox.com
Ernesto Nebel
XSoft, Xerox Corporation
10875 Rancho Bernardo Road, Suite 200
San Diego, CA 92127-2116
Phone: (619) 676-7817
Fax: (619) 676-7865
EMail: nebel@xsoft.sd.xerox.com
A. Media type registration for multipart/form-data π
Here's the official registration paperwork for the media type, all written out exactly as it appears π:
Media Type name:
multipart
Media subtype name:
form-data
Required parameters:
none
Optional parameters:
none
Encoding considerations:
No additional considerations other than as for other multipart types.
Published specification:
RFC 1867
Security Considerations π
Short but mighty π. The multipart/form-data type doesn't introduce any new security considerations of its own. Whatever risks show up are the ones that could come with any of the enclosed parts.
References π
[RFC 1521] MIME (Multipurpose Internet Mail Extensions) Part One:
Mechanisms for Specifying and Describing the Format of
Internet Message Bodies. N. Borenstein & N. Freed.
September 1993.
[RFC 1522] MIME (Multipurpose Internet Mail Extensions) Part Two:
Message Header Extensions for Non-ASCII Text. K. Moore.
September 1993.
[RFC 1806] Communicating Presentation Information in Internet
Messages: The Content-Disposition Header. R. Troost & S.
Dorner, June 1995.
π¦ where this page comes from
- ietf: rfc1867 1995-11
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms