KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > HttpPost


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util;
11
12 import java.io.*;
13 import java.util.*;
14 import javax.servlet.http.HttpServletRequest JavaDoc;
15
16 import org.mmbase.util.xml.*;
17 import org.mmbase.util.logging.Logger;
18 import org.mmbase.util.logging.Logging;
19
20 /**
21  * HttpPost handles all the PostInformation
22  *
23  * @application SCAN. To port this, use of HttpPost by i.e. taglibs should be replaced with the jakarta FileUpload code.
24  * @version $Id: HttpPost.java,v 1.28 2004/09/30 08:52:11 pierre Exp $
25  * @author Daniel Ockeloen
26  * @author Rico Jansen
27  * @author Rob Vermeulen
28  */

29 public class HttpPost {
30
31     // logger
32
private static Logger log = Logging.getLoggerInstance(HttpPost.class);
33
34     public static final String JavaDoc CONFIG_FILE = "httppost.xml";
35
36     public static final String JavaDoc MAX_REQUEST_SIZE_PROPERTY = "maxrequestsize";
37     public static final String JavaDoc MAX_IN_MEMORY_PARAMETER_SIZE_PROPERTY = "maxinmemoryparametersize";
38     public static final String JavaDoc MAX_PARAMETER_SIZE_PROPERTY = "maxparametersize";
39     public static final String JavaDoc UPLOAD_DIR_PROPERTY = "uploaddir";
40
41     public static final int DEFAULT_MAX_REQUEST_SIZE = 4 * 1024 * 1024; // 4 MB
42
public static final int DEFAULT_MAX_PARAMETER_SIZE = 4 * 1024 * 1024;//4 MB
43
public static final int DEFAULT_MAX_IN_MEMORY_PARAMETER_SIZE =4 * 1024 * 1024; // 2 MB
44

45     private int maxRequestSize = DEFAULT_MAX_REQUEST_SIZE;
46     private int maxParameterSize = DEFAULT_MAX_PARAMETER_SIZE;
47     private int maxInMemoryParameterSize = DEFAULT_MAX_IN_MEMORY_PARAMETER_SIZE;
48     private String JavaDoc uploadDir = "/tmp/";
49
50     /**
51      * HttpPost only starts reading the request once a parameter is asked
52      */

53     private boolean isRequestDecoded = false;
54
55     /**
56      * if post Parameters are decoded to disk they have this postid
57      */

58     private long postid;
59
60     /**
61     * post buffer, holds the values ones decoded
62     */

63     private Hashtable postValues = new Hashtable();
64
65     /**
66      * Some postparameters are decoded to disk
67      */

68     private boolean isPostedToDisk = false;
69
70     private HttpServletRequest JavaDoc req = null;
71
72     private static UtilReader utilReader = new UtilReader(CONFIG_FILE);
73
74     int maxLoop = 20000;
75
76     /**
77      * Initialise WorkerPostHandler
78      */

79     public HttpPost(HttpServletRequest JavaDoc req) {
80         this.req = req;
81
82         Map properties = utilReader.getProperties();
83         setProperties(properties);
84         postid = System.currentTimeMillis();
85         if (log.isDebugEnabled()) {
86             log.debug("initialized HttpPost (maxRequestSize,maxParameterSize,maxInMemoryParameterSize)=(" + maxRequestSize + "," + maxParameterSize + "," + maxInMemoryParameterSize + ")");
87         }
88     }
89
90     /**
91      * Destuctor removes the tmp-files
92      */

93     protected void finalize() {
94         reset();
95     }
96
97     /**
98      * resets WorkerPosthandler
99      */

100     public void reset() {
101         /* removing postValueFiles */
102         if (isPostedToDisk) {
103             File f = new File(uploadDir);
104             File[] files = f.listFiles();
105             for (int i = 0; i < files.length; i++) {
106                 if (files[i].getName().indexOf("form_" + postid) == 0) {
107                     files[i].delete();
108                 }
109             }
110         }
111         postid = 0; // reset postid value
112
isPostedToDisk = false; // default, write postValues to memory
113
}
114
115     /**
116     * This method checks if the parameter is a multivalued one
117     * (as returned by a multiple select form) it returns true
118     * if so and false if not. It will also return false when
119     * the parameter doesn't exist.
120     * @see #getPostMultiParameter
121     * @see #getPostParameter
122     */

123     public boolean checkPostMultiParameter(String JavaDoc name) throws PostValueToLargeException {
124         if (!isRequestDecoded) {
125             decodePost(req);
126         }
127
128         Object JavaDoc obj = postValues.get(name);
129         if (obj != null && obj instanceof Vector) {
130             return true;
131         }
132         return false;
133     }
134
135     /**
136     * This method returns the Hashtable containing the POST information.
137     * Use of this method is discouraged.
138     * Instead use getPostMultiParameter, getPostParameter and checkPostMulitparameter
139     * @see #getPostMultiParameter
140     * @see #getPostParameter
141     * @see #checkPostMultiParameter
142     */

143     public Hashtable getPostParameters() throws PostValueToLargeException {
144         if (!isRequestDecoded) {
145             decodePost(req);
146         }
147         return postValues;
148     }
149
150     /**
151     * This method returns the value of the postparameter as a String.
152     * If it is a parameter with multiple values it returns the first one.
153     * @see #getPostMultiParameter
154     * @see #checkPostMultiParameter
155     * @exception PostValueToLargeException will be thrown when the postParameterValue
156     * is saved on disk instead of memory.
157     */

158     public byte[] getPostParameterBytes(String JavaDoc name) throws PostValueToLargeException {
159         // decode when not done yet..
160
if (!isRequestDecoded) {
161             decodePost(req);
162         }
163
164         // when the parameter was not found, return null
165
Object JavaDoc obj = postValues.get(name);
166         if (obj == null) {
167             return null;
168         }
169
170         // when it is an instance of String throw the exeption
171
if (obj instanceof String JavaDoc) {
172             String JavaDoc msg = "Use getPostParameterFile";
173             log.warn(msg);
174             throw new PostValueToLargeException("Use getPostParameterFile");
175         }
176         if (obj instanceof Vector) {
177             Vector v = (Vector)obj;
178             byte[] data = (byte[])v.elementAt(0);
179             return data;
180         }
181         byte[] data = (byte[])obj;
182         return data;
183     }
184
185     /**
186     * This method returns the value of the postparameter as a Vector.
187     * In case of a parameter with one value, it returns it as a Vector
188     * with one element.
189     * it also converts the byte[] into strings
190     * @see #checkPostMultiParameter
191     */

192     public Vector getPostMultiParameter(String JavaDoc name) throws PostValueToLargeException {
193         return getPostMultiParameter(name, null);
194     }
195
196     /**
197     * This method returns the value of the postparameter as a Vector.
198     * In case of a parameter with one value, it returns it as a Vector
199     * with one element.
200     * it also converts the byte[] into strings
201     * @see #checkPostMultiParameter
202     */

203     public Vector getPostMultiParameter(String JavaDoc name, String JavaDoc encoding) throws PostValueToLargeException {
204
205         // decode when not done yet..
206
if (!isRequestDecoded) {
207             decodePost(req);
208         }
209
210         // when the parameter was not found, return null
211
Object JavaDoc obj = postValues.get(name);
212         if (obj == null) {
213             return null;
214         }
215
216         Vector results = new Vector();
217         if (obj instanceof Vector) {
218             Vector v = (Vector)obj;
219             Enumeration e = v.elements();
220             while (e.hasMoreElements()) {
221                 Object JavaDoc o = e.nextElement();
222                 if (o.getClass().isArray()) {
223                     byte[] data = (byte[])o;
224                     results.addElement(getString(data, encoding));
225                 } else {
226                     if (!(o instanceof String JavaDoc)) {
227                         log.warn("unknown data type " + o.getClass().getName() + " for parameter " + name);
228                     }
229                     results.addElement(o);
230                 }
231             }
232         } else {
233             // we assume that obj will be byte[]
234
byte[] data = (byte[])obj;
235             results.addElement(getString(data, encoding));
236         }
237         return results;
238     }
239
240     private static String JavaDoc getString(byte[] data, String JavaDoc encoding) {
241         if (encoding == null) {
242             return new String JavaDoc(data);
243         }
244         try {
245             return new String JavaDoc(data, encoding);
246         } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
247             log.warn("encoding was:" + encoding + "\n" + Logging.stackTrace(uee));
248             return new String JavaDoc(data);
249         }
250     }
251
252     /**
253      * @return true if the post was posted to a file (not in memory)
254      * @since MMBase-1.7
255      **/

