001    /*
002     * Copyright 1999,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    
018    package org.apache.commons.messagelet.impl;
019    
020    import java.io.UnsupportedEncodingException;
021    import java.security.Principal;
022    import java.text.ParseException;
023    import java.text.SimpleDateFormat;
024    import java.util.ArrayList;
025    import java.util.Collections;
026    import java.util.Date;
027    import java.util.Enumeration;
028    import java.util.HashMap;
029    import java.util.Locale;
030    import java.util.Map;
031    
032    import javax.servlet.ServletContext;
033    import javax.servlet.http.Cookie;
034    import javax.servlet.http.HttpServletRequest;
035    import javax.servlet.http.HttpSession;
036    
037    import org.apache.commons.collections.iterators.IteratorEnumeration;
038    
039    /**
040     * Based on the HttpRequestBase code from Catalina.
041     *
042     * @author Craig R. McClanahan
043     * @author James Strachan
044     * @version $Revision: 155459 $ $Date: 2005-02-26 13:24:44 +0000 (Sat, 26 Feb 2005) $
045     */
046    
047    public class HttpServletRequestImpl extends ServletRequestImpl implements HttpServletRequest {
048    
049    
050        /**
051         * The authentication type used for this request.
052         */
053        protected String authType = null;
054    
055    
056        /**
057         * The context path for this request.
058         */
059        protected String contextPath = "";
060    
061    
062        /**
063         * The set of cookies associated with this Request.
064         */
065        protected ArrayList cookies = new ArrayList();
066    
067    
068        /**
069         * The set of SimpleDateFormat formats to use in getDateHeader().
070         */
071        protected SimpleDateFormat formats[] = {
072            new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
073            new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
074            new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
075        };
076    
077    
078    
079        /**
080         * The HTTP headers associated with this Request, keyed by name.  The
081         * values are ArrayLists of the corresponding header values.
082         */
083        protected HashMap headers = new HashMap();
084    
085    
086    
087        /**
088         * The request method associated with this Request.
089         */
090        protected String method = null;
091    
092    
093        /**
094         * The path information for this request.
095         */
096        protected String pathInfo = null;
097    
098    
099        /**
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    }