KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > connector > Request


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.connector;
20
21
22 import java.io.InputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.BufferedReader JavaDoc;
25 import java.io.UnsupportedEncodingException JavaDoc;
26 import java.security.Principal JavaDoc;
27 import java.text.SimpleDateFormat JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.Locale JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.TimeZone JavaDoc;
35 import java.util.TreeMap JavaDoc;
36
37 import javax.security.auth.Subject JavaDoc;
38 import javax.servlet.FilterChain JavaDoc;
39 import javax.servlet.RequestDispatcher JavaDoc;
40 import javax.servlet.ServletContext JavaDoc;
41 import javax.servlet.ServletInputStream JavaDoc;
42 import javax.servlet.ServletRequestAttributeEvent JavaDoc;
43 import javax.servlet.ServletRequestAttributeListener JavaDoc;
44 import javax.servlet.http.Cookie JavaDoc;
45 import javax.servlet.http.HttpServletRequest JavaDoc;
46 import javax.servlet.http.HttpSession JavaDoc;
47
48 import org.apache.tomcat.util.buf.B2CConverter;
49 import org.apache.tomcat.util.buf.MessageBytes;
50 import org.apache.tomcat.util.buf.StringCache;
51 import org.apache.tomcat.util.http.Cookies;
52 import org.apache.tomcat.util.http.FastHttpDateFormat;
53 import org.apache.tomcat.util.http.Parameters;
54 import org.apache.tomcat.util.http.ServerCookie;
55 import org.apache.tomcat.util.http.mapper.MappingData;
56
57 import org.apache.coyote.ActionCode;
58
59 import org.apache.catalina.Context;
60 import org.apache.catalina.Globals;
61 import org.apache.catalina.Host;
62 import org.apache.catalina.Manager;
63 import org.apache.catalina.Realm;
64 import org.apache.catalina.Session;
65 import org.apache.catalina.Wrapper;
66 import org.apache.catalina.core.ApplicationFilterFactory;
67 import org.apache.catalina.realm.GenericPrincipal;
68 import org.apache.catalina.util.Enumerator;
69 import org.apache.catalina.util.ParameterMap;
70 import org.apache.catalina.util.RequestUtil;
71 import org.apache.catalina.util.StringManager;
72 import org.apache.catalina.util.StringParser;
73
74
75 /**
76  * Wrapper object for the Coyote request.
77  *
78  * @author Remy Maucherat
79  * @author Craig R. McClanahan
80  * @version $Revision: 470756 $ $Date: 2006-11-03 11:56:25 +0100 (ven., 03 nov. 2006) $
81  */

