1 /*
2 * Copyright 1999,2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 package org.apache.commons.messagelet.impl;
19
20 import java.io.UnsupportedEncodingException;
21 import java.security.Principal;
22 import java.text.ParseException;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.Enumeration;
28 import java.util.HashMap;
29 import java.util.Locale;
30 import java.util.Map;
31
32 import javax.servlet.ServletContext;
33 import javax.servlet.http.Cookie;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpSession;
36
37 import org.apache.commons.collections.iterators.IteratorEnumeration;
38
39 /**
40 * Based on the HttpRequestBase code from Catalina.
41 *
42 * @author Craig R. McClanahan
43 * @author James Strachan
44 * @version $Revision: 155459 $ $Date: 2005-02-26 13:24:44 +0000 (Sat, 26 Feb 2005) $
45 */
46
47 public class HttpServletRequestImpl extends ServletRequestImpl implements HttpServletRequest {
48
49
50 /**
51 * The authentication type used for this request.
52 */
53 protected String authType = null;
54
55
56 /**
57 * The context path for this request.
58 */
59 protected String contextPath = "";
60
61
62 /**
63 * The set of cookies associated with this Request.
64 */
65 protected ArrayList cookies = new ArrayList();
66
67
68 /**
69 * The set of SimpleDateFormat formats to use in getDateHeader().
70 */
71 protected SimpleDateFormat formats[] = {
72 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
73 new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
74 new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
75 };
76
77
78
79 /**
80 * The HTTP headers associated with this Request, keyed by name. The
81 * values are ArrayLists of the corresponding header values.
82 */
83 protected HashMap headers = new HashMap();
84
85
86
87 /**
88 * The request method associated with this Request.
89 */
90 protected String method = null;
91
92
93 /**
94 * The path information for this request.
95 */
96 protected String pathInfo = null;
97
98
99 /**
100 * The query string for this request.
101 */
102 protected String queryString = null;
103
104
105 /**
106 * Was the requested session ID received in a cookie?
107 */
108 protected boolean requestedSessionCookie = false;
109
110
111 /**
112 * The requested session ID (if any) for this request.
113 */
114 protected String requestedSessionId = null;
115
116
117 /**
118 * Was the requested session ID received in a URL?
119 */
120 protected boolean requestedSessionURL = false;
121
122
123 /**
124 * The request URI associated with this request.
125 */
126 protected String requestURI = null;
127
128
129 /**
130 * The servlet path for this request.
131 */
132 protected String servletPath = null;
133
134
135 /**
136 * The currently active session for this request.
137 */
138 protected HttpSessionImpl session = null;
139
140
141 /**
142 * The Principal who has been authenticated for this Request.
143 */
144 protected Principal userPrincipal = null;
145
146
147 /**
148 * The parameters
149 */
150 private Map parameters = null;
151
152
153 // --------------------------------------------------------- Public Methods
154
155 public HttpServletRequestImpl(ServletContext servletContext) {
156 super( servletContext );
157 }
158
159
160 /**
161 * Add a Cookie to the set of Cookies associated with this Request.
162 *
163 * @param cookie The new cookie
164 */
165 public void addCookie(Cookie cookie) {
166
167 synchronized (cookies) {
168 cookies.add(cookie);
169 }
170
171 }
172
173
174 /**
175 * Add a Header to the set of Headers associated with this Request.
176 *
177 * @param name The new header name
178 * @param value The new header value
179 */
180 public void addHeader(String name, String value) {
181
182 name = name.toLowerCase();
183 synchronized (headers) {
184 ArrayList values = (ArrayList) headers.get(name);
185 if (values == null) {
186 values = new ArrayList();
187 headers.put(name, values);
188 }
189 values.add(value);
190 }
191
192 }
193
194
195 /**
196 * Clear the collection of Cookies associated with this Request.
197 */
198 public void clearCookies() {
199
200 synchronized (cookies) {
201 cookies.clear();
202 }
203
204 }
205
206
207 /**
208 * Clear the collection of Headers associated with this Request.
209 */
210 public void clearHeaders() {
211
212 headers.clear();
213
214 }
215
216
217
218
219 /**
220 * Set the authentication type used for this request, if any; otherwise
221 * set the type to <code>null</code>. Typical values are "BASIC",
222 * "DIGEST", or "SSL".
223 *
224 * @param authType The authentication type used
225 */
226 public void setAuthType(String authType) {
227
228 this.authType = authType;
229
230 }
231
232
233 /**
234 * Set the context path for this Request. This will normally be called
235 * when the associated Context is mapping the Request to a particular
236 * Wrapper.
237 *
238 * @param path The context path
239 */
240 public void setContextPath(String path) {
241
242 if (path == null)
243 this.contextPath = "";
244 else
245 this.contextPath = path;
246
247 }
248
249
250 /**
251 * Set the HTTP request method used for this Request.
252 *
253 * @param method The request method
254 */
255 public void setMethod(String method) {
256
257 this.method = method;
258
259 }
260
261
262 /**
263 * Set the path information for this Request. This will normally be called
264 * when the associated Context is mapping the Request to a particular
265 * Wrapper.
266 *
267 * @param path The path information
268 */
269 public void setPathInfo(String path) {
270
271 this.pathInfo = path;
272
273 }
274
275
276 /**
277 * Set the query string for this Request. This will normally be called
278 * by the HTTP Connector, when it parses the request headers.
279 *
280 * @param query The query string
281 */
282 public void setQueryString(String query) {
283
284 this.queryString = query;
285 this.parameters = null;
286
287 }
288
289
290 /**
291 * Set a flag indicating whether or not the requested session ID for this
292 * request came in through a cookie. This is normally called by the
293 * HTTP Connector, when it parses the request headers.
294 *
295 * @param flag The new flag
296 */
297 public void setRequestedSessionCookie(boolean flag) {
298
299 this.requestedSessionCookie = flag;
300
301 }
302
303
304 /**
305 * Set the requested session ID for this request. This is normally called
306 * by the HTTP Connector, when it parses the request headers.
307 *
308 * @param id The new session id
309 */
310 public void setRequestedSessionId(String id) {
311
312 this.requestedSessionId = id;
313
314 }
315
316
317 /**
318 * Set a flag indicating whether or not the requested session ID for this
319 * request came in through a URL. This is normally called by the
320 * HTTP Connector, when it parses the request headers.
321 *
322 * @param flag The new flag
323 */
324 public void setRequestedSessionURL(boolean flag) {
325
326 this.requestedSessionURL = flag;
327
328 }
329
330
331 /**
332 * Set the unparsed request URI for this Request. This will normally
333 * be called by the HTTP Connector, when it parses the request headers.
334 *
335 * @param uri The request URI
336 */
337 public void setRequestURI(String uri) {
338
339 this.requestURI = uri;
340
341 }
342
343
344 /**
345 * Set the servlet path for this Request. This will normally be called
346 * when the associated Context is mapping the Request to a particular
347 * Wrapper.
348 *
349 * @param path The servlet path
350 */
351 public void setServletPath(String path) {
352
353 this.servletPath = path;
354
355 }
356
357
358 /**
359 * Set the Principal who has been authenticated for this Request. This
360 * value is also used to calculate the value to be returned by the
361 * <code>getRemoteUser()</code> method.
362 *
363 * @param principal The user Principal
364 */
365 public void setUserPrincipal(Principal principal) {
366
367 this.userPrincipal = principal;
368
369 }
370
371
372
373 // --------------------------------------------- HttpServletRequest Methods
374
375
376 /**
377 * Return the authentication type used for this Request.
378 */
379 public String getAuthType() {
380
381 return (authType);
382
383 }
384
385
386 /**
387 * Return the portion of the request URI used to select the Context
388 * of the Request.
389 */
390 public String getContextPath() {
391
392 return (contextPath);
393
394 }
395
396
397 /**
398 * Return the set of Cookies received with this Request.
399 */
400 public Cookie[] getCookies() {
401
402 synchronized (cookies) {
403 if (cookies.size() < 1)
404 return (null);
405 Cookie results[] = new Cookie[cookies.size()];
406 return ((Cookie[]) cookies.toArray(results));
407 }
408
409 }
410
411
412 /**
413 * Return the value of the specified date header, if any; otherwise
414 * return -1.
415 *
416 * @param name Name of the requested date header
417 *
418 * @exception IllegalArgumentException if the specified header value
419 * cannot be converted to a date
420 */
421 public long getDateHeader(String name) {
422
423 String value = getHeader(name);
424 if (value == null)
425 return (-1L);
426
427 // Work around a bug in SimpleDateFormat in pre-JDK1.2b4
428 // (Bug Parade bug #4106807)
429 value += " ";
430
431 // Attempt to convert the date header in a variety of formats
432 for (int i = 0; i < formats.length; i++) {
433 try {
434 Date date = formats[i].parse(value);
435 return (date.getTime());
436 } catch (ParseException e) {
437 ;
438 }
439 }
440 throw new IllegalArgumentException(value);
441
442 }
443
444
445 /**
446 * Return the first value of the specified header, if any; otherwise,
447 * return <code>null</code>
448 *
449 * @param name Name of the requested header
450 */
451 public String getHeader(String name) {
452
453 name = name.toLowerCase();
454 synchronized (headers) {
455 ArrayList values = (ArrayList) headers.get(name);
456 if (values != null)
457 return ((String) values.get(0));
458 else
459 return (null);
460 }
461
462 }
463
464
465 /**
466 * Return all of the values of the specified header, if any; otherwise,
467 * return an empty enumeration.
468 *
469 * @param name Name of the requested header
470 */
471 public Enumeration getHeaders(String name) {
472
473 name = name.toLowerCase();
474 synchronized (headers) {
475 ArrayList values = (ArrayList) headers.get(name);
476 if (values != null)
477 return (new IteratorEnumeration( values.iterator() ));
478 else
479 return (new IteratorEnumeration( Collections.EMPTY_LIST.iterator() ));
480 }
481
482 }
483
484
485 /**
486 * Return the names of all headers received with this request.
487 */
488 public Enumeration getHeaderNames() {
489
490 synchronized (headers) {
491 return (new IteratorEnumeration( headers.keySet().iterator() ));
492 }
493
494 }
495
496
497 /**
498 * Return the value of the specified header as an integer, or -1 if there
499 * is no such header for this request.
500 *
501 * @param name Name of the requested header
502 *
503 * @exception IllegalArgumentException if the specified header value
504 * cannot be converted to an integer
505 */
506 public int getIntHeader(String name) {
507
508 String value = getHeader(name);
509 if (value == null)
510 return (-1);
511 else
512 return (Integer.parseInt(value));
513
514 }
515
516
517 /**
518 * Return the HTTP request method used in this Request.
519 */
520 public String getMethod() {
521
522 return (method);
523
524 }
525
526
527 /**
528 * Returns a <code>Map</code> of the parameters of this request.
529 * Request parameters are extra information sent with the request.
530 * For HTTP servlets, parameters are contained in the query string
531 * or posted form data.
532 *
533 * @return A <code>Map</code> containing parameter names as keys
534 * and parameter values as map values.
535 */
536 public Map getParameterMap() {
537 if ( parameters == null ) {
538 parameters = new HashMap();
539 if ( queryString != null ) {
540 try {
541 RequestUtil.parseParameters(parameters, queryString, getCharacterEncoding());
542 }
543 catch (UnsupportedEncodingException e) {
544 servletContext.log( "Could not parse query string: " + queryString, e);
545 }
546 }
547 }
548 return parameters;
549 }
550
551 /**
552 * Return the path information associated with this Request.
553 */
554 public String getPathInfo() {
555
556 return (pathInfo);
557
558 }
559
560
561 /**
562 * Return the extra path information for this request, translated
563 * to a real path.
564 */
565 public String getPathTranslated() {
566
567 if (pathInfo == null)
568 return (null);
569 else
570 return (servletContext.getRealPath(pathInfo));
571
572 }
573
574
575 /**
576 * Return the query string associated with this request.
577 */
578 public String getQueryString() {
579
580 return (queryString);
581
582 }
583
584
585 /**
586 * Return the name of the remote user that has been authenticated
587 * for this Request.
588 */
589 public String getRemoteUser() {
590
591 if (userPrincipal != null)
592 return (userPrincipal.getName());
593 else
594 return (null);
595
596 }
597
598
599 /**
600 * Return the session identifier included in this request, if any.
601 */
602 public String getRequestedSessionId() {
603
604 return (requestedSessionId);
605
606 }
607
608
609 /**
610 * Return the request URI for this request.
611 */
612 public String getRequestURI() {
613
614 return (requestURI);
615
616 }
617
618
619 /**
620 * Reconstructs the URL the client used to make the request.
621 * The returned URL contains a protocol, server name, port
622 * number, and server path, but it does not include query
623 * string parameters.
624 * <p>
625 * Because this method returns a <code>StringBuffer</code>,
626 * not a <code>String</code>, you can modify the URL easily,
627 * for example, to append query parameters.
628 * <p>
629 * This method is useful for creating redirect messages and
630 * for reporting errors.
631 *
632 * @return A <code>StringBuffer</code> object containing the
633 * reconstructed URL
634 */
635 public StringBuffer getRequestURL() {
636
637 StringBuffer url = new StringBuffer();
638 String scheme = getScheme();
639 int port = getServerPort();
640 if (port < 0)
641 port = 80; // Work around java.net.URL bug
642
643 url.append(scheme);
644 url.append("://");
645 url.append(getServerName());
646 if ((scheme.equals("http") && (port != 80))
647 || (scheme.equals("https") && (port != 443))) {
648 url.append(':');
649 url.append(port);
650 }
651 url.append(getRequestURI());
652
653 return (url);
654
655 }
656
657
658 /**
659 * Return the portion of the request URI used to select the servlet
660 * that will process this request.
661 */
662 public String getServletPath() {
663
664 return (servletPath);
665
666 }
667
668
669 /**
670 * Return the session associated with this Request, creating one
671 * if necessary.
672 */
673 public HttpSession getSession() {
674
675 return (getSession(true));
676
677 }
678
679
680 /**
681 * Return the session associated with this Request, creating one
682 * if necessary and requested.
683 *
684 * @param create Create a new session if one does not exist
685 */
686 public HttpSession getSession(boolean create) {
687 // Return the current session if it exists and is valid
688 if ((session != null) && !session.isValid())
689 session = null;
690
691 if ( create && session == null) {
692 session = new HttpSessionImpl( servletContext );
693 }
694 return session;
695 }
696
697
698 /**
699 * Return <code>true</code> if the session identifier included in this
700 * request came from a cookie.
701 */
702 public boolean isRequestedSessionIdFromCookie() {
703
704 if (requestedSessionId != null)
705 return (requestedSessionCookie);
706 else
707 return (false);
708
709 }
710
711
712 /**
713 * Return <code>true</code> if the session identifier included in this
714 * request came from the request URI.
715 */
716 public boolean isRequestedSessionIdFromURL() {
717
718 if (requestedSessionId != null)
719 return (requestedSessionURL);
720 else
721 return (false);
722
723 }
724
725
726 /**
727 * Return <code>true</code> if the session identifier included in this
728 * request came from the request URI.
729 *
730 * @deprecated As of Version 2.1 of the Java Servlet API, use
731 * <code>isRequestedSessionIdFromURL()</code> instead.
732 */
733 public boolean isRequestedSessionIdFromUrl() {
734
735 return (isRequestedSessionIdFromURL());
736
737 }
738
739
740 /**
741 * Return <code>true</code> if the session identifier included in this
742 * request identifies a valid session.
743 */
744 public boolean isRequestedSessionIdValid() {
745 return false;
746
747 }
748
749
750 /**
751 * Return <code>true</code> if the authenticated user principal
752 * possesses the specified role name.
753 *
754 * @param role Role name to be validated
755 */
756 public boolean isUserInRole(String role) {
757 return false;
758 }
759
760
761 /**
762 * Return the principal that has been authenticated for this Request.
763 */
764 public Principal getUserPrincipal() {
765
766 return (userPrincipal);
767
768 }
769 }