|
File Upload
Part:
1
2
3
4
5
(Continued from previous part...)
On UploadForm page, I selected the same files:
File Upload Form:
Your email: [herong_yang@yahoo.com ]
Your comments: [I am uploading two files: ]
[ hello.txt ]
[ dot.gif ]
File 1: [C:\hello.txt ] Browse...
File 2: [C:\dot.gif ] Browse...
Submit
After clicking the submit button, I got the following result on the returning page:
-----------------------------7d59ec3031a
disposition: null: Content-Disposition: form-data; name="email"
blank: null:
data: null: herong_yang@yahoo.com
boundary: null: -----------------------------7d59ec3031a
disposition: null: Content-Disposition: form-data; name="comment"
blank: null:
data: null: I am uploading two files:
data: null: hello.txt
data: null: dot.gif
boundary: null: -----------------------------7d59ec3031a
disposition: hello.txt: Content-Disposition: form-data; name="file...
type: hello.txt: Content-Type: text/plain
blank: hello.txt:
boundary: null: -----------------------------7d59ec3031a
disposition: dot.gif: Content-Disposition: form-data; name="file2"...
type: dot.gif: Content-Type: image/gif
blank: dot.gif:
boundary: null: -----------------------------7d59ec3031a
disposition: null: Content-Disposition: form-data; name="submit"
blank: null:
data: null: Submit
boundary: null: -----------------------------7d59ec3031a--
To make sure that the uploaded files are saved correctly, I used the following
commands in a command window:
comp \hello.txt \var\hello.txt
Comparing \hello.txt and \var\hello.txt...
Files compare OK
comp dot.gif \var\dot.gif
Comparing \dot.gif and \var\dot.gif...
Files compare OK
Beautiful, my program worked perfectly. Now let's a closer look at my program.
It uses a number of logics to resolve some of the technical issues:
1. How to find out the encryption type? Since encryption type is not submitted in
the HTTP request body, I have to use the following code to determine if
the encryption type is multipart/form-data:
if (enctype==null) {
// try to determine the encryption type
if (i>3 && sLine.startsWith("--")) {
enctype = "form-data";
boundary = sLine;
...
2. How to process a multiple parts data in a single loop?
If multipart/form-data is used, the HTTP
request body contains multiple parts, and each part contains a header section
and a data section. How to read all the sections and all the parts in a single
loop and process them accordingly? I used a status code to indicate the type
of the current line in the reading loop. The following code shows you the logic
used to determine the status of the current line based the status of the previous
line:
if (status.equals("boundary")) {
// Expecting the "Content-Disposition:" line
status = "disposition";
} else if (status.equals("disposition")) {
// Expecting the "Content-Type:" line or a blank line
if (sLine.startsWith("Content-Type:")) {
status = "type";
} else {
status = "blank";
}
} else if (status.equals("type")) {
// Expecting a blank line
status = "blank";
} else if (status.equals("blank")||status.equals("data")) {
// Expecting the data or boundary
if (sLine.startsWith(boundary)) {
status = "boundary";
} else {
status = "data";
}
}
3. How and when to open and close the files to save the uploaded files? That's
easy with the status code calculated correct. See the following the code:
if (status.equals("disposition")) {
// Getting the file name and open a file for saving
int l = sLine.indexOf("filename=");
if (l>=0) {
fName = sLine.substring(l+9);
fName = fName.replaceAll("\"","");
l = fName.lastIndexOf("\\");
if (l>=0) fName = fName.substring(l+1);
if (fName.length()>0)
file = new FileOutputStream("\\var\\"+fName);
}
} else if (status.equals("boundary")) {
fName = null;
if (file!=null) {
file.close();
file = null;
}
}
4. How to save the uploaded data correctly? Saving the data is easy.
But the last line of the data contains an extra new line character.
I used a flag "holdNewLine" to hold the new line character if the
current line has one:
if (status.equals("data")) {
if (file!=null) {
if (holdNewLine) file.write(crlf);
file.write(line,0,i);
holdNewLine = hasNewLine;
......
}
Conclusion
- RFC 1867 defines a new HTML input type, FILE, for the browser to collect
files to update.
- RFC 1867 defines a new encryption type, multipart/form-data, for the browser
to upload files in the HTTP request body in a multi-part format.
- Uploaded files should be handled as binary data. The new line character
of the last line in the uploaded files should be removed.
- Be careful about saving uploaded files on a Web server.
They should be saved in a secure area. Web server should avoid using the
path name submitted by the browser. Web users could use it to damage your
server file system.
Part:
1
2
3
4
5
|