82
83 public class Request
84     implements HttpServletRequest JavaDoc {
85
86
87     // ----------------------------------------------------------- Constructors
88

89
90     static {
91         // Ensure that classes are loaded for SM
92
new StringCache.ByteEntry();
93         new StringCache.CharEntry();
94     }
95
96     public Request() {
97
98         formats[0].setTimeZone(GMT_ZONE);
99         formats[1].setTimeZone(GMT_ZONE);
100         formats[2].setTimeZone(GMT_ZONE);
101
102     }
103
104
105     // ------------------------------------------------------------- Properties
106

107
108     /**
109      * Coyote request.
110      */

111     protected org.apache.coyote.Request coyoteRequest;
112
113     /**
114      * Set the Coyote request.
115      *
116      * @param coyoteRequest The Coyote request
117      */

118     public void setCoyoteRequest(org.apache.coyote.Request coyoteRequest) {
119         this.coyoteRequest = coyoteRequest;
120         inputBuffer.setRequest(coyoteRequest);
121     }
122
123     /**
124      * Get the Coyote request.
125      */

126     public org.apache.coyote.Request getCoyoteRequest() {
127         return (this.coyoteRequest);
128     }
129
130
131     // ----------------------------------------------------- Variables
132

133
134     protected static final TimeZone JavaDoc GMT_ZONE = TimeZone.getTimeZone("GMT");
135
136
137     /**
138      * The string manager for this package.
139      */

140     protected static StringManager sm =
141         StringManager.getManager(Constants.Package);
142
143
144     /**
145      * The set of cookies associated with this Request.
146      */

147     protected Cookie JavaDoc[] cookies = null;
148
149
150     /**
151      * The set of SimpleDateFormat formats to use in getDateHeader().
152      *
153      * Notice that because SimpleDateFormat is not thread-safe, we can't
154      * declare formats[] as a static variable.
155      */

156     protected SimpleDateFormat JavaDoc formats[] = {
157         new SimpleDateFormat JavaDoc("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
158         new SimpleDateFormat JavaDoc("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
159         new SimpleDateFormat JavaDoc("EEE MMMM d HH:mm:ss yyyy", Locale.US)
160     };
161
162
163     /**
164      * The default Locale if none are specified.
165      */

166     protected static Locale JavaDoc defaultLocale = Locale.getDefault();
167
168
169     /**
170      * The attributes associated with this Request, keyed by attribute name.
171      */

172     protected HashMap JavaDoc attributes = new HashMap JavaDoc();
173
174
175     /**
176      * List of read only attributes for this Request.
177      */

178     private HashMap JavaDoc readOnlyAttributes = new HashMap JavaDoc();
179
180
181     /**
182      * The preferred Locales assocaited with this Request.
183      */

184     protected ArrayList JavaDoc locales = new ArrayList JavaDoc();
185
186
187     /**
188      * Internal notes associated with this request by Catalina components
189      * and event listeners.
190      */

191     private transient HashMap JavaDoc notes = new HashMap JavaDoc();
192
193
194     /**
195      * Authentication type.
196      */

197     protected String JavaDoc authType = null;
198
199     
200     /**
201      * Associated event.
202      */

203     protected CometEventImpl event = null;
204     
205
206     /**
207      * Comet state
208      */

209     protected boolean comet = false;
210     
211     
212     /**
213      * The current dispatcher type.
214      */

215     protected Object JavaDoc dispatcherType = null;
216
217
218     /**
219      * The associated input buffer.
220      */

221     protected InputBuffer inputBuffer = new InputBuffer();
222
223
224     /**
225      * ServletInputStream.
226      */

227     protected CoyoteInputStream inputStream =
228         new CoyoteInputStream(inputBuffer);
229
230
231     /**
232      * Reader.
233      */

234     protected CoyoteReader reader = new CoyoteReader(inputBuffer);
235
236
237     /**
238      * Using stream flag.
239      */

240     protected boolean usingInputStream = false;
241
242
243     /**
244      * Using writer flag.
245      */

246     protected boolean usingReader = false;
247
248
249     /**
250      * User principal.
251      */

252     protected Principal JavaDoc userPrincipal = null;
253
254
255     /**
256      * Session parsed flag.
257      */

258     protected boolean sessionParsed = false;
259
260
261     /**
262      * Request parameters parsed flag.
263      */

264     protected boolean parametersParsed = false;
265
266
267     /**
268      * Cookies parsed flag.
269      */

270     protected boolean cookiesParsed = false;
271
272
273     /**
274      * Secure flag.
275      */

276     protected boolean secure = false;
277
278     
279     /**
280      * The Subject associated with the current AccessControllerContext
281      */

282     protected transient Subject JavaDoc subject = null;
283
284
285     /**
286      * Post data buffer.
287      */

288     protected static int CACHED_POST_LEN = 8192;
289     protected byte[] postData = null;
290
291
292     /**
293      * Hash map used in the getParametersMap method.
294      */

295     protected ParameterMap parameterMap = new ParameterMap();
296
297
298     /**
299      * The currently active session for this request.
300      */

301     protected Session JavaDoc session = null;
302
303
304     /**
305      * The current request dispatcher path.
306      */

307     protected Object JavaDoc requestDispatcherPath = null;
308
309
310     /**
311      * Was the requested session ID received in a cookie?
312      */

313     protected boolean requestedSessionCookie = false;
314
315
316     /**
317      * The requested session ID (if any) for this request.
318      */

319     protected String JavaDoc requestedSessionId = null;
320
321
322     /**
323      * Was the requested session ID received in a URL?
324      */

325     protected boolean requestedSessionURL = false;
326
327
328     /**
329      * Parse locales.
330      */

331     protected boolean localesParsed = false;
332
333
334     /**
335      * The string parser we will use for parsing request lines.
336      */

337     private StringParser parser = new StringParser();
338
339
340     /**
341      * Local port
342      */

343     protected int localPort = -1;
344
345     /**
346      * Remote address.
347      */

348     protected String JavaDoc remoteAddr = null;
349
350
351     /**
352      * Remote host.
353      */

354     protected String JavaDoc remoteHost = null;
355
356     
357     /**
358      * Remote port
359      */

360     protected int remotePort = -1;
361     
362     /**
363      * Local address
364      */

365     protected String JavaDoc localAddr = null;
366
367     
368     /**
369      * Local address
370      */

371     protected String JavaDoc localName = null;
372
373
374     // --------------------------------------------------------- Public Methods
375

376
377     /**
378      * Release all object references, and initialize instance variables, in
379      * preparation for reuse of this object.
380      */

381     public void recycle() {
382
383         context = null;
384         wrapper = null;
385
386         dispatcherType = null;
387         requestDispatcherPath = null;
388
389         comet = false;
390         if (event != null) {
391             event.clear();
392             event = null;
393         }
394         
395         authType = null;
396         inputBuffer.recycle();
397         usingInputStream = false;
398         usingReader = false;
399         userPrincipal = null;
400         subject = null;
401         sessionParsed = false;
402         parametersParsed = false;
403         cookiesParsed = false;
404         locales.clear();
405         localesParsed = false;
406         secure = false;
407         remoteAddr = null;
408         remoteHost = null;
409         remotePort = -1;
410         localPort = -1;
411         localAddr = null;
412         localName = null;
413
414         attributes.clear();
415         notes.clear();
416         cookies = null;
417
418         if (session != null) {
419             session.endAccess();
420         }
421         session = null;
422         requestedSessionCookie = false;
423         requestedSessionId = null;
424         requestedSessionURL = false;
425
426         if (Constants.SECURITY || Connector.RECYCLE_FACADES) {
427             parameterMap = new ParameterMap();
428         } else {
429             parameterMap.setLocked(false);
430             parameterMap.clear();
431         }
432
433         mappingData.recycle();
434
435         if (Constants.SECURITY || Connector.RECYCLE_FACADES) {
436             if (facade != null) {
437                 facade.clear();
438                 facade = null;
439             }
440             if (inputStream != null) {
441                 inputStream.clear();
442                 inputStream = null;
443             }
444             if (reader != null) {
445                 reader.clear();
446                 reader = null;
447             }
448         }
449
450     }
451
452
453     /**
454      * Clear cached encoders (to save memory for Comet requests).
455      */

456     public void clearEncoders() {
457         inputBuffer.clearEncoders();
458     }
459     
460
461     // -------------------------------------------------------- Request Methods
462

463
464     /**
465      * Associated Catalina connector.
466      */

467     protected Connector connector;
468
469     /**
470      * Return the Connector through which this Request was received.
471      */

472     public Connector getConnector() {
473         return (this.connector);
474     }
475
476     /**
477      * Set the Connector through which this Request was received.
478      *
479      * @param connector The new connector
480      */

481     public void setConnector(Connector connector) {
482         this.connector = connector;
483     }
484
485
486     /**
487      * Associated context.
488      */

489     protected Context JavaDoc context = null;
490
491     /**
492      * Return the Context within which this Request is being processed.
493      */

494     public Context JavaDoc getContext() {
495         return (this.context);
496     }
497
498
499     /**
500      * Set the Context within which this Request is being processed. This
501      * must be called as soon as the appropriate Context is identified, because
502      * it identifies the value to be returned by <code>getContextPath()</code>,
503      * and thus enables parsing of the request URI.
504      *
505      * @param context The newly associated Context
506      */

507     public void setContext(Context JavaDoc context) {
508         this.context = context;
509     }
510
511
512     /**
513      * Filter chain associated with the request.
514      */

515     protected FilterChain JavaDoc filterChain = null;
516
517     /**
518      * Get filter chain associated with the request.
519      */

520     public FilterChain JavaDoc getFilterChain() {
521         return (this.filterChain);
522     }
523
524     /**
525      * Set filter chain associated with the request.
526      *
527      * @param filterChain new filter chain
528      */

529     public void setFilterChain(FilterChain JavaDoc filterChain) {
530         this.filterChain = filterChain;
531     }
532
533
534     /**
535      * Return the Host within which this Request is being processed.
536      */

537     public Host getHost() {
538         if (getContext() == null)
539             return null;
540         return (Host) getContext().getParent();
541         //return ((Host) mappingData.host);
542
}
543
544
545     /**
546      * Set the Host within which this Request is being processed. This
547      * must be called as soon as the appropriate Host is identified, and
548      * before the Request is passed to a context.
549      *
550      * @param host The newly associated Host
551      */

552     public void setHost(Host host) {
553         mappingData.host = host;
554     }
555
556
557     /**
558      * Descriptive information about this Request implementation.
559      */

560     protected static final String JavaDoc info =
561         "org.apache.coyote.catalina.CoyoteRequest/1.0";
562
563     /**
564      * Return descriptive information about this Request implementation and
565      * the corresponding version number, in the format
566      * <code>&lt;description&gt;/&lt;version&gt;</code>.
567      */

568     public String JavaDoc getInfo() {
569         return (info);
570     }
571
572
573     /**
574      * Mapping data.
575      */

576     protected MappingData mappingData = new MappingData();
577
578     /**
579      * Return mapping data.
580      */

581     public MappingData getMappingData() {
582         return (mappingData);
583     }
584
585
586     /**
587      * The facade associated with this request.
588      */

589     protected RequestFacade facade = null;
590
591     /**
592      * Return the <code>ServletRequest</code> for which this object
593      * is the facade. This method must be implemented by a subclass.
594      */

595     public HttpServletRequest JavaDoc getRequest() {
596         if (facade == null) {
597             facade = new RequestFacade(this);
598         }
599         return (facade);
600     }
601
602
603     /**
604      * The response with which this request is associated.
605      */

606     protected org.apache.catalina.connector.Response response = null;
607
608     /**
609      * Return the Response with which this Request is associated.
610      */

611     public org.apache.catalina.connector.Response getResponse() {
612         return (this.response);
613     }
614
615     /**
616      * Set the Response with which this Request is associated.
617      *
618      * @param response The new associated response
619      */

620     public void setResponse(org.apache.catalina.connector.Response response) {
621         this.response = response;
622     }
623
624     /**
625      * Return the input stream associated with this Request.
626      */

627     public InputStream JavaDoc getStream() {
628         if (inputStream == null) {
629             inputStream = new CoyoteInputStream(inputBuffer);
630         }
631         return inputStream;
632     }
633
634     /**
635      * Set the input stream associated with this Request.
636      *
637      * @param stream The new input stream
638      */

639     public void setStream(InputStream JavaDoc stream) {
640         // Ignore
641
}
642
643
644     /**
645      * URI byte to char converter (not recycled).
646      */

647     protected B2CConverter URIConverter = null;
648
649     /**
650      * Return the URI converter.
651      */

652     protected B2CConverter getURIConverter() {
653         return URIConverter;
654     }
655
656     /**
657      * Set the URI converter.
658      *
659      * @param URIConverter the new URI connverter
660      */

661     protected void setURIConverter(B2CConverter URIConverter) {
662         this.URIConverter = URIConverter;
663     }
664
665
666     /**
667      * Associated wrapper.
668      */

669     protected Wrapper wrapper = null;
670
671     /**
672      * Return the Wrapper within which this Request is being processed.
673      */

674     public Wrapper getWrapper() {
675         return (this.wrapper);
676     }
677
678
679     /**
680      * Set the Wrapper within which this Request is being processed. This
681      * must be called as soon as the appropriate Wrapper is identified, and
682      * before the Request is ultimately passed to an application servlet.
683      * @param wrapper The newly associated Wrapper
684      */

685     public void setWrapper(Wrapper wrapper) {
686         this.wrapper = wrapper;
687     }
688
689
690     // ------------------------------------------------- Request Public Methods
691

692
693     /**
694      * Create and return a ServletInputStream to read the content
695      * associated with this Request.
696      *
697      * @exception IOException if an input/output error occurs
698      */

699     public ServletInputStream JavaDoc createInputStream()
700         throws IOException JavaDoc {
701         if (inputStream == null) {
702             inputStream = new CoyoteInputStream(inputBuffer);
703         }
704         return inputStream;
705     }
706
707
708     /**
709      * Perform whatever actions are required to flush and close the input
710      * stream or reader, in a single operation.
711      *
712      * @exception IOException if an input/output error occurs
713      */

714     public void finishRequest() throws IOException JavaDoc {
715         // The reader and input stream don't need to be closed
716
}
717
718
719     /**
720      * Return the object bound with the specified name to the internal notes
721      * for this request, or <code>null</code> if no such binding exists.
722      *
723      * @param name Name of the note to be returned
724      */

725     public Object JavaDoc getNote(String JavaDoc name) {
726         return (notes.get(name));
727     }
728
729
730     /**
731      * Return an Iterator containing the String names of all notes bindings
732      * that exist for this request.
733      */

734     public Iterator JavaDoc getNoteNames() {
735         return (notes.keySet().iterator());
736     }
737
738
739     /**
740      * Remove any object bound to the specified name in the internal notes
741      * for this request.
742      *
743      * @param name Name of the note to be removed
744      */

745     public void removeNote(String JavaDoc name) {
746         notes.remove(name);
747     }
748
749
750     /**
751      * Bind an object to a specified name in the internal notes associated
752      * with this request, replacing any existing binding for this name.
753      *
754      * @param name Name to which the object should be bound
755      * @param value Object to be bound to the specified name
756      */

757     public void setNote(String JavaDoc name, Object JavaDoc value) {
758         notes.put(name, value);
759     }
760
761
762     /**
763      * Set the content length associated with this Request.
764      *
765      * @param length The new content length
766      */

767     public void setContentLength(int length) {
768         // Not used
769
}
770
771
772     /**
773      * Set the content type (and optionally the character encoding)
774      * associated with this Request. For example,
775      * <code>text/html; charset=ISO-8859-4</code>.
776      *
777      * @param type The new content type
778      */

779     public void setContentType(String JavaDoc type) {
780         // Not used
781
}
782
783
784     /**
785      * Set the protocol name and version associated with this Request.
786      *
787      * @param protocol Protocol name and version
788      */

789     public void setProtocol(String JavaDoc protocol) {
790         // Not used
791
}
792
793
794     /**
795      * Set the IP address of the remote client associated with this Request.
796      *
797      * @param remoteAddr The remote IP address
798      */

799     public void setRemoteAddr(String JavaDoc remoteAddr) {
800         // Not used
801
}
802
803
804     /**
805      * Set the fully qualified name of the remote client associated with this
806      * Request.
807      *
808      * @param remoteHost The remote host name
809      */

810     public void setRemoteHost(String JavaDoc remoteHost) {
811         // Not used
812
}
813
814
815     /**
816      * Set the name of the scheme associated with this request. Typical values
817      * are <code>http</code>, <code>https</code>, and <code>ftp</code>.
818      *
819      * @param scheme The scheme
820      */

821     public void setScheme(String JavaDoc scheme) {
822         // Not used
823
}
824
825
826     /**
827      * Set the value to be returned by <code>isSecure()</code>
828      * for this Request.
829      *
830      * @param secure The new isSecure value
831      */

832     public void setSecure(boolean secure) {
833         this.secure = secure;
834     }
835
836
837     /**
838      * Set the name of the server (virtual host) to process this request.
839      *
840      * @param name The server name
841      */

842     public void setServerName(String JavaDoc name) {
843         coyoteRequest.serverName().setString(name);
844     }
845
846
847     /**
848      * Set the port number of the server to process this request.
849      *
850      * @param port The server port
851      */

852     public void setServerPort(int port) {
853         coyoteRequest.setServerPort(port);
854     }
855
856
857     // ------------------------------------------------- ServletRequest Methods
858

859
860     /**
861      * Return the specified request attribute if it exists; otherwise, return
862      * <code>null</code>.
863      *
864      * @param name Name of the request attribute to return
865      */

866     public Object JavaDoc getAttribute(String JavaDoc name) {
867
868         if (name.equals(Globals.DISPATCHER_TYPE_ATTR)) {
869             return (dispatcherType == null)
870                 ? ApplicationFilterFactory.REQUEST_INTEGER
871                 : dispatcherType;
872         } else if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
873             return (requestDispatcherPath == null)
874                 ? getRequestPathMB().toString()
875                 : requestDispatcherPath.toString();
876         }
877
878         Object JavaDoc attr=attributes.get(name);
879
880         if(attr!=null)
881             return(attr);
882
883         attr = coyoteRequest.getAttribute(name);
884         if(attr != null)
885             return attr;
886         if( isSSLAttribute(name) ) {
887             coyoteRequest.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE,
888                                  coyoteRequest);
889             attr = coyoteRequest.getAttribute(Globals.CERTIFICATES_ATTR);
890             if( attr != null) {
891                 attributes.put(Globals.CERTIFICATES_ATTR, attr);
892             }
893             attr = coyoteRequest.getAttribute(Globals.CIPHER_SUITE_ATTR);
894             if(attr != null) {
895                 attributes.put(Globals.CIPHER_SUITE_ATTR, attr);
896             }
897             attr = coyoteRequest.getAttribute(Globals.KEY_SIZE_ATTR);
898             if(attr != null) {
899                 attributes.put(Globals.KEY_SIZE_ATTR, attr);
900             }
901             attr = coyoteRequest.getAttribute(Globals.SSL_SESSION_ID_ATTR);
902             if(attr != null) {
903                 attributes.put(Globals.SSL_SESSION_ID_ATTR, attr);
904             }
905             attr = attributes.get(name);
906         }
907         return attr;
908     }
909
910
911     /**
912      * Test if a given name is one of the special Servlet-spec SSL attributes.
913      */

914     static boolean isSSLAttribute(String JavaDoc name) {
915         return Globals.CERTIFICATES_ATTR.equals(name) ||
916             Globals.CIPHER_SUITE_ATTR.equals(name) ||
917             Globals.KEY_SIZE_ATTR.equals(name) ||
918             Globals.SSL_SESSION_ID_ATTR.equals(name);
919     }
920
921     /**
922      * Return the names of all request attributes for this Request, or an
923      * empty <code>Enumeration</code> if there are none.
924      */

925     public Enumeration JavaDoc getAttributeNames() {
926         if (isSecure()) {
927             getAttribute(Globals.CERTIFICATES_ATTR);
928         }
929         return new Enumerator(attributes.keySet(), true);
930     }
931
932
933     /**
934      * Return the character encoding for this Request.
935      */

936     public String JavaDoc getCharacterEncoding() {
937       return (coyoteRequest.getCharacterEncoding());
938     }
939
940
941     /**
942      * Return the content length for this Request.
943      */

944     public int getContentLength() {
945         return (coyoteRequest.getContentLength());
946     }
947
948
949     /**
950      * Return the content type for this Request.
951      */

952     public String JavaDoc getContentType() {
953         return (coyoteRequest.getContentType());
954     }
955
956
957     /**
958      * Return the servlet input stream for this Request. The default
959      * implementation returns a servlet input stream created by
960      * <code>createInputStream()</code>.
961      *
962      * @exception IllegalStateException if <code>getReader()</code> has
963      * already been called for this request
964      * @exception IOException if an input/output error occurs
965      */

966     public ServletInputStream JavaDoc getInputStream() throws IOException JavaDoc {
967
968         if (usingReader)
969             throw new IllegalStateException JavaDoc
970                 (sm.getString("coyoteRequest.getInputStream.ise"));
971
972         usingInputStream = true;
973         if (inputStream == null) {
974             inputStream = new CoyoteInputStream(inputBuffer);
975         }
976         return inputStream;
977
978     }
979
980
981     /**
982      * Return the preferred Locale that the client will accept content in,
983      * based on the value for the first <code>Accept-Language</code> header
984      * that was encountered. If the request did not specify a preferred
985      * language, the server's default Locale is returned.
986      */

987     public Locale JavaDoc getLocale() {
988
989         if (!localesParsed)
990             parseLocales();
991
992         if (locales.size() > 0) {
993             return ((Locale JavaDoc) locales.get(0));
994         } else {
995             return (defaultLocale);
996         }
997
998     }
999
1000
1001    /**
1002     * Return the set of preferred Locales that the client will accept
1003     * content in, based on the values for any <code>Accept-Language</code>
1004     * headers that were encountered. If the request did not specify a
1005     * preferred language, the server's default Locale is returned.
1006     */

1007    public Enumeration JavaDoc getLocales() {
1008
1009        if (!localesParsed)
1010            parseLocales();
1011
1012        if (locales.size() > 0)
1013            return (new Enumerator(locales));
1014        ArrayList JavaDoc results = new ArrayList JavaDoc();
1015        results.add(defaultLocale);
1016        return (new Enumerator(results));
1017
1018    }
1019
1020
1021    /**
1022     * Return the value of the specified request parameter, if any; otherwise,
1023     * return <code>null</code>. If there is more than one value defined,
1024     * return only the first one.
1025     *
1026     * @param name Name of the desired request parameter
1027     */

1028    public String JavaDoc getParameter(String JavaDoc name) {
1029
1030        if (!parametersParsed)
1031            parseParameters();
1032
1033        return coyoteRequest.getParameters().getParameter(name);
1034
1035    }
1036
1037
1038
1039    /**
1040     * Returns a <code>Map</code> of the parameters of this request.
1041     * Request parameters are extra information sent with the request.
1042     * For HTTP servlets, parameters are contained in the query string
1043     * or posted form data.
1044     *
1045     * @return A <code>Map</code> containing parameter names as keys
1046     * and parameter values as map values.
1047     */

1048    public Map JavaDoc getParameterMap() {
1049
1050        if (parameterMap.isLocked())
1051            return parameterMap;
1052
1053        Enumeration JavaDoc enumeration = getParameterNames();
1054        while (enumeration.hasMoreElements()) {
1055            String JavaDoc name = enumeration.nextElement().toString();
1056            String JavaDoc[] values = getParameterValues(name);
1057            parameterMap.put(name, values);
1058        }
1059
1060        parameterMap.setLocked(true);
1061
1062        return parameterMap;
1063
1064    }
1065
1066
1067    /**
1068     * Return the names of all defined request parameters for this request.
1069     */

1070    public Enumeration JavaDoc getParameterNames() {
1071
1072        if (!parametersParsed)
1073            parseParameters();
1074
1075        return coyoteRequest.getParameters().getParameterNames();
1076
1077    }
1078
1079
1080    /**
1081     * Return the defined values for the specified request parameter, if any;
1082     * otherwise, return <code>null</code>.
1083     *
1084     * @param name Name of the desired request parameter
1085     */

1086    public String JavaDoc[] getParameterValues(String JavaDoc name) {
1087
1088        if (!parametersParsed)
1089            parseParameters();
1090
1091        return coyoteRequest.getParameters().getParameterValues(name);
1092
1093    }
1094
1095
1096    /**
1097     * Return the protocol and version used to make this Request.
1098     */

1099    public String JavaDoc getProtocol() {
1100        return coyoteRequest.protocol().toString();
1101    }
1102
1103
1104    /**
1105     * Read the Reader wrapping the input stream for this Request. The
1106     * default implementation wraps a <code>BufferedReader</code> around the
1107     * servlet input stream returned by <code>createInputStream()</code>.
1108     *
1109     * @exception IllegalStateException if <code>getInputStream()</code>
1110     * has already been called for this request
1111     * @exception IOException if an input/output error occurs
1112     */

1113    public BufferedReader JavaDoc getReader() throws IOException JavaDoc {
1114
1115        if (usingInputStream)
1116            throw new IllegalStateException JavaDoc
1117                (sm.getString("coyoteRequest.getReader.ise"));
1118
1119        usingReader = true;
1120        inputBuffer.checkConverter();
1121        if (reader == null) {
1122            reader = new CoyoteReader(inputBuffer);
1123        }
1124        return reader;
1125
1126    }
1127
1128
1129    /**
1130     * Return the real path of the specified virtual path.
1131     *
1132     * @param path Path to be translated
1133     *
1134     * @deprecated As of version 2.1 of the Java Servlet API, use
1135     * <code>ServletContext.getRealPath()</code>.
1136     */

1137    public String JavaDoc getRealPath(String JavaDoc path) {
1138
1139        if (context == null)
1140            return (null);
1141        ServletContext JavaDoc servletContext = context.getServletContext();
1142        if (servletContext == null)
1143            return (null);
1144        else {
1145            try {
1146                return (servletContext.getRealPath(path));
1147            } catch (IllegalArgumentException JavaDoc e) {
1148                return (null);
1149            }
1150        }
1151
1152    }
1153
1154
1155    /**
1156     * Return the remote IP address making this Request.
1157     */

1158    public String JavaDoc getRemoteAddr() {
1159        if (remoteAddr == null) {
1160            coyoteRequest.action
1161                (ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, coyoteRequest);
1162            remoteAddr = coyoteRequest.remoteAddr().toString();
1163        }
1164        return remoteAddr;
1165    }
1166
1167
1168    /**
1169     * Return the remote host name making this Request.
1170     */

1171    public String JavaDoc getRemoteHost() {
1172        if (remoteHost == null) {
1173            if (!connector.getEnableLookups()) {
1174                remoteHost = getRemoteAddr();
1175            } else {
1176                coyoteRequest.action
1177                    (ActionCode.ACTION_REQ_HOST_ATTRIBUTE, coyoteRequest);
1178                remoteHost = coyoteRequest.remoteHost().toString();
1179            }
1180        }
1181        return remoteHost;
1182    }
1183
1184    /**
1185     * Returns the Internet Protocol (IP) source port of the client
1186     * or last proxy that sent the request.
1187     */

1188    public int getRemotePort(){
1189        if (remotePort == -1) {
1190            coyoteRequest.action
1191                (ActionCode.ACTION_REQ_REMOTEPORT_ATTRIBUTE, coyoteRequest);
1192            remotePort = coyoteRequest.getRemotePort();
1193        }
1194        return remotePort;
1195    }
1196
1197    /**
1198     * Returns the host name of the Internet Protocol (IP) interface on
1199     * which the request was received.
1200     */

1201    public String JavaDoc getLocalName(){
1202        if (localName == null) {
1203            coyoteRequest.action
1204                (ActionCode.ACTION_REQ_LOCAL_NAME_ATTRIBUTE, coyoteRequest);
1205            localName = coyoteRequest.localName().toString();
1206        }
1207        return localName;
1208    }
1209
1210    /**
1211     * Returns the Internet Protocol (IP) address of the interface on
1212     * which the request was received.
1213     */

1214    public String JavaDoc getLocalAddr(){
1215        if (localAddr == null) {
1216            coyoteRequest.action
1217                (ActionCode.ACTION_REQ_LOCAL_ADDR_ATTRIBUTE, coyoteRequest);
1218            localAddr = coyoteRequest.localAddr().toString();
1219        }
1220        return localAddr;
1221    }
1222
1223
1224    /**
1225     * Returns the Internet Protocol (IP) port number of the interface
1226     * on which the request was received.
1227     */

1228    public int getLocalPort(){
1229        if (localPort == -1){
1230            coyoteRequest.action
1231                (ActionCode.ACTION_REQ_LOCALPORT_ATTRIBUTE, coyoteRequest);
1232            localPort = coyoteRequest.getLocalPort();
1233        }
1234        return localPort;
1235    }
1236    
1237    /**
1238     * Return a RequestDispatcher that wraps the resource at the specified
1239     * path, which may be interpreted as relative to the current request path.
1240     *
1241     * @param path Path of the resource to be wrapped
1242     */

1243    public RequestDispatcher JavaDoc getRequestDispatcher(String JavaDoc path) {
1244
1245        if (context == null)
1246            return (null);
1247
1248        // If the path is already context-relative, just pass it through
1249
if (path == null)
1250            return (null);
1251        else if (path.startsWith("/"))
1252            return (context.getServletContext().getRequestDispatcher(path));
1253
1254        // Convert a request-relative path to a context-relative one
1255
String JavaDoc servletPath = (String JavaDoc) getAttribute(Globals.INCLUDE_SERVLET_PATH_ATTR);
1256        if (servletPath == null)
1257            servletPath = getServletPath();
1258
1259        // Add the path info, if there is any
1260
String JavaDoc pathInfo = getPathInfo();
1261        String JavaDoc requestPath = null;
1262
1263        if (pathInfo == null) {
1264            requestPath = servletPath;
1265        } else {
1266            requestPath = servletPath + pathInfo;
1267        }
1268
1269        int pos = requestPath.lastIndexOf('/');
1270        String JavaDoc relative = null;
1271        if (pos >= 0) {
1272            relative = RequestUtil.normalize
1273                (requestPath.substring(0, pos + 1) + path);
1274        } else {
1275            relative = RequestUtil.normalize(requestPath + path);
1276        }
1277
1278        return (context.getServletContext().getRequestDispatcher(relative));
1279
1280    }
1281
1282
1283    /**
1284     * Return the scheme used to make this Request.
1285     */

1286    public String JavaDoc getScheme() {
1287        return (coyoteRequest.scheme().toString());
1288    }
1289
1290
1291    /**
1292     * Return the server name responding to this Request.
1293     */

1294    public String JavaDoc getServerName() {
1295        return (coyoteRequest.serverName().toString());
1296    }
1297
1298
1299    /**
1300     * Return the server port responding to this Request.
1301     */

1302    public int getServerPort() {
1303        return (coyoteRequest.getServerPort());
1304    }
1305
1306
1307    /**
1308     * Was this request received on a secure connection?
1309     */

1310    public boolean isSecure() {
1311        return (secure);
1312    }
1313
1314
1315    /**
1316     * Remove the specified request attribute if it exists.
1317     *
1318     * @param name Name of the request attribute to remove
1319     */

1320    public void removeAttribute(String JavaDoc name) {
1321        Object JavaDoc value = null;
1322        boolean found = false;
1323
1324        // Remove the specified attribute
1325
// Check for read only attribute
1326
// requests are per thread so synchronization unnecessary
1327
if (readOnlyAttributes.containsKey(name)) {
1328            return;
1329        }
1330
1331        // Pass special attributes to the native layer
1332
if (name.startsWith("org.apache.tomcat.")) {
1333            coyoteRequest.getAttributes().remove(name);
1334        }
1335
1336        found = attributes.containsKey(name);
1337        if (found) {
1338            value = attributes.get(name);
1339            attributes.remove(name);
1340        } else {
1341            return;
1342        }
1343        
1344        // Notify interested application event listeners
1345
Object JavaDoc listeners[] = context.getApplicationEventListeners();
1346        if ((listeners == null) || (listeners.length == 0))
1347            return;
1348        ServletRequestAttributeEvent JavaDoc event =
1349          new ServletRequestAttributeEvent JavaDoc(context.getServletContext(),
1350                                           getRequest(), name, value);
1351        for (int i = 0; i < listeners.length; i++) {
1352            if (!(listeners[i] instanceof ServletRequestAttributeListener JavaDoc))
1353                continue;
1354            ServletRequestAttributeListener JavaDoc listener =
1355                (ServletRequestAttributeListener JavaDoc) listeners[i];
1356            try {
1357                listener.attributeRemoved(event);
1358            } catch (Throwable JavaDoc t) {
1359                context.getLogger().error(sm.getString("coyoteRequest.attributeEvent"), t);
1360                // Error valve will pick this execption up and display it to user
1361
attributes.put( Globals.EXCEPTION_ATTR, t );
1362            }
1363        }
1364    }
1365
1366
1367    /**
1368     * Set the specified request attribute to the specified value.
1369     *
1370     * @param name Name of the request attribute to set
1371     * @param value The associated value
1372     */

1373    public void setAttribute(String JavaDoc name, Object JavaDoc value) {
1374    
1375        // Name cannot be null
1376
if (name == null)
1377            throw new IllegalArgumentException JavaDoc
1378                (sm.getString("coyoteRequest.setAttribute.namenull"));
1379
1380        // Null value is the same as removeAttribute()
1381
if (value == null) {
1382            removeAttribute(name);
1383            return;
1384        }
1385
1386        if (name.equals(Globals.DISPATCHER_TYPE_ATTR)) {
1387            dispatcherType = value;
1388            return;
1389        } else if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
1390            requestDispatcherPath = value;
1391            return;
1392        }
1393
1394        Object JavaDoc oldValue = null;
1395        boolean replaced = false;
1396
1397        // Add or replace the specified attribute
1398
// Check for read only attribute
1399
// requests are per thread so synchronization unnecessary
1400
if (readOnlyAttributes.containsKey(name)) {
1401            return;
1402        }
1403
1404        oldValue = attributes.put(name, value);
1405        if (oldValue != null) {
1406            replaced = true;
1407        }
1408
1409        // Pass special attributes to the native layer
1410
if (name.startsWith("org.apache.tomcat.")) {
1411            coyoteRequest.setAttribute(name, value);
1412        }
1413        
1414        // Notify interested application event listeners
1415
Object JavaDoc listeners[] = context.getApplicationEventListeners();
1416        if ((listeners == null) || (listeners.length == 0))
1417            return;
1418        ServletRequestAttributeEvent JavaDoc event = null;
1419        if (replaced)
1420            event =
1421                new ServletRequestAttributeEvent JavaDoc(context.getServletContext(),
1422                                                 getRequest(), name, oldValue);
1423        else
1424            event =
1425                new ServletRequestAttributeEvent JavaDoc(context.getServletContext(),
1426                                                 getRequest(), name, value);
1427
1428        for (int i = 0; i < listeners.length; i++) {
1429            if (!(listeners[i] instanceof ServletRequestAttributeListener JavaDoc))
1430                continue;
1431            ServletRequestAttributeListener JavaDoc listener =
1432                (ServletRequestAttributeListener JavaDoc) listeners[i];
1433            try {
1434                if (replaced) {
1435                    listener.attributeReplaced(event);
1436                } else {
1437                    listener.attributeAdded(event);
1438                }
1439            } catch (Throwable JavaDoc t) {
1440                context.getLogger().error(sm.getString("coyoteRequest.attributeEvent"), t);
1441                // Error valve will pick this execption up and display it to user
1442
attributes.put( Globals.EXCEPTION_ATTR, t );
1443            }
1444        }
1445    }
1446
1447
1448    /**
1449     * Overrides the name of the character encoding used in the body of
1450     * this request. This method must be called prior to reading request
1451     * parameters or reading input using <code>getReader()</code>.
1452     *
1453     * @param enc The character encoding to be used
1454     *
1455     * @exception UnsupportedEncodingException if the specified encoding
1456     * is not supported
1457     *
1458     * @since Servlet 2.3
1459     */