256     public boolean isPostedToFile() {
257         return isPostedToDisk;
258     }
259
260     /**
261     * This method returns the filename containing the postparametervalue
262     * If it is a parameter with multiple values it returns the first one.
263     * @see #getPostMultiParameter
264     * @see #checkPostMultiParameter
265     */

266     public String JavaDoc getPostParameterFile(String JavaDoc name) throws PostValueToLargeException {
267         Object JavaDoc obj = null;
268         Vector v;
269
270         if (!isRequestDecoded) {
271             decodePost(req);
272         }
273         if ((obj = postValues.get(name)) != null) {
274             // convert byte[] into filename
275
if (!(obj instanceof String JavaDoc)) {
276                 isPostedToDisk = true;
277                 File file = new File(new File(uploadDir), "form_" + postid + "_" + name);
278                 RandomAccessFile raf = null;
279                 try {
280                     raf = new RandomAccessFile(file, "rw");
281                     if (obj instanceof Vector) {
282                         v = (Vector)obj;
283                         raf.write((byte[])v.elementAt(0));
284                     } else {
285                         raf.write((byte[])obj);
286                     }
287                     raf.close();
288                 } catch (Exception JavaDoc e) {
289                     log.error("getPostParameterFile(" + name + "): " + e);
290                 }
291                 return file.getPath();
292             }
293
294             if (obj instanceof Vector) {
295                 v = (Vector)obj;
296                 return (String JavaDoc)v.elementAt(0);
297             } else {
298                 return (String JavaDoc)obj;
299             }
300         } else {
301             return null;
302         }
303     }
304
305     /**
306     * This method returns the value of the postparameter as a String.
307     * If it is a parameter with multiple values it returns the first one.
308     * @see #getPostMultiParameter
309     * @see #checkPostMultiParameter
310     */

