KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opencms > core > CmsRequestHttpServlet


1 /*
2 * File : $Source: /usr/local/cvs/opencms/src-modules/com/opencms/core/CmsRequestHttpServlet.java,v $
3 * Date : $Date: 2005/06/21 15:49:59 $
4 * Version: $Revision: 1.3 $
5 *
6 * This library is part of OpenCms -
7 * the Open Source Content Mananagement System
8 *
9 * Copyright (C) 2001 The OpenCms Group
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * For further information about OpenCms, please see the
22 * OpenCms Website: http://www.opencms.org
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */

28
29 package com.opencms.core;
30
31 import org.opencms.main.CmsLog;
32 import org.opencms.main.OpenCms;
33 import org.opencms.util.CmsResourceTranslator;
34
35 import java.io.ByteArrayOutputStream JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.util.Enumeration JavaDoc;
38 import java.util.Hashtable JavaDoc;
39 import java.util.StringTokenizer JavaDoc;
40
41 import javax.servlet.http.HttpServletRequest JavaDoc;
42 import javax.servlet.http.HttpSession JavaDoc;
43
44 import org.apache.commons.logging.Log;
45
46 /**
47  * Implementation of the I_CmsRequest interface which wraps a HttpServletRequest
48  * and includes handling of multipart - requests.<p>
49  *
50  * This implementation uses a HttpServletRequest as original request to create a
51  * CmsRequestHttpServlet. This either can be a normal HttpServletRequest or a
52  * CmsMultipartRequest which is used to upload file into the OpenCms.<p>
53  *
54  * This class contains a modification of the MultipartRequest published in the O'Reilly
55  * book <it>Java Servlet Programming </it> by J. Junte, <a HREF=http://www.servlets.com/ > www.servlets.com </a>
56  * <p>
57  * It Constructs a new MultipartRequest to handle the specified request,
58  * saving any uploaded files to the given directory, and limiting the upload size to
59  * a maximum size of 8 MB by default.
60  * <p>
61  * The idea is to modify the given MultiPartRequest to make it transparent to normal
62  * requests and store file into CmsFile objects so that they can be transferred into
63  * the OpenCms document database.
64  *
65  * @author Michael Emmerich
66  * @author Alexander Lucas
67  *
68  * @version $Revision: 1.3 $ $Date: 2005/06/21 15:49:59 $
69  *
70  * @deprecated Will not be supported past the OpenCms 6 release.
71  */