1460    public void setCharacterEncoding(String JavaDoc enc)
1461        throws UnsupportedEncodingException JavaDoc {
1462
1463        if (usingReader)
1464            return;
1465        
1466        // Ensure that the specified encoding is valid
1467
byte buffer[] = new byte[1];
1468        buffer[0] = (byte) 'a';
1469        String JavaDoc dummy = new String JavaDoc(buffer, enc);
1470
1471        // Save the validated encoding
1472
coyoteRequest.setCharacterEncoding(enc);
1473
1474    }
1475
1476
1477    // ---------------------------------------------------- HttpRequest Methods
1478

1479
1480    /**
1481     * Add a Cookie to the set of Cookies associated with this Request.
1482     *
1483     * @param cookie The new cookie
1484     */

1485    public void addCookie(Cookie JavaDoc cookie) {
1486
1487        if (!cookiesParsed)
1488            parseCookies();
1489
1490        int size = 0;
1491        if (cookies != null) {
1492            size = cookies.length;
1493        }
1494
1495        Cookie JavaDoc[] newCookies = new Cookie JavaDoc[size + 1];
1496        for (int i = 0; i < size; i++) {
1497            newCookies[i] = cookies[i];
1498        }
1499        newCookies[size] = cookie;
1500
1501        cookies = newCookies;
1502
1503    }
1504
1505
1506    /**
1507     * Add a Header to the set of Headers associated with this Request.
1508     *
1509     * @param name The new header name
1510     * @param value The new header value
1511     */