311     public String JavaDoc getPostParameter(String JavaDoc name) throws PostValueToLargeException {
312         Object JavaDoc obj = null;
313         Vector v;
314
315         if (!isRequestDecoded) {
316             decodePost(req);
317         }
318
319         if ((obj = postValues.get(name)) != null) {
320             try {
321                 if (obj instanceof String JavaDoc) {
322                     throw new PostValueToLargeException("Use getPostParameterFile");
323                 }
324                 // Catch the exception right here, it should be thrown but
325
// that's against the Servlet-API Interface
326
} catch (Exception JavaDoc e) {
327                 log.error("getPostParameter(" + name + "): " + e);
328             }
329
330             if (obj instanceof Vector) {
331                 v = (Vector)obj;
332                 Object JavaDoc elem = v.elementAt(0);
333                 if (elem instanceof String JavaDoc) {
334                     return (String JavaDoc)elem;
335                 } else {
336                     return new String JavaDoc((byte[])v.elementAt(0));
337                 }
338             } else {
339                 return new String JavaDoc((byte[])obj);
340             }
341         } else {
342             return null;
343         }
344     }
345
346     private void decodePost(HttpServletRequest JavaDoc req) throws PostValueToLargeException {
347         isRequestDecoded = true;
348         byte[] postbuffer = null;
349
350         if (req.getHeader("Content-length") != null || req.getHeader("Content-Length") != null) {
351             postbuffer = readContentLength(req);
352             String JavaDoc line = (String JavaDoc)req.getHeader("Content-type");
353             if (line == null) {
354                 line = (String JavaDoc)req.getHeader("Content-Type");
355             }
356
357             if (line != null) {
358                 if (line.indexOf("application/x-www-form-urlencoded") != -1) {
359                     readPostUrlEncoded(postbuffer, postValues);
360                 } else if (line.indexOf("multipart/form-data") != -1) {
361                     if (!isPostedToDisk) {
362                         readPostFormData(postbuffer, postValues, line);
363                     } else {
364                         readPostFormData( new File(uploadDir,"form_" + postid).getPath(), postValues, line);
365                     }
366                 } else {
367                     log.error("decodePost(): found no 'post' tag in post.");
368                 }
369             } else {
370                 log.error("decodePost(): can't find Content-Type");
371             }
372         } else {
373             log.error("decodePost(): found no 'content-length' tag in post.");
374         }
375     }
376
377     /**
378     * read a block into a array of ContentLenght size from the users networksocket
379     *
380     * @param table the hashtable that is used as the source for the mapping process
381     * @return byte[] buffer of length defined in the content-length mimeheader
382     */

