KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > server > httpd > HttpRequestImpl


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "OpenEJB" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of The OpenEJB Group. For written permission,
18  * please contact openejb@openejb.org.
19  *
20  * 4. Products derived from this Software may not be called "OpenEJB"
21  * nor may "OpenEJB" appear in their names without prior written
22  * permission of The OpenEJB Group. OpenEJB is a registered
23  * trademark of The OpenEJB Group.
24  *
25  * 5. Due credit should be given to the OpenEJB Project
26  * (http://openejb.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
42  *
43  * $Id: HttpRequestImpl.java,v 1.8 2005/04/05 08:05:08 dblevins Exp $
44  */

45 package org.openejb.server.httpd;
46
47 import java.io.ByteArrayInputStream JavaDoc;
48 import java.io.DataInput JavaDoc;
49 import java.io.DataInputStream JavaDoc;
50 import java.io.IOException JavaDoc;
51 import java.io.InputStream JavaDoc;
52 import java.net.URI JavaDoc;
53 import java.net.URISyntaxException JavaDoc;
54 import java.net.URLDecoder JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.Map JavaDoc;
57 import java.util.StringTokenizer JavaDoc;
58
59 /**
60  * A class to take care of HTTP Requests. It parses headers, content, form and url
61  * parameters.
62  */

63 public class HttpRequestImpl implements HttpRequest {
64     public static final String JavaDoc FORM_URL_ENCODED = "application/x-www-form-urlencoded";
65     public static final String JavaDoc TEXT_XML = "text/xml";
66     public static final String JavaDoc MULITPART_FORM_DATA = "multipart/form-data";
67     public static final String JavaDoc FILENAME = "filename";
68     public static final String JavaDoc NAME = "name";
69
70     /**
71      * 5.1 Request-Line
72      */

73     private String JavaDoc line;
74     /**
75      * 5.1.1 Method
76      */

77     private int method;
78     /**
79      * 5.1.2 Request-URI
80      */

81     private URI JavaDoc uri;
82     /**
83      * the headers for this page
84      */

85     private HashMap JavaDoc headers;
86     /**
87      * the form parameters for this page
88      */

89     private HashMap JavaDoc formParams = new HashMap JavaDoc();
90     /**
91      * the URL (or query) parameters for this page
92      */

93     private HashMap JavaDoc queryParams = new HashMap JavaDoc();
94     private HashMap JavaDoc parameters = new HashMap JavaDoc();
95
96     protected static final String JavaDoc EJBSESSIONID = "EJBSESSIONID";
97
98     private HashMap JavaDoc cookies;
99
100
101     /**
102      * the content of the body of this page
103      */

104     private byte[] body;
105     private InputStream JavaDoc in;
106     private int length;
107     private String JavaDoc contentType;
108     /** the address the request came in on */
109     private final URI JavaDoc socketURI;
110
111     private HashMap JavaDoc attributes = new HashMap JavaDoc();
112
113     public HttpRequestImpl(URI JavaDoc socketURI) {
114         this.socketURI = socketURI;
115     }
116
117     /**
118      * Gets a header based the header name passed in.
119      *
120      * @param name The name of the header to get
121      * @return The value of the header
122      */

123     public String JavaDoc getHeader(String JavaDoc name) {
124         return (String JavaDoc) headers.get(name);
125     }
126
127     /**
128      * Gets a form parameter based on the name passed in.
129      *
130      * @param name The name of the form parameter to get
131      * @return The value of the parameter
132      */

133     public String JavaDoc getFormParameter(String JavaDoc name) {
134         return (String JavaDoc) formParams.get(name);
135     }
136
137     public Map JavaDoc getFormParameters() {
138         return (Map JavaDoc)formParams.clone();
139     }
140
141     public Map JavaDoc getQueryParameters() {
142         return (Map JavaDoc)queryParams.clone();
143     }
144
145     /**
146      * Gets a URL (or query) parameter based on the name passed in.
147      *
148      * @param name The name of the URL (or query) parameter
149      * @return The value of the URL (or query) parameter
150      */

151     public String JavaDoc getQueryParameter(String JavaDoc name) {
152         return (String JavaDoc) queryParams.get(name);
153     }
154
155     /**
156      * Gets an integer value of the request method. These values are:
157      * <p/>
158      * OPTIONS = 0
159      * GET = 1
160      * HEAD = 2
161      * POST = 3
162      * PUT = 4
163      * DELETE = 5
164      * TRACE = 6
165      * CONNECT = 7
166      * UNSUPPORTED = 8
167      *
168      * @return The integer value of the method
169      */

170     public int getMethod() {
171         return method;
172     }
173
174     /**
175      * Gets the URI for the current URL page.
176      *
177      * @return The URI
178      */

179     public URI JavaDoc getURI() {
180         return uri;
181     }
182
183     public int getContentLength() {
184         return length;
185     }
186
187     public String JavaDoc getContentType() {
188         return contentType;
189     }
190
191     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
192         return this.in;
193     }
194
195     /*------------------------------------------------------------*/
196     /* Methods for reading in and parsing a request */
197     /*------------------------------------------------------------*/
198     /**
199      * parses the request into the 3 different parts, request, headers, and body
200      *
201      * @param input the data input for this page
202      * @throws java.io.IOException if an exception is thrown
203      */

204     protected void readMessage(InputStream JavaDoc input) throws IOException JavaDoc {
205         DataInput JavaDoc in = new DataInputStream JavaDoc(input);
206
207         readRequestLine(in);
208         readHeaders(in);
209         readBody(in);
210
211         parameters = new HashMap JavaDoc();
212         parameters.putAll(this.getFormParameters());
213         parameters.putAll(this.getQueryParameters());
214     }
215
216     /**
217      * reads and parses the request line
218      *
219      * @param in the input to be read
220      * @throws java.io.IOException if an exception is thrown
221      */

222     private void readRequestLine(DataInput JavaDoc in) throws IOException JavaDoc {
223         try {
224             line = in.readLine();
225 // System.out.println(line);
226
} catch (Exception JavaDoc e) {
227             throw new IOException JavaDoc("Could not read the HTTP Request Line :"
228                     + e.getClass().getName()
229                     + " : "
230                     + e.getMessage());
231         }
232
233         StringTokenizer JavaDoc lineParts = new StringTokenizer JavaDoc(line, " ");
234         /* [1] Parse the method */
235         parseMethod(lineParts);
236         /* [2] Parse the URI */
237         parseURI(lineParts);
238     }
239
240     /**
241      * parses the method for this page
242      *
243      * @param lineParts a StringTokenizer of the request line
244      * @throws java.io.IOException if an exeption is thrown
245      */

246     private void parseMethod(StringTokenizer JavaDoc lineParts) throws IOException JavaDoc {
247         String JavaDoc token = null;
248         try {
249             token = lineParts.nextToken();
250         } catch (Exception JavaDoc e) {
251             throw new IOException JavaDoc("Could not parse the HTTP Request Method :"
252                     + e.getClass().getName()
253                     + " : "
254                     + e.getMessage());
255         }
256
257         if (token.equalsIgnoreCase("GET")) {
258             method = GET;
259         } else if (token.equalsIgnoreCase("POST")) {
260             method = POST;
261         } else {
262             method = UNSUPPORTED;
263             throw new IOException JavaDoc("Unsupported HTTP Request Method :" + token);
264         }
265     }
266
267     /**
268      * parses the URI into the different parts
269      *
270      * @param lineParts a StringTokenizer of the URI
271      * @throws java.io.IOException if an exeption is thrown
272      */

273     private void parseURI(StringTokenizer JavaDoc lineParts) throws IOException JavaDoc {
274         String JavaDoc token = null;
275         try {
276             token = lineParts.nextToken();
277         } catch (Exception JavaDoc e) {
278             throw new IOException JavaDoc("Could not parse the HTTP Request Method :"
279                     + e.getClass().getName()
280                     + " : "
281                     + e.getMessage());
282         }
283
284         try {
285             uri = new URI JavaDoc(socketURI.toString()+token);
286         } catch (URISyntaxException JavaDoc e) {
287             throw new IOException JavaDoc("Malformed URI :" + token + " Exception: " + e.getMessage());
288         }
289
290         parseQueryParams(uri.getQuery());
291     }
292
293     /**
294      * parses the URL (or query) parameters
295      *
296      * @param query the URL (or query) parameters to be parsed
297      */

298     private void parseQueryParams(String JavaDoc query) {
299         if (query == null)
300             return;
301         StringTokenizer JavaDoc parameters = new StringTokenizer JavaDoc(query, "&");
302
303         while (parameters.hasMoreTokens()) {
304             StringTokenizer JavaDoc param = new StringTokenizer JavaDoc(parameters.nextToken(), "=");
305
306             /* [1] Parse the Name */
307             if (!param.hasMoreTokens())
308                 continue;
309             String JavaDoc name = URLDecoder.decode(param.nextToken());
310             if (name == null)
311                 continue;
312
313             String JavaDoc value;
314             /* [2] Parse the Value */
315             if (!param.hasMoreTokens()){
316                 value = "";
317             } else {
318                 value = URLDecoder.decode(param.nextToken());
319             }
320
321             //System.out.println("[] "+name+" = "+value);
322
queryParams.put(name, value);
323         }
324     }
325
326     /**
327      * reads the headers from the data input sent from the browser
328      *
329      * @param in the data input sent from the browser
330      * @throws java.io.IOException if an exeption is thrown
331      */

332     private void readHeaders(DataInput JavaDoc in) throws IOException JavaDoc {
333 // System.out.println("\nREQUEST");
334
headers = new HashMap JavaDoc();
335         while (true) {
336             // Header Field
337
String JavaDoc hf = null;
338
339             try {
340                 hf = in.readLine();
341                 //System.out.println(hf);
342
} catch (Exception JavaDoc e) {
343                 throw new IOException JavaDoc("Could not read the HTTP Request Header Field :"
344                         + e.getClass().getName()
345                         + " : "
346                         + e.getMessage());
347             }
348
349             if (hf == null || hf.equals("")) {
350                 break;
351             }
352
353             /* [1] parse the name */
354             int colonIndex = hf.indexOf((int) ':');
355             String JavaDoc name = hf.substring(0, colonIndex);
356             if (name == null)
357                 break;
358
359             /* [2] Parse the Value */
360             String JavaDoc value = hf.substring(colonIndex + 1, hf.length());
361             if (value == null)
362                 break;
363             value = value.trim();
364             headers.put(name, value);
365         }
366         
367         // Update the URI to be what the client sees the the server as.
368
String JavaDoc host = (String JavaDoc) headers.get("Host");
369         if( host!=null ) {
370             String JavaDoc hostName = uri.getHost();
371             int port = uri.getPort();
372             int idx = host.indexOf(":");
373             if( idx >= 0 ) {
374                 hostName = host.substring(0, idx);
375                 try {
376                     port = Integer.parseInt(host.substring(idx+1));
377                 }
378                 catch (NumberFormatException JavaDoc ignore) {
379                 }
380             } else {
381                 hostName = host;
382             }
383             
384             try {
385                 uri = new URI JavaDoc(uri.getScheme(),
386                         uri.getUserInfo(), hostName, port,
387                         uri.getPath(), uri.getQuery(),
388                         uri.getFragment());
389             } catch (URISyntaxException JavaDoc ignore) {
390             }
391         }
392         
393         //temp-debug-------------------------------------------
394
//java.util.Iterator myKeys = headers.keySet().iterator();
395
//String temp = null;
396
//while(myKeys.hasNext()) {
397
// temp = (String)myKeys.next();
398
// System.out.println("Test: " + temp + "=" + headers.get(temp));
399
//}
400
//end temp-debug---------------------------------------
401
}
402
403     /**
404      * reads the body from the data input passed in
405      *
406      * @param in the data input with the body of the page
407      * @throws java.io.IOException if an exception is thrown
408      */

409     private void readBody(DataInput JavaDoc in) throws IOException JavaDoc {
410         //System.out.println("Body Length: " + body.length);
411
// Content-type: application/x-www-form-urlencoded
412
// or multipart/form-data
413
length = parseContentLength();
414
415         contentType = getHeader(HttpRequest.HEADER_CONTENT_TYPE);
416
417         if (method == POST && FORM_URL_ENCODED.equals(contentType)) {
418             String JavaDoc rawParams = null;
419
420             try {
421                 byte[] body = new byte[length];
422                 in.readFully(body);
423                 rawParams = new String JavaDoc(body);
424             } catch (Exception JavaDoc e) {
425                 throw (IOException JavaDoc)new IOException JavaDoc("Could not read the HTTP Request Body: " + e.getMessage()).initCause(e);
426             }
427
428             StringTokenizer JavaDoc parameters = new StringTokenizer JavaDoc(rawParams, "&");
429             String JavaDoc name = null;
430             String JavaDoc value = null;
431
432             while (parameters.hasMoreTokens()) {
433                 StringTokenizer JavaDoc param = new StringTokenizer JavaDoc(parameters.nextToken(), "=");
434
435                 /* [1] Parse the Name */
436                 name = URLDecoder.decode(param.nextToken());
437                 if (name == null)
438                     break;
439
440                 /* [2] Parse the Value */
441                 if (param.hasMoreTokens()) {
442                     value = URLDecoder.decode(param.nextToken());
443                 } else {
444                     value = ""; //if there is no token set value to blank string
445
}
446
447                 if (value == null)
448                     value = "";
449
450                 formParams.put(name, value);
451                     //System.out.println(name + ": " + value);
452
}
453         } else if (method == POST){
454             // TODO This really is terrible
455
byte[] body = new byte[length];
456             in.readFully(body);
457             this.in = new ByteArrayInputStream JavaDoc(body);
458         } else {
459             this.in = new ByteArrayInputStream JavaDoc(new byte[0]);
460         }
461
462     }
463
464     private int parseContentLength() {
465         // Content-length: 384
466
String JavaDoc len = getHeader(HttpRequest.HEADER_CONTENT_LENGTH);
467         //System.out.println("readRequestBody Content-Length: " + len);
468

469         int length = -1;
470         if (len != null) {
471             try {
472                 length = Integer.parseInt(len);
473             } catch (Exception JavaDoc e) {
474                 //don't care
475
}
476         }
477         return length;
478     }
479
480     protected HashMap JavaDoc getCookies() {
481         if (cookies != null) return cookies;
482
483         cookies = new HashMap JavaDoc();
484
485         String JavaDoc cookieHeader = getHeader(HEADER_COOKIE);
486         if (cookieHeader == null) return cookies;
487
488         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(cookieHeader, ";");
489         while (tokens.hasMoreTokens()) {
490             StringTokenizer JavaDoc token = new StringTokenizer JavaDoc(tokens.nextToken(), "=");
491             String JavaDoc name = token.nextToken();
492             String JavaDoc value = token.nextToken();
493             cookies.put(name, value);
494         }
495         return cookies;
496     }
497
498     protected String JavaDoc getCookie(String JavaDoc name) {
499         return (String JavaDoc) getCookies().get(name);
500     }
501
502     public HttpSession getSession(boolean create) {
503         return null;
504     }
505
506     public HttpSession getSession() {
507         return getSession(true);
508     }
509     
510     public Object JavaDoc getAttribute(String JavaDoc name) {
511         return attributes.get(name);
512     }
513
514     public void setAttribute(String JavaDoc name, Object JavaDoc value){
515         attributes.put(name, value);
516     }
517
518     public String JavaDoc getParameter(String JavaDoc name) {
519         return (String JavaDoc)parameters.get(name);
520     }
521
522     public Map JavaDoc getParameters() {
523         return (Map JavaDoc)parameters.clone();
524     }
525 }
Popular Tags