1512    public void addHeader(String JavaDoc name, String JavaDoc value) {
1513        // Not used
1514
}
1515
1516
1517    /**
1518     * Add a Locale to the set of preferred Locales for this Request. The
1519     * first added Locale will be the first one returned by getLocales().
1520     *
1521     * @param locale The new preferred Locale
1522     */

1523    public void addLocale(Locale JavaDoc locale) {
1524        locales.add(locale);
1525    }
1526
1527
1528    /**
1529     * Add a parameter name and corresponding set of values to this Request.
1530     * (This is used when restoring the original request on a form based
1531     * login).
1532     *
1533     * @param name Name of this request parameter
1534     * @param values Corresponding values for this request parameter
1535     */

1536    public void addParameter(String JavaDoc name, String JavaDoc values[]) {
1537        coyoteRequest.getParameters().addParameterValues(name, values);
1538    }
1539
1540
1541    /**
1542     * Clear the collection of Cookies associated with this Request.
1543     */

1544    public void clearCookies() {
1545        cookiesParsed = true;
1546        cookies = null;
1547    }
1548
1549
1550    /**
1551     * Clear the collection of Headers associated with this Request.
1552     */

1553    public void clearHeaders() {
1554        // Not used
1555
}
1556
1557
1558    /**
1559     * Clear the collection of Locales associated with this Request.
1560     */