383     public byte[] readContentLength(HttpServletRequest JavaDoc req) throws PostValueToLargeException {
384         int len, len2, len3;
385         byte buffer[] = null;
386         DataInputStream connect_in = null;
387
388         int i = 0;
389
390         try {
391             connect_in = new DataInputStream(req.getInputStream());
392         } catch (Exception JavaDoc e) {
393             log.error("readContentLength(): can't open input stream");
394         }
395
396         len = req.getContentLength();
397         // Maximum postsize
398
if (len < maxInMemoryParameterSize) {
399             log.debug("readContentLength(): writing to memory.");
400             try {
401                 buffer = new byte[len];
402                 len2 = connect_in.read(buffer, 0, len);
403                 while (len2 < len && i < maxLoop) {
404                     log.debug("readContentLength(): found len2( " + len2 + ")");
405                     len3 = connect_in.read(buffer, len2, len - len2);
406                     if (len3 == -1) {
407                         log.debug("readContentLength(): WARNING: EOF while not Content Length");
408                         break;
409                     } else {
410                         len2 += len3;
411                     }
412                     i++;
413                 }
414                 if (i >= maxLoop) {
415                     log.info("readContentLength(): (memory) broken out of loop after " + i + " times");
416                 }
417             } catch (Exception JavaDoc e) {
418                 log.error("readContentLength(): Can't read post msg from client");
419                 log.error(Logging.stackTrace(e));
420                 buffer[len - 1] = -1;
421                 // just to return _something_...
422
// Mozilla 0.9.7 (and 0.9.6?) had a bug here. Now they are only slow, but work, if you don't supply a file...
423

424             }
425         } else if (len < maxParameterSize) {
426             log.debug("readContentLength(): writing to disk");
427             try {
428                 isPostedToDisk = true;
429                 RandomAccessFile raf = new RandomAccessFile(new File(uploadDir,"form_" + postid), "rw");
430                 int bufferlength = 64000;
431                 buffer = new byte[bufferlength];
432                 int index1 = 0, totallength = 0;
433
434                 index1 = connect_in.read(buffer);
435                 raf.write(buffer, 0, index1);
436                 totallength += index1;
437                 log.debug("readContentLength(): writing to disk: +");
438
439                 while (totallength < len && i < maxLoop) {
440                     index1 = connect_in.read(buffer);
441                     raf.write(buffer, 0, index1);
442                     if (index1 == -1) {
443                         log.error("readContentLength(): EOF while not Content Length");
444                         break;
445                     } else {
446                         totallength += index1;
447                     }
448                     i++;
449                 }
450                 if (i >= maxLoop) {
451                     log.info("readContentLength(): (disk) broken out of loop after " + i + " times");
452                 }
453                 log.info(" written(" + totallength + ")");
454                 raf.close();
455             } catch (Exception JavaDoc e) {
456                 log.error("readContentLength(): " + e);
457             }
458         } else {
459             log.error("readContentLength(): post too large: " + len + " size");
460             throw new PostValueToLargeException("post size to large (actual,allowed)" + len + "," + maxRequestSize + ")");
461         }
462         return buffer;
463     }
464
465     /**
466      * Extra disposition info, e.g.
467      * Content-Disposition: form-data; name="file"; filename="cees.gif"
468      *
469      * @return String array with respectively dispositon, fieldname, and filename
470      */

471     private String JavaDoc[] extractDispositionInfo(String JavaDoc line) throws IOException {
472         String JavaDoc[] retval = new String JavaDoc[3];
473
474         // Convert the line to a lowercase string without the ending \r\n
475
// Keep the original line for error messages and for variable names
476
String JavaDoc origline = line;
477         line = origline.toLowerCase();
478
479         // Get the content disposition, should be "form-data"
480
int start = line.indexOf("content-disposition: ");
481         int end = line.indexOf(";");
482         if (start == -1 || end == -1) {
483             throw new IOException("Content disposition corrupt: " + origline);
484         }
485         String JavaDoc disposition = line.substring(start + 21, end);
486         if (!disposition.equals("form-data")) {
487             throw new IOException("Invalid content disposition: " + disposition);
488         }
489
490         // Get the field name
491
start = line.indexOf("name=\"", end); // start at last semicolon
492
end = line.indexOf("\"", start + 7); // skip name=\"
493
if (start == -1 || end == -1) {
494             throw new IOException("Content disposition corrupt: " + origline);
495         }
496         String JavaDoc name = origline.substring(start + 6, end);
497
498         // Get the filename, if give
499
String JavaDoc filename = null;
500         start = line.indexOf("filename=\"", end + 2); // start after name
501
end = line.indexOf("\"", start + 10); // skip filename=\"
502
if (start != -1 && end != -1) { // note the !=
503
filename = origline.substring(start + 10, end);
504             // The filename may contain a full path. Cut to just the filename
505
int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
506             if (slash > -1) {
507                 filename = filename.substring(slash + 1); // past last slash
508
}
509
510             if (filename.equals("")) {
511                 filename = "unknown"; // sanity check
512
}
513
514         }
515
516         // Return a String array: disposition, fieldname, filename
517
retval[0] = disposition;
518         retval[1] = name;
519         retval[2] = filename;
520         return retval;
521     }
522
523     /**
524      * Content-type info, e.g.
525      * Content-type: image/gif
526      *
527      * @return String
528      */

