KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > base > util > HttpRequestFileUpload


1 /*
2  * $Id: HttpRequestFileUpload.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2001 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24
25 package org.ofbiz.base.util;
26
27
28 import java.io.File JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.util.Date JavaDoc;
32 import java.util.Dictionary JavaDoc;
33 import java.util.Hashtable JavaDoc;
34
35 import javax.servlet.ServletInputStream JavaDoc;
36 import javax.servlet.http.HttpServletRequest JavaDoc;
37
38
39 /**
40  * HttpRequestFileUpload - Receive a file upload through an HttpServletRequest
41  *
42  * @author Dustin Caldwell
43  * @version 1.0
44  */

45 public class HttpRequestFileUpload {
46
47     private int BUFFER_SIZE = 4096;
48     private int WAIT_INTERVAL = 200; // in milliseconds
49
private int MAX_WAITS = 20;
50     private int waitCount = 0;
51     private String JavaDoc savePath;
52     private String JavaDoc filepath;
53     private String JavaDoc filename;
54     private String JavaDoc contentType;
55     private String JavaDoc overrideFilename = null;
56     private Dictionary JavaDoc fields;
57
58     public String JavaDoc getOverrideFilename() {
59         return overrideFilename;
60     }
61
62     public void setOverrideFilename(String JavaDoc ofName) {
63         overrideFilename = ofName;
64     }
65
66     public String JavaDoc getFilename() {
67         return filename;
68     }
69
70     public String JavaDoc getFilepath() {
71         return filepath;
72     }
73
74     public void setSavePath(String JavaDoc savePath) {
75         this.savePath = savePath;
76     }
77
78     public String JavaDoc getContentType() {
79         return contentType;
80     }
81
82     public String JavaDoc getFieldValue(String JavaDoc fieldName) {
83         if (fields == null || fieldName == null)
84             return null;
85         return (String JavaDoc) fields.get(fieldName);
86     }
87
88     private void setFilename(String JavaDoc s) {
89         if (s == null)
90             return;
91
92         int pos = s.indexOf("filename=\"");
93
94         if (pos != -1) {
95             filepath = s.substring(pos + 10, s.length() - 1);
96             // Windows browsers include the full path on the client
97
// But Linux/Unix and Mac browsers only send the filename
98
// test if this is from a Windows browser
99
pos = filepath.lastIndexOf("\\");
100             if (pos != -1)
101                 filename = filepath.substring(pos + 1);
102             else
103                 filename = filepath;
104         }
105     }
106
107     private void setContentType(String JavaDoc s) {
108         if (s == null)
109             return;
110
111         int pos = s.indexOf(": ");
112
113         if (pos != -1)
114             contentType = s.substring(pos + 2, s.length());
115     }
116
117     public void doUpload(HttpServletRequest JavaDoc request) throws IOException JavaDoc {
118         ServletInputStream JavaDoc in = request.getInputStream();
119
120         /* System.out.println("Header:");
121          Enumeration ee = request.getHeaderNames();
122          while(ee.hasMoreElements()) {
123          String ss = (String)ee.nextElement();
124          System.out.println(ss + " = [" + request.getHeader(ss) + "]");
125          }*/

126         String JavaDoc reqLengthString = request.getHeader("content-length");
127
128         System.out.println("expect " + reqLengthString + " bytes.");
129         int requestLength = 0;
130
131         try {
132             requestLength = new Integer JavaDoc(reqLengthString).intValue();
133         } catch (Exception JavaDoc e2) {
134             e2.printStackTrace();
135             return;
136         }
137         byte[] line = new byte[BUFFER_SIZE];
138
139         int i = -1;
140
141         i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
142         requestLength -= i;
143         if (i < 3)
144             return;
145         int boundaryLength = i - 2;
146
147         String JavaDoc boundary = new String JavaDoc(line, 0, boundaryLength); // -2 discards the newline character
148

149         System.out.println("boundary=[" + boundary + "] length is " + boundaryLength);
150         fields = new Hashtable JavaDoc();
151
152         while (requestLength > 0/* i != -1*/) {
153             String JavaDoc newLine = "";
154
155             if (i > -1) {
156                 newLine = new String JavaDoc(line, 0, i);
157             }
158             if (newLine.startsWith("Content-Disposition: form-data; name=\"")) {
159                 if (newLine.indexOf("filename=\"") != -1) {
160                     setFilename(new String JavaDoc(line, 0, i - 2));
161                     if (filename == null)
162                         return;
163                     // this is the file content
164
i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
165                     requestLength -= i;
166
167                     setContentType(new String JavaDoc(line, 0, i - 2));
168
169                     // blank line
170
i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
171                     requestLength -= i;
172                     newLine = new String JavaDoc(line, 0, i);
173                     String JavaDoc filenameToUse = filename;
174
175                     if (overrideFilename != null) {
176                         filenameToUse = overrideFilename;
177                     }
178
179                     // first line of actual file
180
i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
181                     requestLength -= i;
182                     newLine = new String JavaDoc(line, 0, i);
183
184                     byte[] lastTwoBytes = new byte[2];
185
186                     if (i > 1) {
187                         lastTwoBytes[0] = line[i - 2];
188                         lastTwoBytes[1] = line[i - 1];
189                     }
190                     System.out.println("about to create a file:" + (savePath == null ? "" : savePath) + filenameToUse);
191                     // before creating the file make sure directory exists
192
File JavaDoc savePathFile = new File JavaDoc(savePath);
193                     if (!savePathFile.exists()) {
194                         savePathFile.mkdirs();
195                     }
196                     FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc((savePath == null ? "" : savePath) + filenameToUse);
197                     boolean bail = (new String JavaDoc(line, 0, i).startsWith(boundary));
198                     boolean oneByteLine = (i == 1); // handle one-byte lines
199

200                     while ((requestLength > 0/* i != -1*/) && !bail) {
201
202                         // write the current buffer, except the last 2 bytes;
203
if (i > 1) {
204                             fos.write(line, 0, i - 2);
205                         }
206
207                         oneByteLine = (i == 1); // we need to track on-byte lines differently
208

209                         i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
210                         requestLength -= i;
211
212                         // the problem is the last line of the file content
213
// contains the new line character.
214

215                         // if the line just read was the last line, we're done.
216
// if not, we must write the last 2 bytes of the previous buffer
217
// just assume that a one-byte line isn't the last line
218

219                         if (requestLength < 1) {
220                             bail = true;
221                         } else if (oneByteLine) {
222                             fos.write(lastTwoBytes, 0, 1); // we only saved one byte
223
} else {
224                             fos.write(lastTwoBytes, 0, 2);
225                         }
226
227                         if (i > 1) {
228                             // save the last 2 bytes of the buffer
229
lastTwoBytes[0] = line[i - 2];
230                             lastTwoBytes[1] = line[i - 1];
231                         } else {
232                             lastTwoBytes[0] = line[0]; // only save one byte
233
}
234                     }
235                     fos.flush();
236                     fos.close();
237                 } else {
238                     // this is a field
239
// get the field name
240
int pos = newLine.indexOf("name=\"");
241                     String JavaDoc fieldName = newLine.substring(pos + 6, newLine.length() - 3);
242
243                     // System.out.println("fieldName:" + fieldName);
244
// blank line
245
i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
246                     requestLength -= i;
247                     i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
248                     requestLength -= i;
249                     newLine = new String JavaDoc(line, 0, i);
250                     StringBuffer JavaDoc fieldValue = new StringBuffer JavaDoc(BUFFER_SIZE);
251
252                     while (requestLength > 0/* i != -1*/ && !newLine.startsWith(boundary)) {
253                         // The last line of the field
254
// contains the new line character.
255
// So, we need to check if the current line is
256
// the last line.
257
i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
258                         requestLength -= i;
259                         if ((i == boundaryLength + 2 || i == boundaryLength + 4) // + 4 is eof
260
&& (new String JavaDoc(line, 0, i).startsWith(boundary)))
261                             fieldValue.append(newLine.substring(0, newLine.length() - 2));
262                         else
263                             fieldValue.append(newLine);
264                         newLine = new String JavaDoc(line, 0, i);
265                     }
266                     // System.out.println("fieldValue:" + fieldValue.toString());
267
fields.put(fieldName, fieldValue.toString());
268                 }
269             }
270             i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
271             if (i > -1) {
272                 requestLength -= i;
273             }
274
275         } // end while
276
}
277
278     // reads a line, waiting if there is nothing available and reqLen > 0
279
private int waitingReadLine(ServletInputStream JavaDoc in, byte[] buf, int off, int len, int reqLen) throws IOException JavaDoc {
280         int i = -1;
281
282         while (((i = in.readLine(buf, off, len)) == -1) && (reqLen > 0)) {
283             System.out.print("waiting");
284             if (waitCount > MAX_WAITS) {
285                 System.out.println("waited " + waitCount + " times, bailing out while still expecting " +
286                     reqLen + " bytes.");
287                 throw new IOException JavaDoc("waited " + waitCount + " times, bailing out while still expecting " +
288                         reqLen + " bytes.");
289             }
290             waitCount++;
291             long endMS = new Date JavaDoc().getTime() + WAIT_INTERVAL;
292
293             while (endMS > (new Date JavaDoc().getTime())) {
294                 try {
295                     wait(WAIT_INTERVAL);
296                 } catch (Exception JavaDoc e3) {
297                     System.out.print(".");
298                 }
299             }
300             System.out.println((new Date JavaDoc().getTime() - endMS) + " ms");
301         }
302         return i;
303     }
304 }
305
Popular Tags