1561    public void clearLocales() {
1562        locales.clear();
1563    }
1564
1565
1566    /**
1567     * Clear the collection of parameters associated with this Request.
1568     */

1569    public void clearParameters() {
1570        // Not used
1571
}
1572
1573
1574    /**
1575     * Set the authentication type used for this request, if any; otherwise
1576     * set the type to <code>null</code>. Typical values are "BASIC",
1577     * "DIGEST", or "SSL".
1578     *
1579     * @param type The authentication type used
1580     */

1581    public void setAuthType(String JavaDoc type) {
1582        this.authType = type;
1583    }
1584
1585
1586    /**
1587     * Set the context path for this Request. This will normally be called
1588     * when the associated Context is mapping the Request to a particular
1589     * Wrapper.
1590     *
1591     * @param path The context path
1592     */

1593    public void setContextPath(String JavaDoc path) {
1594
1595        if (path == null) {
1596            mappingData.contextPath.setString("");
1597        } else {
1598            mappingData.contextPath.setString(path);
1599        }
1600
1601    }
1602
1603
1604    /**
1605     * Set the HTTP request method used for this Request.
1606     *
1607     * @param method The request method
1608     */

1609    public void setMethod(String JavaDoc method) {
1610        // Not used
1611
}
1612
1613
1614    /**
1615     * Set the query string for this Request. This will normally be called
1616     * by the HTTP Connector, when it parses the request headers.
1617     *
1618     * @param query The query string
1619     */

1620    public void setQueryString(String JavaDoc query) {
1621        // Not used
1622
}
1623
1624
1625    /**
1626     * Set the path information for this Request. This will normally be called
1627     * when the associated Context is mapping the Request to a particular
1628     * Wrapper.
1629     *
1630     * @param path The path information
1631     */

1632    public void setPathInfo(String JavaDoc path) {
1633        mappingData.pathInfo.setString(path);
1634    }
1635
1636
1637    /**
1638     * Set a flag indicating whether or not the requested session ID for this
1639     * request came in through a cookie. This is normally called by the
1640     * HTTP Connector, when it parses the request headers.
1641     *
1642     * @param flag The new flag
1643     */

1644    public void setRequestedSessionCookie(boolean flag) {
1645
1646        this.requestedSessionCookie = flag;
1647
1648    }
1649
1650
1651    /**
1652     * Set the requested session ID for this request. This is normally called
1653     * by the HTTP Connector, when it parses the request headers.
1654     *
1655     * @param id The new session id
1656     */