529     private String JavaDoc extractContentType(String JavaDoc line) throws IOException {
530         String JavaDoc contentType = null;
531
532         // Convert the line to a lowercase string
533
String JavaDoc origline = line;
534         line = origline.toLowerCase();
535
536         // Get the content-type if any
537
if (line.startsWith("content-type")) {
538             int start = line.indexOf(" ");
539             if (start == -1) {
540                 throw new IOException("Content type corrupt: " + origline);
541             }
542             contentType = line.substring(start + 1);
543         } else if (line.length() != 0) { // no content type, so should be empty
544
throw new IOException("Malformed line after disposition: " + origline);
545         }
546
547         return contentType;
548     }
549
550     /**
551     * read post info from buffer, must be defined in multipart/form-data format.
552     *
553     * @param postbuffer buffer with the postbuffer information
554     * @param post_header hashtable to put the postbuffer information in
555     */

556     public boolean readPostFormData(byte[] postbuffer, Hashtable post_header, String JavaDoc line) {
557         int i2, i3, i4, start2, end2;
558         String JavaDoc r;
559         String JavaDoc templine = "--" + line.substring(line.indexOf("boundary=") + 9);
560         byte[] marker = new byte[templine.length()];
561         byte[] marker2 = new byte[4];
562         byte[] marker3 = new byte[1];
563         byte[] marker4 = new byte[1];
564         byte[] dest;
565         marker2[0] = (byte)'\r';
566         marker2[1] = (byte)'\n';
567         marker2[2] = (byte)'\r';
568         marker2[3] = (byte)'\n';
569         marker3[0] = (byte)'=';
570         marker4[0] = (byte)'\"';
571         templine.getBytes(0, templine.length(), marker, 0);
572
573         start2 = indexOf(postbuffer, marker, 0) + marker.length;
574
575         int z = 0;
576         do {
577             // hunt second one
578
end2 = indexOf(postbuffer, marker, start2);
579             if (end2 < 0) {
580                 log.error("readPostFormData(): postbuffer < 0 !!!! ");
581                 break;
582             }
583
584             // get all the data in between
585
i2 = indexOf(postbuffer, marker2, start2);
586
587             // [begin] I guess that the "content-disposition" is between the start2 and i2, -cjr
588
// XXX Quite messy, this code (until [end]) stands outside of the rest of the extraction code and
589
// partly overlaps, e.g. now name of field is extracted twice!
590
/**
591              * The code we are parsing here is like:
592              *
593              * Content-Disposition: form-data; name="file"; filename="cees.gif"
594              * Content-type: image/gif
595              *
596              */

597             String JavaDoc disposition = new String JavaDoc(postbuffer, start2 + 2, i2 - (start2 + 2));
598             int separator = indexOf(postbuffer, new byte[] {(byte)'\r', (byte)'\n' }, start2 + 2);
599
600             int filesize = (end2 - i2 - 6);
601             if (filesize < 0)
602                 filesize = 0; // some browser bugs
603
/**
604              * No separator in Content-disposition: .. implies that there is only a name,
605              * no filename, and hence that it is no file upload. The code under "if" above
606              * is applicable for file uploads only.
607              */

608             if (separator > start2 + 2 && separator < i2) {
609                 try {
610                     String JavaDoc[] dispositionInfo = extractDispositionInfo(disposition.substring(0, separator - (start2 + 2)));
611                     String JavaDoc mimetype = extractContentType(disposition.substring(separator - (start2 + 2) + 2));
612                     String JavaDoc fieldname = dispositionInfo[1];
613                     String JavaDoc filename = dispositionInfo[2];
614                     Vector v1 = new Vector();
615                     v1.addElement(mimetype.getBytes());
616                     addpostinfo(post_header, fieldname + "_type", v1);
617                     Vector v2 = new Vector();
618                     v2.addElement(filename.getBytes());
619                     addpostinfo(post_header, fieldname + "_name", v2);
620
621                     Vector v3 = new Vector();
622                     v3.addElement("" + filesize);
623                     addpostinfo(post_header, fieldname + "_size", v3);
624
625                     if (log.isDebugEnabled()) {
626                         log.debug("mimetype = " + mimetype);
627                         log.debug("filename = " + dispositionInfo[2]);
628                         log.debug("filesize = " + filesize);
629                     }
630                 } catch (IOException e) {
631                     log.error(e.getMessage());
632                 }
633             }
634             // [end]
635

636             i3 = indexOf(postbuffer, marker3, start2 + 2) + 2;
637             i4 = indexOf(postbuffer, marker4, i3 + 2);
638             //r = new String(postbuffer,)
639
r = new String JavaDoc(postbuffer, i3, (i4 - i3)); // extraction of fieldname
640
// log.debug("readPostFormData(): r="+r);
641
// copy it to a buffer
642
dest = new byte[filesize];
643             System.arraycopy(postbuffer, i2 + 4, dest, 0, filesize);
644             // r2=new String(postbuffer,0,i2+4,((end2-i2))-6);
645

646             addpostinfo(post_header, r, dest);
647             start2 = end2 + marker.length;
648             z++;
649         } while (postbuffer[start2] != '-' && z < maxLoop);
650         if (z >= maxLoop) {
651             log.info("readPostFormData: broken out of loop after " + z + " times");
652         }
653         return false;
654     }
655
656     /**
657     * read post info from buffer, must be defined in multipart/form-data format.
658     * Deze methode gaat in het beginsel alleen werken voor het uploaden van 1 bestand
659     * De te vinden markers kunnen anders op de scheiding liggen van 2 blokken
660     * Het kan dus voorkomen dat de marker op de scheiding ligt van 2 blokken ook dan
661     * zal deze methode falen.
662     *
663     * @param postbuffer buffer with the postbuffer information
664     * @param post_header hashtable to put the fromFile information in
665     */