72 public class CmsRequestHttpServlet implements I_CmsRequest {
73
74     /**
75      * Definition of the error message for missing boundary.
76      */

77     static final String JavaDoc C_REQUEST_NOBOUNDARY = "Separation boundary was not specified";
78
79     /**
80      * Definition of the error message for being not a multipart request.
81      */

82     static final String JavaDoc C_REQUEST_NOMULTIPART = "Posted content type isn't multipart/form-data";
83
84     /**
85      * Definition of the error message for an empty request.
86      */

87     static final String JavaDoc C_REQUEST_NOTNULL = "The Request cannot be null.";
88
89     /**
90      * Definition of the error message for a premature end.
91      */

92     static final String JavaDoc C_REQUEST_PROMATUREEND = "Corrupt form data: premature ending";
93
94     /**
95      * Definition of the error message for a negative maximum post size.
96      */

97     static final String JavaDoc C_REQUEST_SIZENOTNEGATIVE = "The maxPostSize must be positive.";
98
99     /** The log object for this class. */
100     private static final Log LOG = CmsLog.getLog(CmsRequestHttpServlet.class);
101     
102     /**
103      * File counter.
104      */

105     int m_filecounter;
106
107     /**
108      * Storage for all uploaded files.
109      */

110     private Hashtable JavaDoc m_files = new Hashtable JavaDoc();
111
112     /**
113      * Storage for all uploaded name values.
114      */

115     private Hashtable JavaDoc m_parameters = new Hashtable JavaDoc();
116
117     /**
118      * The original request.
119      */

120     private HttpServletRequest JavaDoc m_req;
121
122     /** String to the requested resource. */
123     private String JavaDoc m_requestedResource;
124     private String JavaDoc m_scheme="";
125     private String JavaDoc m_serverName="";
126     private int m_serverPort;
127     private String JavaDoc m_servletUrl="";
128
129     /**
130      * Resource translator (for uploaded file names).
131      */

132     private CmsResourceTranslator m_translator;
133     
134     /**
135      * The type of theis CmsRequest.
136      */

137     private int m_type = com.opencms.core.I_CmsConstants.C_REQUEST_HTTP;
138
139     /**
140      * The data from the original request. We save them to get them after the
141      * original request is expired.
142      */

143     private String JavaDoc m_webAppUrl="";
144
145     /**
146      * Constructor, creates a new CmsRequestHttpServlet object.
147      *
148      * @param req The original HttpServletRequest used to create this CmsRequest
149      * @param translator the translator
150      * @throws IOException if something goes wrong
151      */

152     public CmsRequestHttpServlet(HttpServletRequest JavaDoc req, CmsResourceTranslator translator) throws IOException JavaDoc {
153         m_req = req;
154         m_translator = translator;
155         
156         // get the webAppUrl and the servletUrl
157
try {
158             m_webAppUrl = m_req.getContextPath();
159         } catch (NoSuchMethodError JavaDoc err) {
160             // this is the old servlet-api without this method
161
// ignore this missing method and the context-path
162
}
163         m_serverName = m_req.getServerName();
164         m_scheme = m_req.getScheme();
165         m_serverPort = m_req.getServerPort();
166         m_servletUrl = m_webAppUrl + m_req.getServletPath();
167         // Test if this is a multipart-request.
168
// If it is, extract all files from it.
169
String JavaDoc type = req.getHeader("content-type");
170         if ((type != null) && type.startsWith("multipart/form-data") && (req.getContentLength() > -1)) {
171             readRequest();
172         } else {
173             // Encoding project:
174
// Set request content encoding
175
String JavaDoc encoding = req.getCharacterEncoding();
176             if (encoding == null) {
177                 // First try to get current encoding from session
178
HttpSession JavaDoc httpSession = req.getSession(false);
179                 I_CmsSession session = (httpSession != null)
180                     ? new CmsSession(httpSession) : null;
181                 if (session != null) {
182                     encoding = (String JavaDoc)session.getValue(
183                         com.opencms.core.I_CmsConstants.C_SESSION_CONTENT_ENCODING);
184                 }
185                 // If encoding not found in session - use default one
186
if (encoding == null) {
187                     encoding = OpenCms.getSystemInfo().getDefaultEncoding();
188                 }
189                 req.setCharacterEncoding(encoding);
190             }
191             if (LOG.isDebugEnabled()) {
192                 LOG.debug("Request character encoding is: '" + req.getCharacterEncoding() + "'");
193             }
194         }
195     }
196
197     /**
198      * Returns the content of an uploaded file.
199      * Returns null if no file with this name has been uploaded with this request.
200      * Returns an empty byte[] if a file without content has been uploaded.
201      *
202      * @param name The name of the uploaded file.
203      * @return The selected uploaded file content.
204      */

205     public byte[] getFile(String JavaDoc name) {
206         return (byte[])m_files.get(name);
207     }
208
209     /**
210      * Returns the names of all uploaded files in this request.
211      * Returns an empty eumeration if no files were included in the request.
212      *
213      * @return An Enumeration of file names.
214      */

215     public Enumeration JavaDoc getFileNames() {
216         Enumeration JavaDoc names = m_files.keys();
217         return names;
218     }
219
220     /**
221      * Returns the original request that was used to create the CmsRequest.
222      *
223      * @return The original request of the CmsRequest.
224      */

225     public HttpServletRequest JavaDoc getOriginalRequest() {
226         return m_req;
227     }
228
229     /**
230      * Returns the type of the request that was used to create the CmsRequest.
231      * The returned int must be one of the constants defined above in this interface.
232      *
233      * @return The type of the CmsRequest.
234      */

235     public int getOriginalRequestType() {
236         return m_type;
237     }
238
239     /**
240      * Returns the value of a named parameter as a String.
241      * Returns null if the parameter does not exist or an empty string if the parameter
242      * exists but without a value.
243      *
244      * @param name The name of the parameter.
245      * @return The value of the parameter.
246      */

247     public String JavaDoc getParameter(String JavaDoc name) {
248         String JavaDoc parameter = null;
249
250         // Test if this is a multipart-request.
251
// If it is, extract all files from it.
252
String JavaDoc type = m_req.getHeader("content-type");
253         if ((type != null) && type.startsWith("multipart/form-data")) {
254             parameter = (String JavaDoc)m_parameters.get(name);
255         } else {
256             parameter = m_req.getParameter(name);
257         }
258         return parameter;
259     }
260
261     /**
262      * Returns all parameter names as an Enumeration of String objects.
263      * Returns an empty Enumeratrion if no parameters were included in the request.
264      *
265      * @return Enumeration of parameter names.
266      */

267     public Enumeration JavaDoc getParameterNames() {
268         String JavaDoc type = m_req.getHeader("content-type");
269         if ((type != null) && type.startsWith("multipart/form-data")) {
270
271             // add all parameters extreacted in the multipart handling
272
return m_parameters.keys();
273         } else {
274
275             // add all parameters from the original request
276
return m_req.getParameterNames();
277         }
278     }
279
280     /**
281      * Returns all parameter values of a parameter key.
282      *
283      * @param key the parameter key
284      * @return Aarray of String containing the parameter values.
285      */

286     public String JavaDoc[] getParameterValues(String JavaDoc key) {
287         return m_req.getParameterValues(key);
288     }
289
290     /**
291      * This funtion returns the name of the requested resource.
292      * <P>
293      * For a http request, the name of the resource is extracted as follows:
294      * <CODE>http://{servername}/{servletpath}/{path to the cms resource}</CODE>
295      * In the following example:
296      * <CODE>http://my.work.server/servlet/opencms/system/def/explorer</CODE>
297      * the requested resource is <CODE>/system/def/explorer</CODE>.
298      * </P>
299      *
300      * @return The path to the requested resource.
301      */

302     public String JavaDoc getRequestedResource() {
303         if (m_requestedResource != null) {
304             return m_requestedResource;
305         }
306         m_requestedResource = m_req.getPathInfo();
307         if (m_requestedResource == null) {
308             m_requestedResource = "/";
309         }
310         return m_requestedResource;
311     }
312     /**
313      * Methods to get the data from the original request.
314      *
315      * @return the scheme
316      */

317     public String JavaDoc getScheme() {
318         return m_scheme;
319     }
320
321     /**
322      * Methods to get the data from the original request.
323      *
324      * @return the server name
325      */

326     public String JavaDoc getServerName() {
327         return m_serverName;
328     }
329     /**
330      * Methods to get the data from the original request.
331      *
332      * @return the server port
333      */

334     public int getServerPort() {
335         return m_serverPort;
336     }
337
338     /**
339      * Gets the part of the Url that describes the current servlet of this
340      * Web-Application.
341      *
342      * @return the servlet part of the url
343      */

344     public String JavaDoc getServletUrl() {
345         return m_servletUrl;
346     }
347
348     /**
349      * Returns the part of the Url that descibes the Web-Application.
350      *
351      * E.g: http://www.myserver.com/opencms/engine/index.html returns
352      * http://www.myserver.com/opencms
353      *
354      * @return the web application part of the url
355      */

356     public String JavaDoc getWebAppUrl() {
357         return m_webAppUrl;
358     }
359     
360     /**
361      * Overwrites the original request that was used to create the CmsRequest.
362      *
363      * @param request the request
364      */

365     public void setOriginalRequest(HttpServletRequest JavaDoc request) {
366         m_req = request;
367     }
368     
369     /**
370      * Set the name returned by getRequestedResource().
371      * This is required in case there was a folder name requested and
372      * a default file (e.g. index.html) has to be used instead of the folder.
373      *
374      * @param resourceName The name to set the requested resource name to
375      */

376     public void setRequestedResource(String JavaDoc resourceName) {
377         m_requestedResource = resourceName;
378     }
379
380     /**
381      * Extracts and returns the boundary token from a line.
382      *
383      * @param line with boundary from input stream.
384      * @return The boundary token.
385      */

386     private String JavaDoc extractBoundary(String JavaDoc line) {
387         int index = line.indexOf("boundary=");
388         if (index == -1) {
389             return null;
390         }
391
392         // 9 for "boundary="
393
String JavaDoc boundary = line.substring(index + 9);
394
395         // The real boundary is always preceeded by an extra "--"
396
boundary = "--" + boundary;
397         return boundary;
398     }
399
400     /**
401      * Extracts and returns the content type from a line, or null if the
402      * line was empty.
403      * @param line Line from input stream.
404      * @return Content type of the line.
405      * @throws IOException Throws an IOException if the line is malformatted.
406      */

407     private String JavaDoc extractContentType(String JavaDoc line) throws IOException JavaDoc {
408         String JavaDoc contentType = null;
409
410         // Convert the line to a lowercase string
411
String JavaDoc origline = line;
412         line = origline.toLowerCase();
413
414         // Get the content type, if any
415
if (line.startsWith("content-type")) {
416             int start = line.indexOf(" ");
417             if (start == -1) {
418                 throw new IOException JavaDoc("Content type corrupt: " + origline);
419             }
420             contentType = line.substring(start + 1);
421         } else {
422             if (line.length() != 0) {
423                 // no content type, so should be empty
424
throw new IOException JavaDoc("Malformed line after disposition: " + origline);
425             }
426         }
427         return contentType;
428     }
429
430     /**
431      * Extracts and returns disposition info from a line, as a String array
432      * with elements: disposition, name, filename. Throws an IOException
433      * if the line is malformatted.
434      *
435      * @param line Line from input stream.
436      * @return Array of string containing disposition information.
437      * @throws IOException if the line is malformatted
438      */

439     private String JavaDoc[] extractDispositionInfo(String JavaDoc line) throws IOException JavaDoc {
440
441         // Return the line's data as an array: disposition, name, filename
442
String JavaDoc[] retval = new String JavaDoc[3];
443
444         // Convert the line to a lowercase string without the ending \r\n
445
// Keep the original line for error messages and for variable names.
446
String JavaDoc origline = line;
447         line = origline.toLowerCase();
448
449         // Get the content disposition, should be "form-data"
450
int start = line.indexOf("content-disposition: ");
451         int end = line.indexOf(";");
452         if (start == -1 || end == -1) {
453             throw new IOException JavaDoc("Content disposition corrupt: " + origline);
454         }
455         String JavaDoc disposition = line.substring(start + 21, end);
456         if (!disposition.equals("form-data")) {
457             throw new IOException JavaDoc("Invalid content disposition: " + disposition);
458         }
459
460         // Get the field name
461
// start at last semicolon
462
start = line.indexOf("name=\"", end);
463
464         // skip name=\"
465
end = line.indexOf("\"", start + 7);
466         if (start == -1 || end == -1) {
467             throw new IOException JavaDoc("Content disposition corrupt: " + origline);
468         }
469         String JavaDoc name = origline.substring(start + 6, end);
470
471         // Get the filename, if given
472
String JavaDoc filename = null;
473
474         // start after name
475
start = line.indexOf("filename=\"", end + 2);
476
477         // skip filename=\"
478
end = line.indexOf("\"", start + 10);
479
480         // note the !=
481
if (start != -1 && end != -1) {
482             filename = origline.substring(start + 10, end);
483
484             // The filename may contain a full path. Cut to just the filename.
485
int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
486             if (slash > -1) {
487                 filename = filename.substring(slash + 1); // past last slash
488
}
489             if (filename.equals("")) {
490                 filename = "unknown"; // sanity check
491
}
492         }
493
494         // Translate the filename using the resource translator
495
filename = m_translator.translateResource(filename);
496
497         // Return a String array: disposition, name, filename
498
retval[0] = disposition;
499         retval[1] = name;
500         retval[2] = filename;
501         return retval;
502     }
503
504     /**
505      * A utility method that reads a single part of the multipart request
506      * that represents a file. Unlike the method name it does NOT saves the file to disk.
507      * The name is from the original O'Reilly implmentaton.
508      * <p>
509      * A subclass can override this method for a better optimized or
510      * differently behaved implementation.
511      *
512      * @param in The stream from which to read the file.
513      * @param boundary The boundary signifying the end of this part.
514      * @return the output
515      * @throws IOException If there's a problem reading or parsing the request.
516      */

517     private byte[] readAndSaveFile(CmsMultipartInputStreamHandler in, String JavaDoc boundary) throws IOException JavaDoc {
518         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc(8 * 1024);
519         byte[] boundaryBytes = boundary.getBytes();
520         int[] lookaheadBuf = new int[boundary.length() + 3];
521         int[] newLineBuf = {
522             -1, -1
523         };
524         int matches = 0;
525         int matchingByte = new Byte JavaDoc(boundaryBytes[matches]).intValue();
526
527         /*
528         File parts of multipart request should not be read line by line.
529         Since some servlet environments touch and change the new line
530         character(s) when calling the ServletInputStream's <code>readLine</code>
531         this may cause problems with binary file uploads.
532         We decided to read this parts byte by byte here.
533         */

534         int read = in.read();
535         while (read > -1) {
536             if (read == matchingByte) {
537
538                 // read byte is matching the next byte of the boundary
539
// we should not write to the output stream here.
540
lookaheadBuf[matches] = read;
541                 matches++;
542                 if (matches == boundary.length()) {
543
544                     // The end of the Boundary has been reached.
545
// Now snip the following line feed.
546
read = in.read();
547                     if (newLineBuf[1] == read) {
548
549                         // New line contains ONE single character.
550
// Write the last byte of the buffer to the output stream.
551
out.write(newLineBuf[0]);
552                     } else {
553
554                         // new line contains TWO characters, possibly "\r\n"
555
// The bytes in the buffer are not part of the file.
556
// We even have to read one more byte.
557
in.read();
558                     }
559                     break;
560                 }
561                 matchingByte = new Byte JavaDoc(boundaryBytes[matches]).intValue();
562             } else {
563
564                 // read byte does not match the next byte of the boundary
565
// write the first buffer byte to the output stream
566
if (newLineBuf[0] != -1) {
567                     out.write(newLineBuf[0]);
568                 }
569                 if (matches == 0) {
570
571                     // this may be the most propably case.
572
newLineBuf[0] = newLineBuf[1];
573                 } else {
574
575                     // we have started to read the boundary.
576
// Unfortunately, this was NOT the real boundary.
577
// Fall back to normal read mode.
578
// write the complete buffer to the output stream
579
if (newLineBuf[1] != -1) {
580                         out.write(newLineBuf[1]);
581                     }
582                     for (int i = 0; i < matches; i++) {
583                         out.write(lookaheadBuf[i]);
584                     }
585
586                     // reset boundary matching counter
587
matches = 0;
588                     matchingByte = new Byte JavaDoc(boundaryBytes[matches]).intValue();
589
590                     // clear buffer
591
newLineBuf[0] = -1;
592                 }
593
594                 // put the last byte read into the buffer.
595
// it may be part of a line feed.
596
newLineBuf[1] = read;
597             }
598             read = in.read();
599         }
600         out.flush();
601         return out.toByteArray();
602     }
603
604     /**
605      * A utility method that reads an individual part. Dispatches to
606      * readParameter() and readAndSaveFile() to do the actual work.
607      * <p>
608      * The single files are stored in a hashtable (seperated in filename and contents)
609      * for later addition to a CmsFile Object
610      * <p> A subclass can override this method for a better optimized or
611      * differently behaved implementation.
612      *
613      * @param in The stream from which to read the part
614      * @param boundary The boundary separating parts
615      * @return A flag indicating whether this is the last part
616      * @throws IOException If there's a problem reading or parsing the
617      * request
618      */

619     private boolean readNextPart(CmsMultipartInputStreamHandler in, String JavaDoc boundary) throws IOException JavaDoc {
620
621         // Read the first line, should look like this:
622
// content-disposition: form-data; name="field1"; filename="file1.txt"
623
String JavaDoc line = in.readLine();
624         if (line == null || line.equals("")) {
625
626             // No parts left, we're done
627
return true;
628         }
629
630         // Parse the content-disposition line
631
String JavaDoc[] dispInfo = extractDispositionInfo(line);
632
633         // String disposition = dispInfo[0];
634
String JavaDoc name = dispInfo[1];
635         String JavaDoc filename = dispInfo[2];
636
637         // Now onto the next line. This will either be empty
638
// or contain a Content-Type and then an empty line.
639
line = in.readLine();
640         if (line == null) {
641
642             // No parts left, we're done
643
return true;
644         }
645
646         // Get the content type, or null if none specified
647
String JavaDoc contentType = extractContentType(line);
648         if (contentType != null) {
649
650             // Eat the empty line
651
line = in.readLine();
652             if (line == null || line.length() > 0) { // line should be empty
653
line = in.readLine();
654                 if (line == null || line.length() > 0) { // line should be empty
655
throw new IOException JavaDoc("Malformed line after content type: " + line);
656                 }
657             }
658             
659         } else {
660
661             // Assume a default content type
662
contentType = "application/octet-stream";
663         }
664
665         // Now, finally, we read the content (end after reading the boundary)
666
if (filename == null) {
667
668             // This is a parameter
669
String JavaDoc value = readParameter(in, boundary);
670             m_parameters.put(name, value);
671         } else {
672             m_filecounter++;
673             // stroe the filecontent
674
m_files.put(filename, readAndSaveFile(in, boundary));
675             // store the name of the file to the parameters
676
m_parameters.put(name, filename);
677         }
678
679         // there's more to read
680
return false;
681     }
682
683     /**
684      * A utility method that reads a single part of the multipart request
685      * that represents a parameter. A subclass can override this method
686      * for a better optimized or differently behaved implementation.
687      *
688      * @param in The stream from which to read the parameter information
689      * @param boundary The boundary signifying the end of this part
690      * @return The parameter value
691      * @throws IOException If there's a problem reading or parsing the
692      * request
693      */

694     private String JavaDoc readParameter(CmsMultipartInputStreamHandler in, String JavaDoc boundary) throws IOException JavaDoc {
695         StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
696         String JavaDoc line;
697         while ((line = in.readLine()) != null) {
698             if (line.startsWith(boundary)) {
699                 break;
700             }
701
702             // add the \r\n in case there are many lines
703
sbuf.append(line + "\r\n");
704         }
705         if (sbuf.length() == 0) {
706
707             // nothing read
708
return null;
709         }
710
711         // cut off the last line's \r\n
712
sbuf.setLength(sbuf.length() - 2);
713
714         // no URL decoding needed
715
return sbuf.toString();
716     }
717
718     /**
719      * This method actually parses the request. A subclass
720      * can override this method for a better optimized or differently
721      * behaved implementation.
722      *
723      * @throws IOException If the uploaded content is larger than
724      * <tt>maxSize</tt> or there's a problem parsing the request.
725      */

726     private void readRequest() throws IOException JavaDoc {
727
728         // Check the content type to make sure it's "multipart/form-data"
729
String JavaDoc type = m_req.getContentType();
730         if (type == null || !type.toLowerCase().startsWith("multipart/form-data")) {
731             throw new IOException JavaDoc(C_REQUEST_NOMULTIPART);
732         }
733
734         int length = m_req.getContentLength();
735
736         // Get the boundary string; it's included in the content type.
737
// Should look something like "------------------------12012133613061"
738
String JavaDoc boundary = extractBoundary(type);
739         if (boundary == null) {
740             throw new IOException JavaDoc(C_REQUEST_NOBOUNDARY);
741         }
742
743         // Construct the special input stream we'll read from
744
CmsMultipartInputStreamHandler in = new CmsMultipartInputStreamHandler(m_req.getInputStream(), length);
745
746         // Read the first line, should be the first boundary
747
String JavaDoc line = in.readLine();
748         if (line == null) {
749             throw new IOException JavaDoc(C_REQUEST_PROMATUREEND);
750         }
751
752         // Verify that the line is the boundary
753
if (!line.startsWith(boundary)) {
754             throw new IOException JavaDoc(C_REQUEST_NOBOUNDARY);
755         }
756
757         // Now that we're just beyond the first boundary, loop over each part
758
boolean done = false;
759         while (!done) {
760             done = readNextPart(in, boundary);
761         }
762
763         // Unfortunately some servlet environmets cannot handle multipart
764
// requests AND URL parameters at the same time, we have to manage
765
// the URL params ourself here. So try to read th URL parameters:
766
String JavaDoc queryString = m_req.getQueryString();
767         if (queryString != null) {
768             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(m_req.getQueryString(), "&");
769             while (st.hasMoreTokens()) {
770
771                 // Loop through all parameters
772
String JavaDoc currToken = st.nextToken();
773                 if (currToken != null && !"".equals(currToken)) {
774
775                     // look for the "=" character to divide parameter name and value
776
int idx = currToken.indexOf("=");
777                     if (idx > -1) {
778                         String JavaDoc key = currToken.substring(0, idx);
779                         String JavaDoc value = (idx < (currToken.length() - 1)) ? currToken.substring(idx + 1) : "";
780                         m_parameters.put(key, value);
781                     }
782                 }
783             }
784         }
785     }
786 }
787
Popular Tags