1657    public void setRequestedSessionId(String JavaDoc id) {
1658
1659        this.requestedSessionId = id;
1660
1661    }
1662
1663
1664    /**
1665     * Set a flag indicating whether or not the requested session ID for this
1666     * request came in through a URL. This is normally called by the
1667     * HTTP Connector, when it parses the request headers.
1668     *
1669     * @param flag The new flag
1670     */

1671    public void setRequestedSessionURL(boolean flag) {
1672
1673        this.requestedSessionURL = flag;
1674
1675    }
1676
1677
1678    /**
1679     * Set the unparsed request URI for this Request. This will normally be
1680     * called by the HTTP Connector, when it parses the request headers.
1681     *
1682     * @param uri The request URI
1683     */

1684    public void setRequestURI(String JavaDoc uri) {
1685        // Not used
1686
}
1687
1688
1689    /**
1690     * Set the decoded request URI.
1691     *
1692     * @param uri The decoded request URI
1693     */

1694    public void setDecodedRequestURI(String JavaDoc uri) {
1695        // Not used
1696
}
1697
1698
1699    /**
1700     * Get the decoded request URI.
1701     *
1702     * @return the URL decoded request URI
1703     */

1704    public String JavaDoc getDecodedRequestURI() {
1705        return (coyoteRequest.decodedURI().toString());
1706    }
1707
1708
1709    /**
1710     * Get the decoded request URI.
1711     *
1712     * @return the URL decoded request URI
1713     */

1714    public MessageBytes getDecodedRequestURIMB() {
1715        return (coyoteRequest.decodedURI());
1716    }
1717
1718
1719    /**
1720     * Set the servlet path for this Request. This will normally be called
1721     * when the associated Context is mapping the Request to a particular
1722     * Wrapper.
1723     *
1724     * @param path The servlet path
1725     */

1726    public void setServletPath(String JavaDoc path) {
1727        if (path != null)
1728            mappingData.wrapperPath.setString(path);
1729    }
1730
1731
1732    /**
1733     * Set the Principal who has been authenticated for this Request. This
1734     * value is also used to calculate the value to be returned by the
1735     * <code>getRemoteUser()</code> method.
1736     *
1737     * @param principal The user Principal
1738     */

1739    public void setUserPrincipal(Principal JavaDoc principal) {
1740
1741        if (System.getSecurityManager() != null){
1742            HttpSession JavaDoc session = getSession(false);
1743            if ( (subject != null) &&
1744                 (!subject.getPrincipals().contains(principal)) ){
1745                subject.getPrincipals().add(principal);
1746            } else if (session != null &&
1747                        session.getAttribute(Globals.SUBJECT_ATTR) == null) {
1748                subject = new Subject JavaDoc();
1749                subject.getPrincipals().add(principal);
1750            }
1751            if (session != null){
1752                session.setAttribute(Globals.SUBJECT_ATTR, subject);
1753            }
1754        }
1755
1756        this.userPrincipal = principal;
1757    }
1758
1759
1760    // --------------------------------------------- HttpServletRequest Methods
1761

1762
1763    /**
1764     * Return the authentication type used for this Request.
1765     */

1766    public String JavaDoc getAuthType() {
1767        return (authType);
1768    }
1769
1770
1771    /**
1772     * Return the portion of the request URI used to select the Context
1773     * of the Request.
1774     */

1775    public String JavaDoc getContextPath() {
1776        return (mappingData.contextPath.toString());
1777    }
1778
1779
1780    /**
1781     * Get the context path.
1782     *
1783     * @return the context path
1784     */

1785    public MessageBytes getContextPathMB() {
1786        return (mappingData.contextPath);
1787    }
1788
1789
1790    /**
1791     * Return the set of Cookies received with this Request.
1792     */

1793    public Cookie JavaDoc[] getCookies() {
1794
1795        if (!cookiesParsed)
1796            parseCookies();
1797
1798        return cookies;
1799
1800    }
1801
1802
1803    /**
1804     * Set the set of cookies recieved with this Request.
1805     */

1806    public void setCookies(Cookie JavaDoc[] cookies) {
1807
1808        this.cookies = cookies;
1809
1810    }
1811
1812
1813    /**
1814     * Return the value of the specified date header, if any; otherwise
1815     * return -1.
1816     *
1817     * @param name Name of the requested date header
1818     *
1819     * @exception IllegalArgumentException if the specified header value
1820     * cannot be converted to a date
1821     */

1822    public long getDateHeader(String JavaDoc name) {
1823
1824        String JavaDoc value = getHeader(name);
1825        if (value == null)
1826            return (-1L);
1827
1828        // Attempt to convert the date header in a variety of formats
1829
long result = FastHttpDateFormat.parseDate(value, formats);
1830        if (result != (-1L)) {
1831            return result;
1832        }
1833        throw new IllegalArgumentException JavaDoc(value);
1834
1835    }
1836
1837
1838    /**
1839     * Return the first value of the specified header, if any; otherwise,
1840     * return <code>null</code>
1841     *
1842     * @param name Name of the requested header
1843     */

1844    public String JavaDoc getHeader(String JavaDoc name) {
1845        return coyoteRequest.getHeader(name);
1846    }
1847
1848
1849    /**
1850     * Return all of the values of the specified header, if any; otherwise,
1851     * return an empty enumeration.
1852     *
1853     * @param name Name of the requested header
1854     */

1855    public Enumeration JavaDoc getHeaders(String JavaDoc name) {
1856        return coyoteRequest.getMimeHeaders().values(name);
1857    }
1858
1859
1860    /**
1861     * Return the names of all headers received with this request.
1862     */

1863    public Enumeration JavaDoc getHeaderNames() {
1864        return coyoteRequest.getMimeHeaders().names();
1865    }
1866
1867
1868    /**
1869     * Return the value of the specified header as an integer, or -1 if there
1870     * is no such header for this request.
1871     *
1872     * @param name Name of the requested header
1873     *
1874     * @exception IllegalArgumentException if the specified header value
1875     * cannot be converted to an integer
1876     */

1877    public int getIntHeader(String JavaDoc name) {
1878
1879        String JavaDoc value = getHeader(name);
1880        if (value == null) {
1881            return (-1);
1882        } else {
1883            return (Integer.parseInt(value));
1884        }
1885
1886    }
1887
1888
1889    /**
1890     * Return the HTTP request method used in this Request.
1891     */

1892    public String JavaDoc getMethod() {
1893        return coyoteRequest.method().toString();
1894    }
1895
1896
1897    /**
1898     * Return the path information associated with this Request.
1899     */

1900    public String JavaDoc getPathInfo() {
1901        return (mappingData.pathInfo.toString());
1902    }
1903
1904
1905    /**
1906     * Get the path info.
1907     *
1908     * @return the path info
1909     */

1910    public MessageBytes getPathInfoMB() {
1911        return (mappingData.pathInfo);
1912    }
1913
1914
1915    /**
1916     * Return the extra path information for this request, translated
1917     * to a real path.
1918     */

1919    public String JavaDoc getPathTranslated() {
1920
1921        if (context == null)
1922            return (null);
1923
1924        if (getPathInfo() == null) {
1925            return (null);
1926        } else {
1927            return (context.getServletContext().getRealPath(getPathInfo()));
1928        }
1929
1930    }
1931
1932
1933    /**
1934     * Return the query string associated with this request.
1935     */

1936    public String JavaDoc getQueryString() {
1937        String JavaDoc queryString = coyoteRequest.queryString().toString();
1938        if (queryString == null || queryString.equals("")) {
1939            return (null);
1940        } else {
1941            return queryString;
1942        }
1943    }
1944
1945
1946    /**
1947     * Return the name of the remote user that has been authenticated
1948     * for this Request.
1949     */

1950    public String JavaDoc getRemoteUser() {
1951
1952        if (userPrincipal != null) {
1953            return (userPrincipal.getName());
1954        } else {
1955            return (null);
1956        }
1957
1958    }
1959
1960
1961    /**
1962     * Get the request path.
1963     *
1964     * @return the request path
1965     */

1966    public MessageBytes getRequestPathMB() {
1967        return (mappingData.requestPath);
1968    }
1969
1970
1971    /**
1972     * Return the session identifier included in this request, if any.
1973     */

1974    public String JavaDoc getRequestedSessionId() {
1975        return (requestedSessionId);
1976    }
1977
1978
1979    /**
1980     * Return the request URI for this request.
1981     */

1982    public String JavaDoc getRequestURI() {
1983        return coyoteRequest.requestURI().toString();
1984    }
1985
1986
1987    /**
1988     * Reconstructs the URL the client used to make the request.
1989     * The returned URL contains a protocol, server name, port
1990     * number, and server path, but it does not include query
1991     * string parameters.
1992     * <p>
1993     * Because this method returns a <code>StringBuffer</code>,
1994     * not a <code>String</code>, you can modify the URL easily,
1995     * for example, to append query parameters.
1996     * <p>
1997     * This method is useful for creating redirect messages and
1998     * for reporting errors.
1999     *
2000     * @return A <code>StringBuffer</code> object containing the
2001     * reconstructed URL
2002     */