666     public boolean readPostFormData(String JavaDoc formFile, Hashtable post_header, String JavaDoc line) {
667         FileInputStream fis = null;
668         RandomAccessFile raf = null;
669         try {
670             fis = new FileInputStream(formFile);
671         } catch (Exception JavaDoc e) {
672             System.out.println("WorkerPostHandler -> File " + formFile + " not exist");
673         }
674         int i, i2, i3, i4, start2, end2;
675         String JavaDoc r;
676         String JavaDoc templine = "--" + line.substring(line.indexOf("boundary=") + 9);
677         byte[] marker = new byte[templine.length()];
678         byte[] marker2 = new byte[4];
679         byte[] marker3 = new byte[1];
680         byte[] marker4 = new byte[1];
681         byte[] dest;
682         marker2[0] = (byte)'\r';
683         marker2[1] = (byte)'\n';
684         marker2[2] = (byte)'\r';
685         marker2[3] = (byte)'\n';
686         marker3[0] = (byte)'=';
687         marker4[0] = (byte)'\"';
688         templine.getBytes(0, templine.length(), marker, 0);
689         log.info("readPostFormData(): begin");
690
691         int offset = 0;
692         // int temp=0;
693
int len = 64000;
694         byte postbuffer[] = new byte[len];
695         try {
696             // Lees eerst stuk van het bestand.
697
len = fis.read(postbuffer);
698
699             // find first magic cookie
700
start2 = indexOf(postbuffer, marker, 0) + marker.length;
701             i = 0;
702             do {
703                 // Get keyword
704
i3 = indexOf(postbuffer, marker3, start2 + 2) + 2;
705                 i4 = indexOf(postbuffer, marker4, i3 + 2);
706                 r = new String JavaDoc(postbuffer, i3, (i4 - i3));
707                 log.debug("readPostFormData(): postName=" + r);
708
709                 // hunt second one
710
end2 = indexOf(postbuffer, marker, start2);
711                 i2 = indexOf(postbuffer, marker2, start2);
712
713                 if (end2 == -1) {
714                     log.info("readPostFormData(): writing to postValue: ");
715                     File f = new File(uploadDir,"form_" + postid + "_" + r);
716                     raf = new RandomAccessFile(f, "rw");
717                     addpostinfo(post_header, r, f.getPath());
718                     try {
719                         raf.write(postbuffer, i2 + 4, len - (i2 + 4));
720                     } catch (Exception JavaDoc e) {
721                         log.error("readPostFormData(): Cannot write into file(1)" + e);
722                     }
723                     offset = len - i2 + 4;
724                     int j = 0;
725                     do {
726                         // should we do something with temp? it is never read again
727
//temp =
728
fis.read(postbuffer);
729
730                         end2 = indexOf(postbuffer, marker, 0);
731                         if (end2 == -1) {
732                             raf.write(postbuffer);
733                         } else {
734                             raf.write(postbuffer, 0, end2 - 2);
735                         }
736                         offset += len;
737                         j++;
738                     } while (end2 == -1 && j < maxLoop);
739                     if (j >= maxLoop) {
740                         log.info("readPostFormData(): (inner) broken out of loop after " + j + " times");
741                     }
742                     start2 = end2 + marker.length;
743                     raf.close();
744                 } else {
745                     dest = new byte[(end2 - i2) - 6];
746                     System.arraycopy(postbuffer, i2 + 4, dest, 0, (end2 - i2) - 6);
747
748                     addpostinfo(post_header, r, dest);
749                     start2 = end2 + marker.length;
750                 }
751                 i++;
752             }
753             while (postbuffer[start2] != '-' && i < maxLoop);
754             if (i >= maxLoop) {
755                 log.info("readPostFormData(): (outer) broken out of loop after " + i + " times");
756             }
757         } catch (Exception JavaDoc e) {
758             log.error("readPostFormData(): Reached end of file: " + e);
759         }
760         return false;
761     }
762
763     private final void addpostinfo(Hashtable postinfo, String JavaDoc name, Object JavaDoc value) {
764         Object JavaDoc obj;
765         Vector v = null;
766
767         if (postinfo.containsKey(name)) {
768             obj = postinfo.get(name);
769             if (obj instanceof byte[]) {
770                 v = new Vector();
771                 v.addElement((byte[])obj); // Add the first one
772
v.addElement(value); // Then the one given
773
postinfo.put(name, v);
774             } else if (obj instanceof Vector) {
775                 v = (Vector)obj;
776                 v.addElement(value);
777             } else {
778                 log.error("addpostinfo(" + name + "," + value + "): object " + v + " is not Vector or byte[]");
779             }
780         } else {
781             postinfo.put(name, value);
782         }
783     }
784
785     private final void addpostinfo2(Hashtable postinfo, String JavaDoc name, String JavaDoc values) {
786         Object JavaDoc obj;
787         Vector v = null;
788
789         byte[] value = new byte[values.length()];
790         values.getBytes(0, values.length(), value, 0);
791
792         if (postinfo.containsKey(name)) {
793             obj = postinfo.get(name);
794             if (obj instanceof byte[]) {
795                 v = new Vector();
796                 v.addElement((byte[])obj); // Add the first one
797
v.addElement(value); // Then add the current one
798
postinfo.put(name, v);
799             } else if (obj instanceof Vector) {
800                 v = (Vector)obj;
801                 v.addElement(value);
802             } else {
803                 log.error("addpostinfo(" + name + "," + value + "): object " + v + " is not Vector or byte[]");
804             }
805         } else {
806             postinfo.put(name, value);
807         }
808     }
809
810     /**
811     * read post info from buffer, must be defined in UrlEncode format.
812     *
813     * @param postbuffer buffer with the postbuffer information
814     * @param post_header hashtable to put the postbuffer information in
815     */