2003    public StringBuffer JavaDoc getRequestURL() {
2004
2005        StringBuffer JavaDoc url = new StringBuffer JavaDoc();
2006        String JavaDoc scheme = getScheme();
2007        int port = getServerPort();
2008        if (port < 0)
2009            port = 80; // Work around java.net.URL bug
2010

2011        url.append(scheme);
2012        url.append("://");
2013        url.append(getServerName());
2014        if ((scheme.equals("http") && (port != 80))
2015            || (scheme.equals("https") && (port != 443))) {
2016            url.append(':');
2017            url.append(port);
2018        }
2019        url.append(getRequestURI());
2020
2021        return (url);
2022
2023    }
2024
2025
2026    /**
2027     * Return the portion of the request URI used to select the servlet
2028     * that will process this request.
2029     */

2030    public String JavaDoc getServletPath() {
2031        return (mappingData.wrapperPath.toString());
2032    }
2033
2034
2035    /**
2036     * Get the servlet path.
2037     *
2038     * @return the servlet path
2039     */

2040    public MessageBytes getServletPathMB() {
2041        return (mappingData.wrapperPath);
2042    }
2043
2044
2045    /**
2046     * Return the session associated with this Request, creating one
2047     * if necessary.
2048     */

2049    public HttpSession JavaDoc getSession() {
2050        Session JavaDoc session = doGetSession(true);
2051        if (session != null) {
2052            return session.getSession();
2053        } else {
2054            return null;
2055        }
2056    }
2057
2058
2059    /**
2060     * Return the session associated with this Request, creating one
2061     * if necessary and requested.
2062     *
2063     * @param create Create a new session if one does not exist
2064     */

2065    public HttpSession JavaDoc getSession(boolean create) {
2066        Session JavaDoc session = doGetSession(create);
2067        if (session != null) {
2068            return session.getSession();
2069        } else {
2070            return null;
2071        }
2072    }
2073
2074
2075    /**
2076     * Return <code>true</code> if the session identifier included in this
2077     * request came from a cookie.
2078     */

2079    public boolean isRequestedSessionIdFromCookie() {
2080
2081        if (requestedSessionId != null)
2082            return (requestedSessionCookie);
2083        else
2084            return (false);
2085
2086    }
2087
2088
2089    /**
2090     * Return <code>true</code> if the session identifier included in this
2091     * request came from the request URI.
2092     */

2093    public boolean isRequestedSessionIdFromURL() {
2094
2095        if (requestedSessionId != null)
2096            return (requestedSessionURL);
2097        else
2098            return (false);
2099
2100    }
2101
2102
2103    /**
2104     * Return <code>true</code> if the session identifier included in this
2105     * request came from the request URI.
2106     *
2107     * @deprecated As of Version 2.1 of the Java Servlet API, use
2108     * <code>isRequestedSessionIdFromURL()</code> instead.
2109     */

2110    public boolean isRequestedSessionIdFromUrl() {
2111        return (isRequestedSessionIdFromURL());
2112    }
2113
2114
2115    /**
2116     * Return <code>true</code> if the session identifier included in this
2117     * request identifies a valid session.
2118     */

2119    public boolean isRequestedSessionIdValid() {
2120
2121        if (requestedSessionId == null)
2122            return (false);
2123        if (context == null)
2124            return (false);
2125        Manager manager = context.getManager();
2126        if (manager == null)
2127            return (false);
2128        Session JavaDoc session = null;
2129        try {
2130            session = manager.findSession(requestedSessionId);
2131        } catch (IOException JavaDoc e) {
2132            session = null;
2133        }
2134        if ((session != null) && session.isValid())
2135            return (true);
2136        else
2137            return (false);
2138
2139    }
2140
2141
2142    /**
2143     * Return <code>true</code> if the authenticated user principal
2144     * possesses the specified role name.
2145     *
2146     * @param role Role name to be validated
2147     */

2148    public boolean isUserInRole(String JavaDoc role) {
2149
2150        // Have we got an authenticated principal at all?
2151
if (userPrincipal == null)
2152            return (false);
2153
2154        // Identify the Realm we will use for checking role assignmenets
2155
if (context == null)
2156            return (false);
2157        Realm realm = context.getRealm();
2158        if (realm == null)
2159            return (false);
2160
2161        // Check for a role alias defined in a <security-role-ref> element
2162
if (wrapper != null) {
2163            String JavaDoc realRole = wrapper.findSecurityReference(role);
2164            if ((realRole != null) &&
2165                realm.hasRole(userPrincipal, realRole))
2166                return (true);
2167        }
2168
2169        // Check for a role defined directly as a <security-role>
2170
return (realm.hasRole(userPrincipal, role));
2171
2172    }
2173
2174
2175    /**
2176     * Return the principal that has been authenticated for this Request.
2177     */

2178    public Principal JavaDoc getPrincipal() {
2179        return (userPrincipal);
2180    }
2181
2182
2183    /**
2184     * Return the principal that has been authenticated for this Request.
2185     */

2186    public Principal JavaDoc getUserPrincipal() {
2187        if (userPrincipal instanceof GenericPrincipal) {
2188            return ((GenericPrincipal) userPrincipal).getUserPrincipal();
2189        } else {
2190            return (userPrincipal);
2191        }
2192    }
2193
2194
2195    /**
2196     * Return the session associated with this Request, creating one
2197     * if necessary.
2198     */

2199    public Session JavaDoc getSessionInternal() {
2200        return doGetSession(true);
2201    }
2202
2203
2204    /**
2205     * Return the session associated with this Request, creating one
2206     * if necessary and requested.
2207     *
2208     * @param create Create a new session if one does not exist
2209     */

2210    public Session JavaDoc getSessionInternal(boolean create) {
2211        return doGetSession(create);
2212    }
2213
2214
2215    /**
2216     * Get the event associated with the request.
2217     * @return
2218     */

2219    public CometEventImpl getEvent() {
2220        if (event == null) {
2221            event = new CometEventImpl(this, response);
2222        }
2223        return event;
2224    }
2225    
2226    
2227    /**
2228     * Return true if the current request is handling Comet traffic.
2229     */

2230    public boolean isComet() {
2231        return comet;
2232    }
2233
2234    
2235    /**
2236     * Set comet state.
2237     */

2238    public void setComet(boolean comet) {
2239        this.comet = comet;
2240    }
2241
2242    
2243    // ------------------------------------------------------ Protected Methods
2244

2245
2246    protected Session JavaDoc doGetSession(boolean create) {
2247
2248        // There cannot be a session if no context has been assigned yet
2249
if (context == null)
2250            return (null);
2251
2252        // Return the current session if it exists and is valid
2253
if ((session != null) && !session.isValid())
2254            session = null;
2255        if (session != null)
2256            return (session);
2257
2258        // Return the requested session if it exists and is valid
2259
Manager manager = null;
2260        if (context != null)
2261            manager = context.getManager();
2262        if (manager == null)
2263            return (null); // Sessions are not supported
2264
if (requestedSessionId != null) {
2265            try {
2266                session = manager.findSession(requestedSessionId);
2267            } catch (IOException JavaDoc e) {
2268                session = null;
2269            }
2270            if ((session != null) && !session.isValid())
2271                session = null;
2272            if (session != null) {
2273                session.access();
2274                return (session);
2275            }
2276        }
2277
2278        // Create a new session if requested and the response is not committed
2279
if (!create)
2280            return (null);
2281        if ((context != null) && (response != null) &&
2282            context.getCookies() &&
2283            response.getResponse().isCommitted()) {
2284            throw new IllegalStateException JavaDoc
2285              (sm.getString("coyoteRequest.sessionCreateCommitted"));
2286        }
2287
2288        // Attempt to reuse session id if one was submitted in a cookie
2289
// Do not reuse the session id if it is from a URL, to prevent possible
2290
// phishing attacks
2291
if (connector.getEmptySessionPath()
2292                && isRequestedSessionIdFromCookie()) {
2293            session = manager.createSession(getRequestedSessionId());
2294        } else {
2295            session = manager.createSession(null);
2296        }
2297
2298        // Creating a new session cookie based on that session
2299
if ((session != null) && (getContext() != null)
2300               && getContext().getCookies()) {
2301            Cookie JavaDoc cookie = new Cookie JavaDoc(Globals.SESSION_COOKIE_NAME,
2302                                       session.getIdInternal());
2303            configureSessionCookie(cookie);
2304            response.addCookieInternal(cookie);
2305        }
2306
2307        if (session != null) {
2308            session.access();
2309            return (session);
2310        } else {
2311            return (null);
2312        }
2313
2314    }
2315
2316    /**
2317     * Configures the given JSESSIONID cookie.
2318     *
2319     * @param cookie The JSESSIONID cookie to be configured
2320     */

2321    protected void configureSessionCookie(Cookie JavaDoc cookie) {
2322        cookie.setMaxAge(-1);
2323        String JavaDoc contextPath = null;
2324        if (!connector.getEmptySessionPath() && (getContext() != null)) {
2325            contextPath = getContext().getEncodedPath();
2326        }
2327        if ((contextPath != null) && (contextPath.length() > 0)) {
2328            cookie.setPath(contextPath);
2329        } else {
2330            cookie.setPath("/");
2331        }
2332        if (isSecure()) {
2333            cookie.setSecure(true);
2334        }
2335    }
2336
2337    /**
2338     * Parse cookies.
2339     */

2340    protected void parseCookies() {
2341
2342        cookiesParsed = true;
2343
2344        Cookies serverCookies = coyoteRequest.getCookies();
2345        int count = serverCookies.getCookieCount();
2346        if (count <= 0)
2347            return;
2348
2349        cookies = new Cookie JavaDoc[count];
2350
2351        int idx=0;
2352        for (int i = 0; i < count; i++) {
2353            ServerCookie scookie = serverCookies.getCookie(i);
2354            try {
2355                Cookie JavaDoc cookie = new Cookie JavaDoc(scookie.getName().toString(),
2356                                           scookie.getValue().toString());
2357                cookie.setPath(scookie.getPath().toString());
2358                cookie.setVersion(scookie.getVersion());
2359                String JavaDoc domain = scookie.getDomain().toString();
2360                if (domain != null) {
2361                    cookie.setDomain(scookie.getDomain().toString());
2362                }
2363                cookies[idx++] = cookie;
2364            } catch(IllegalArgumentException JavaDoc e) {
2365                // Ignore bad cookie
2366
}
2367        }
2368        if( idx < count ) {
2369            Cookie JavaDoc [] ncookies = new Cookie JavaDoc[idx];
2370            System.arraycopy(cookies, 0, ncookies, 0, idx);
2371            cookies = ncookies;
2372        }
2373
2374    }
2375
2376    /**
2377     * Parse request parameters.
2378     */

2379    protected void parseParameters() {
2380
2381        parametersParsed = true;
2382
2383        Parameters parameters = coyoteRequest.getParameters();
2384
2385        // getCharacterEncoding() may have been overridden to search for
2386
// hidden form field containing request encoding
2387
String JavaDoc enc = getCharacterEncoding();
2388
2389        boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
2390        if (enc != null) {
2391            parameters.setEncoding(enc);
2392            if (useBodyEncodingForURI) {
2393                parameters.setQueryStringEncoding(enc);
2394            }
2395        } else {
2396            parameters.setEncoding
2397                (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
2398            if (useBodyEncodingForURI) {
2399                parameters.setQueryStringEncoding
2400                    (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
2401            }
2402        }
2403
2404        parameters.handleQueryParameters();
2405
2406        if (usingInputStream || usingReader)
2407            return;
2408
2409        if (!getMethod().equalsIgnoreCase("POST"))
2410            return;
2411
2412        String JavaDoc contentType = getContentType();
2413        if (contentType == null)
2414            contentType = "";
2415        int semicolon = contentType.indexOf(';');
2416        if (semicolon >= 0) {
2417            contentType = contentType.substring(0, semicolon).trim();
2418        } else {
2419            contentType = contentType.trim();
2420        }
2421        if (!("application/x-www-form-urlencoded".equals(contentType)))
2422            return;
2423
2424        int len = getContentLength();
2425
2426        if (len > 0) {
2427            int maxPostSize = connector.getMaxPostSize();
2428            if ((maxPostSize > 0) && (len > maxPostSize)) {
2429                context.getLogger().info
2430                    (sm.getString("coyoteRequest.postTooLarge"));
2431                throw new IllegalStateException JavaDoc("Post too large");
2432            }
2433            try {
2434                byte[] formData = null;
2435                if (len < CACHED_POST_LEN) {
2436                    if (postData == null)
2437                        postData = new byte[CACHED_POST_LEN];
2438                    formData = postData;
2439                } else {
2440                    formData = new byte[len];
2441                }
2442                int actualLen = readPostBody(formData, len);
2443                if (actualLen == len) {
2444                    parameters.processParameters(formData, 0, len);
2445                }
2446            } catch (Throwable JavaDoc t) {
2447                ; // Ignore
2448
}
2449        }
2450
2451    }
2452
2453
2454    /**
2455     * Read post body in an array.
2456     */

2457    protected int readPostBody(byte body[], int len)
2458        throws IOException JavaDoc {
2459
2460        int offset = 0;
2461        do {
2462            int inputLen = getStream().read(body, offset, len - offset);
2463            if (inputLen <= 0) {
2464                return offset;
2465            }
2466            offset += inputLen;
2467        } while ((len - offset) > 0);
2468        return len;
2469
2470    }
2471
2472
2473    /**
2474     * Parse request locales.
2475     */

2476    protected void parseLocales() {
2477
2478        localesParsed = true;
2479
2480        Enumeration JavaDoc values = getHeaders("accept-language");
2481
2482        while (values.hasMoreElements()) {
2483            String JavaDoc value = values.nextElement().toString();
2484            parseLocalesHeader(value);
2485        }
2486
2487    }
2488
2489
2490    /**
2491     * Parse accept-language header value.
2492     */

2493    protected void parseLocalesHeader(String JavaDoc value) {
2494
2495        // Store the accumulated languages that have been requested in
2496
// a local collection, sorted by the quality value (so we can
2497
// add Locales in descending order). The values will be ArrayLists
2498
// containing the corresponding Locales to be added
2499
TreeMap JavaDoc locales = new TreeMap JavaDoc();
2500
2501        // Preprocess the value to remove all whitespace
2502
int white = value.indexOf(' ');
2503        if (white < 0)
2504            white = value.indexOf('\t');
2505        if (white >= 0) {
2506            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
2507            int len = value.length();
2508            for (int i = 0; i < len; i++) {
2509                char ch = value.charAt(i);
2510                if ((ch != ' ') && (ch != '\t'))
2511                    sb.append(ch);
2512            }
2513            value = sb.toString();
2514        }
2515
2516        // Process each comma-delimited language specification
2517
parser.setString(value); // ASSERT: parser is available to us
2518
int length = parser.getLength();
2519        while (true) {
2520
2521            // Extract the next comma-delimited entry
2522
int start = parser.getIndex();
2523            if (start >= length)
2524                break;
2525            int end = parser.findChar(',');
2526            String JavaDoc entry = parser.extract(start, end).trim();
2527            parser.advance(); // For the following entry
2528

2529            // Extract the quality factor for this entry
2530
double quality = 1.0;
2531            int semi = entry.indexOf(";q=");
2532            if (semi >= 0) {
2533                try {
2534                    quality = Double.parseDouble(entry.substring(semi + 3));
2535                } catch (NumberFormatException JavaDoc e) {
2536                    quality = 0.0;
2537                }
2538                entry = entry.substring(0, semi);
2539            }
2540
2541            // Skip entries we are not going to keep track of
2542
if (quality < 0.00005)
2543                continue; // Zero (or effectively zero) quality factors
2544
if ("*".equals(entry))
2545                continue; // FIXME - "*" entries are not handled
2546

2547            // Extract the language and country for this entry
2548
String JavaDoc language = null;
2549            String JavaDoc country = null;
2550            String JavaDoc variant = null;
2551            int dash = entry.indexOf('-');
2552            if (dash < 0) {
2553                language = entry;
2554                country = "";
2555                variant = "";
2556            } else {
2557                language = entry.substring(0, dash);
2558                country = entry.substring(dash + 1);
2559                int vDash = country.indexOf('-');
2560                if (vDash > 0) {
2561                    String JavaDoc cTemp = country.substring(0, vDash);
2562                    variant = country.substring(vDash + 1);
2563                    country = cTemp;
2564                } else {
2565                    variant = "";
2566                }
2567            }
2568
2569            // Add a new Locale to the list of Locales for this quality level
2570
Locale JavaDoc locale = new Locale JavaDoc(language, country, variant);
2571            Double JavaDoc key = new Double JavaDoc(-quality); // Reverse the order
2572
ArrayList JavaDoc values = (ArrayList JavaDoc) locales.get(key);
2573            if (values == null) {
2574                values = new ArrayList JavaDoc();
2575                locales.put(key, values);
2576            }
2577            values.add(locale);
2578
2579        }
2580
2581        // Process the quality values in highest->lowest order (due to
2582
// negating the Double value when creating the key)
2583
Iterator JavaDoc keys = locales.keySet().iterator();
2584        while (keys.hasNext()) {
2585            Double JavaDoc key = (Double JavaDoc) keys.next();
2586            ArrayList JavaDoc list = (ArrayList JavaDoc) locales.get(key);
2587            Iterator JavaDoc values = list.iterator();
2588            while (values.hasNext()) {
2589                Locale JavaDoc locale = (Locale JavaDoc) values.next();
2590                addLocale(locale);
2591            }
2592        }
2593
2594    }
2595
2596}
2597
Popular Tags