816     private boolean readPostUrlEncoded(byte[] postbuffer, Hashtable post_header) {
817         String JavaDoc mimestr = "";
818         int i = 0, idx;
819         char letter;
820
821         String JavaDoc buffer = new String JavaDoc(postbuffer);
822         buffer = buffer.replace('+', ' ');
823         StringTokenizer tok = new StringTokenizer(buffer, "&");
824         int z = 0;
825         while (tok.hasMoreTokens() && i < maxLoop) {
826             mimestr = tok.nextToken();
827             if ((idx = mimestr.indexOf('=')) != -1) {
828                 while ((i = mimestr.indexOf('%', i)) != -1) {
829                     // Unescape the 'invalids' in the buffer (%xx) form
830
try {
831                         letter = (char)Integer.parseInt(mimestr.substring(i + 1, i + 3), 16);
832                         mimestr = mimestr.substring(0, i) + letter + mimestr.substring(i + 3);
833                     } catch (Exception JavaDoc e) {}
834
835                     i++;
836                 }
837                 addpostinfo2(post_header, mimestr.substring(0, idx), mimestr.substring(idx + 1));
838             } else {
839                 addpostinfo2(post_header, mimestr, "");
840             }
841             z++;
842         }
843         if (z >= maxLoop) {
844             log.info("readPostUrlEncoded: broken out of loop after " + z + " times");
845         }
846         return true;
847     }
848
849     /**
850      * gives the index of a bytearray in a bytearray
851      *
852      * @param v1[] The bytearray the search in.
853      * @param v2[] The bytearray to find.
854      * @param fromindex An index ti search from.
855      * @return The index of v2[] in v1[], else -1
856      */

857     private int indexOf(byte v1[], byte v2[], int fromIndex) {
858
859         int max = (v1.length - v2.length);
860
861         // Yikes !!! Bij gebruik van continue test wordt de variable i (in de for) niet
862
// opnieuw gedeclareerd. continue test kan gezien worden als ga verder met de for.
863
// test is dus zeker GEEN label.
864
test : for (int i = ((fromIndex < 0) ? 0 : fromIndex); i <= max; i++) {
865             int n = v2.length;
866             int j = i;
867             int k = 0;
868             while (n-- != 0) {
869                 if (v1[j++] != v2[k++]) {
870                     continue test;
871                 }
872             }
873             return i;
874         }
875         return -1;
876     }
877
878     private void setProperties(Map properties) {
879         //keesj:sorry for this long code...
880
if (properties.containsKey(MAX_PARAMETER_SIZE_PROPERTY)) {
881             try {
882                 maxParameterSize = Integer.parseInt(properties.get(MAX_PARAMETER_SIZE_PROPERTY).toString());
883             } catch (NumberFormatException JavaDoc e) {
884                 log.warn("The value{" + properties.get(MAX_PARAMETER_SIZE_PROPERTY) + "} of property {" + MAX_PARAMETER_SIZE_PROPERTY + "} in file " + CONFIG_FILE + " is not a integer");
885             }
886         }
887
888         if (properties.containsKey(MAX_IN_MEMORY_PARAMETER_SIZE_PROPERTY)) {
889             try {
890                 maxInMemoryParameterSize = Integer.parseInt(properties.get(MAX_IN_MEMORY_PARAMETER_SIZE_PROPERTY).toString());
891             } catch (NumberFormatException JavaDoc e) {
892                 log.warn("The value{" + properties.get(MAX_IN_MEMORY_PARAMETER_SIZE_PROPERTY) + "} of property {" + MAX_IN_MEMORY_PARAMETER_SIZE_PROPERTY + "} in file " + CONFIG_FILE + " is not a integer");
893             }
894         }
895
896         if (properties.containsKey(MAX_REQUEST_SIZE_PROPERTY)) {
897             try {
898                 maxRequestSize = Integer.parseInt(properties.get(MAX_REQUEST_SIZE_PROPERTY).toString());
899             } catch (NumberFormatException JavaDoc e) {
900                 log.warn("The value{" + properties.get(MAX_REQUEST_SIZE_PROPERTY) + "} of property {" + MAX_REQUEST_SIZE_PROPERTY + "} in file " + CONFIG_FILE + " is not a integer");
901             }
902         }
903         if (properties.containsKey(UPLOAD_DIR_PROPERTY)) {
904             String JavaDoc tmpDir = properties.get(UPLOAD_DIR_PROPERTY).toString();
905             File file = new File(tmpDir);
906             if (file.exists() && file.isDirectory()) {
907                 uploadDir = tmpDir;
908             } else {
909                 log.warn("The value {" + properties.get(UPLOAD_DIR_PROPERTY) + "} of property {" + UPLOAD_DIR_PROPERTY + "} in file " + CONFIG_FILE + " is not a directory {" + file.getPath() + "}");
910             }
911             file = null;
912         }
913         // do some basic checks
914
if (maxInMemoryParameterSize > maxRequestSize){
915             log.warn(MAX_IN_MEMORY_PARAMETER_SIZE_PROPERTY + " is bigger then " + MAX_REQUEST_SIZE_PROPERTY);
916         }
917     }
918 }
919
Popular Tags