KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > coyote > tomcat4 > CoyoteRequest


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

16
17 package org.apache.coyote.tomcat4;
18
19
20 import java.io.BufferedReader JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.InputStreamReader JavaDoc;
24 import java.io.UnsupportedEncodingException JavaDoc;
25 import java.net.InetAddress JavaDoc;
26 import java.net.Socket JavaDoc;
27 import java.security.AccessController JavaDoc;
28 import java.security.Principal JavaDoc;
29 import java.security.PrivilegedAction JavaDoc;
30 import java.text.ParseException JavaDoc;
31 import java.text.SimpleDateFormat JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.Enumeration JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Locale JavaDoc;
38 import java.util.Map JavaDoc;
39 import java.util.TreeMap JavaDoc;
40
41 import javax.servlet.RequestDispatcher JavaDoc;
42 import javax.servlet.ServletContext JavaDoc;
43 import javax.servlet.ServletInputStream JavaDoc;
44 import javax.servlet.ServletRequest JavaDoc;
45 import javax.servlet.http.Cookie JavaDoc;
46 import javax.servlet.http.HttpServletRequest JavaDoc;
47 import javax.servlet.http.HttpServletResponse JavaDoc;
48 import javax.servlet.http.HttpSession JavaDoc;
49
50 import org.apache.catalina.Connector;
51 import org.apache.catalina.Context;
52 import org.apache.catalina.Globals;
53 import org.apache.catalina.HttpRequest;
54 import org.apache.catalina.Manager;
55 import org.apache.catalina.Realm;
56 import org.apache.catalina.Session;
57 import org.apache.catalina.Wrapper;
58 import org.apache.catalina.util.Enumerator;
59 import org.apache.catalina.util.ParameterMap;
60 import org.apache.catalina.util.RequestUtil;
61 import org.apache.catalina.util.StringManager;
62 import org.apache.catalina.util.StringParser;
63 import org.apache.coyote.ActionCode;
64 import org.apache.coyote.Request;
65 import org.apache.tomcat.util.buf.B2CConverter;
66 import org.apache.tomcat.util.http.Parameters;
67
68 /**
69  * Wrapper object for the Coyote request.
70  *
71  * @author Remy Maucherat
72  * @author Craig R. McClanahan
73  * @version $Revision: 1.38 $ $Date: 2004/08/29 15:33:45 $
74  */

75
76 public class CoyoteRequest
77     implements HttpRequest, HttpServletRequest JavaDoc {
78
79
80     // --------------------------------------- PrivilegedGetSession Inner Class
81

82
83     protected class PrivilegedGetSession
84         implements PrivilegedAction JavaDoc {
85
86         private boolean create;
87
88         PrivilegedGetSession(boolean create) {
89             this.create = create;
90         }
91
92         public Object JavaDoc run() {
93             return doGetSession(create);
94         }
95
96     }
97
98
99     // ------------------------------------------------------------- Properties
100

101
102     /**
103      * Coyote request.
104      */

105     protected Request JavaDoc coyoteRequest;
106
107     /**
108      * Set the Coyote request.
109      *
110      * @param coyoteRequest The Coyote request
111      */

112     public void setCoyoteRequest(Request JavaDoc coyoteRequest) {
113         this.coyoteRequest = coyoteRequest;
114         inputStream.setRequest(coyoteRequest);
115     }
116
117     /**
118      * Get the Coyote request.
119      */

120     public Request JavaDoc getCoyoteRequest() {
121         return (this.coyoteRequest);
122     }
123
124
125     // ----------------------------------------------------- Instance Variables
126

127
128     /**
129      * The string manager for this package.
130      */

131     protected static StringManager sm =
132         StringManager.getManager(Constants.Package);
133
134
135     /**
136      * The set of cookies associated with this Request.
137      */

138     protected Cookie JavaDoc[] cookies = null;
139
140
141     /**
142      * The set of SimpleDateFormat formats to use in getDateHeader().
143      */

144     protected SimpleDateFormat JavaDoc formats[] = {
145         new SimpleDateFormat JavaDoc("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
146         new SimpleDateFormat JavaDoc("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
147         new SimpleDateFormat JavaDoc("EEE MMMM d HH:mm:ss yyyy", Locale.US)
148     };
149
150
151     /**
152      * The default Locale if none are specified.
153      */

154     protected static Locale JavaDoc defaultLocale = Locale.getDefault();
155
156
157     /**
158      * The attributes associated with this Request, keyed by attribute name.
159      */

160     protected HashMap JavaDoc attributes = new HashMap JavaDoc();
161
162
163     /**
164      * The preferred Locales assocaited with this Request.
165      */

166     protected ArrayList JavaDoc locales = new ArrayList JavaDoc();
167
168
169     /**
170      * Internal notes associated with this request by Catalina components
171      * and event listeners.
172      */

173     private transient HashMap JavaDoc notes = new HashMap JavaDoc();
174
175
176     /**
177      * Authentication type.
178      */

179     protected String JavaDoc authType = null;
180
181
182     /**
183      * Reader.
184      * Note: At the moment, no attempt is being made at recycling the reader,
185      * but this could be implemented in the future, using a design like the one
186      * used for the output buffer.
187      */

188     protected BufferedReader JavaDoc reader = null;
189
190
191     /**
192      * ServletInputStream.
193      */

194     protected CoyoteInputStream inputStream = new CoyoteInputStream();
195
196
197     /**
198      * Using stream flag.
199      */

200     protected boolean usingInputStream = false;
201
202
203     /**
204      * Using writer flag.
205      */

206     protected boolean usingReader = false;
207
208
209     /**
210      * Context path.
211      */

212     protected String JavaDoc contextPath = "";
213
214
215     /**
216      * Path info.
217      */

218     protected String JavaDoc pathInfo = null;
219
220
221     /**
222      * Servlet path.
223      */

224     protected String JavaDoc servletPath = null;
225
226
227     /**
228      * User principal.
229      */

230     protected Principal JavaDoc userPrincipal = null;
231
232
233     /**
234      * Session parsed flag.
235      */

236     protected boolean sessionParsed = false;
237
238
239     /**
240      * Request parameters parsed flag.
241      */

242     protected boolean requestParametersParsed = false;
243
244
245     /**
246      * Secure flag.
247      */

248     protected boolean secure = false;
249
250
251     /**
252      * Post data buffer.
253      */

254     protected static int CACHED_POST_LEN = 8192;
255     protected byte[] postData = null;
256
257
258     /**
259      * Hash map used in the getParametersMap method.
260      */

261     protected ParameterMap parameterMap = new ParameterMap();
262
263
264     /**
265      * The currently active session for this request.
266      */

267     protected Session JavaDoc session = null;
268
269
270     /**
271      * Was the requested session ID received in a cookie?
272      */

273     protected boolean requestedSessionCookie = false;
274
275
276     /**
277      * The requested session ID (if any) for this request.
278      */

279     protected String JavaDoc requestedSessionId = null;
280
281
282     /**
283      * Was the requested session ID received in a URL?
284      */

285     protected boolean requestedSessionURL = false;
286
287
288     /**
289      * The socket through which this Request was received.
290      */

291     protected Socket JavaDoc socket = null;
292
293
294     /**
295      * Parse locales.
296      */

297     protected boolean localesParsed = false;
298
299
300     /**
301      * The string parser we will use for parsing request lines.
302      */

303     private StringParser parser = new StringParser();
304
305
306     /**
307      * Remote address.
308      */

309     protected String JavaDoc remoteAddr = null;
310
311
312     /**
313      * Remote host.
314      */

315     protected String JavaDoc remoteHost = null;
316
317
318     // --------------------------------------------------------- Public Methods
319

320
321     /**
322      * Release all object references, and initialize instance variables, in
323      * preparation for reuse of this object.
324      */

325     public void recycle() {
326
327         context = null;
328         wrapper = null;
329
330         authorization = null;
331         authType = null;
332         usingInputStream = false;
333         usingReader = false;
334         contextPath = "";
335         pathInfo = null;
336         servletPath = null;
337         reader = null;
338         inputStream.recycle();
339         userPrincipal = null;
340         sessionParsed = false;
341         authorization = null;
342         requestParametersParsed = false;
343         locales.clear();
344         localesParsed = false;
345         secure = false;
346         remoteAddr = null;
347         remoteHost = null;
348
349         attributes.clear();
350         notes.clear();
351         cookies = null;
352
353         session = null;
354         requestedSessionCookie = false;
355         requestedSessionId = null;
356         requestedSessionURL = false;
357
358         parameterMap.setLocked(false);
359         parameterMap.clear();
360
361         if (facade != null) {
362             facade.clear();
363             facade = null;
364         }
365
366     }
367
368
369     // -------------------------------------------------------- Request Methods
370

371
372     /**
373      * The authorization credentials sent with this Request.
374      */

375     protected String JavaDoc authorization = null;
376
377     /**
378      * Return the authorization credentials sent with this request.
379      */

380     public String JavaDoc getAuthorization() {
381
382         return (this.authorization);
383
384     }
385
386     /**
387      * Set the authorization credentials sent with this request.
388      *
389      * @param authorization The new authorization credentials
390      */

391     public void setAuthorization(String JavaDoc authorization) {
392         this.authorization = authorization;
393     }
394
395
396     /**
397      * Associated Catalina connector.
398      */

399     protected CoyoteConnector connector;
400
401     /**
402      * Return the Connector through which this Request was received.
403      */

404     public Connector getConnector() {
405         return (this.connector);
406     }
407
408     /**
409      * Set the Connector through which this Request was received.
410      *
411      * @param connector The new connector
412      */

413     public void setConnector(Connector connector) {
414         this.connector = (CoyoteConnector) connector;
415     }
416
417     /**
418      * The Context within which this Request is being processed.
419      */

420     protected Context JavaDoc context = null;
421
422     /**
423      * Return the Context within which this Request is being processed.
424      */

425     public Context JavaDoc getContext() {
426         return (this.context);
427     }
428
429     /**
430      * Set the Context within which this Request is being processed. This
431      * must be called as soon as the appropriate Context is identified, because
432      * it identifies the value to be returned by <code>getContextPath()</code>,
433      * and thus enables parsing of the request URI.
434      *
435      * @param context The newly associated Context
436      */

437     public void setContext(Context JavaDoc context) {
438         this.context = context;
439     }
440
441
442     /**
443      * Descriptive information about this Request implementation.
444      */

445     protected static final String JavaDoc info =
446         "org.apache.coyote.catalina.CoyoteRequest/1.0";
447
448     /**
449      * Return descriptive information about this Request implementation and
450      * the corresponding version number, in the format
451      * <code>&lt;description&gt;/&lt;version&gt;</code>.
452      */

453     public String JavaDoc getInfo() {
454         return (info);
455     }
456
457
458     /**
459      * The facade associated with this request.
460      */

461     protected CoyoteRequestFacade facade = null;
462
463     /**
464      * Return the <code>ServletRequest</code> for which this object
465      * is the facade. This method must be implemented by a subclass.
466      */

467     public ServletRequest JavaDoc getRequest() {
468         if (facade == null) {
469             facade = new CoyoteRequestFacade(this);
470         }
471         return (facade);
472     }
473
474
475     /**
476      * The response with which this request is associated.
477      */

478     protected org.apache.catalina.Response response = null;
479
480     /**
481      * Return the Response with which this Request is associated.
482      */

483     public org.apache.catalina.Response getResponse() {
484         return (this.response);
485     }
486
487     /**
488      * Set the Response with which this Request is associated.
489      *
490      * @param response The new associated response
491      */

492     public void setResponse(org.apache.catalina.Response response) {
493         this.response = response;
494     }
495
496
497     /**
498      * Return the Socket (if any) through which this Request was received.
499      * This should <strong>only</strong> be used to access underlying state
500      * information about this Socket, such as the SSLSession associated with
501      * an SSLSocket.
502      */

503     public Socket JavaDoc getSocket() {
504         return (socket);
505     }
506
507     /**
508      * Set the Socket (if any) through which this Request was received.
509      *
510      * @param socket The socket through which this request was received
511      */

512     public void setSocket(Socket JavaDoc socket) {
513         this.socket = socket;
514         remoteHost = null;
515         remoteAddr = null;
516     }
517
518
519     /**
520      * Return the input stream associated with this Request.
521      */

522     public InputStream JavaDoc getStream() {
523         return inputStream;
524     }
525
526     /**
527      * Set the input stream associated with this Request.
528      *
529      * @param stream The new input stream
530      */

531     public void setStream(InputStream JavaDoc stream) {
532         // Ignore
533
}
534
535
536     /**
537      * URI byte to char converter (not recycled).
538      */

539     protected B2CConverter URIConverter = null;
540
541     /**
542      * Return the URI converter.
543      */

544     protected B2CConverter getURIConverter() {
545         return URIConverter;
546     }
547
548     /**
549      * Set the URI converter.
550      *
551      * @param URIConverter the new URI connverter
552      */

553     protected void setURIConverter(B2CConverter URIConverter) {
554         this.URIConverter = URIConverter;
555     }
556
557
558     /**
559      * The Wrapper within which this Request is being processed.
560      */

561     protected Wrapper wrapper = null;
562
563     /**
564      * Return the Wrapper within which this Request is being processed.
565      */

566     public Wrapper getWrapper() {
567         return (this.wrapper);
568     }
569
570     /**
571      * Set the Wrapper within which this Request is being processed. This
572      * must be called as soon as the appropriate Wrapper is identified, and
573      * before the Request is ultimately passed to an application servlet.
574      *
575      * @param wrapper The newly associated Wrapper
576      */

577     public void setWrapper(Wrapper wrapper) {
578         this.wrapper = wrapper;
579     }
580
581
582     // ------------------------------------------------- Request Public Methods
583

584
585     /**
586      * Create and return a ServletInputStream to read the content
587      * associated with this Request.
588      *
589      * @exception IOException if an input/output error occurs
590      */

591     public ServletInputStream JavaDoc createInputStream()
592         throws IOException JavaDoc {
593         return inputStream;
594     }
595
596
597     /**
598      * Perform whatever actions are required to flush and close the input
599      * stream or reader, in a single operation.
600      *
601      * @exception IOException if an input/output error occurs
602      */

603     public void finishRequest() throws IOException JavaDoc {
604         // The reader and input stream don't need to be closed
605
}
606
607
608     /**
609      * Return the object bound with the specified name to the internal notes
610      * for this request, or <code>null</code> if no such binding exists.
611      *
612      * @param name Name of the note to be returned
613      */

614     public Object JavaDoc getNote(String JavaDoc name) {
615         return (notes.get(name));
616     }
617
618
619     /**
620      * Return an Iterator containing the String names of all notes bindings
621      * that exist for this request.
622      */

623     public Iterator JavaDoc getNoteNames() {
624         return (notes.keySet().iterator());
625     }
626
627
628     /**
629      * Remove any object bound to the specified name in the internal notes
630      * for this request.
631      *
632      * @param name Name of the note to be removed
633      */

634     public void removeNote(String JavaDoc name) {
635         notes.remove(name);
636     }
637
638
639     /**
640      * Bind an object to a specified name in the internal notes associated
641      * with this request, replacing any existing binding for this name.
642      *
643      * @param name Name to which the object should be bound
644      * @param value Object to be bound to the specified name
645      */

646     public void setNote(String JavaDoc name, Object JavaDoc value) {
647         notes.put(name, value);
648     }
649
650
651     /**
652      * Set the content length associated with this Request.
653      *
654      * @param length The new content length
655      */

656     public void setContentLength(int length) {
657         // Not used
658
}
659
660
661     /**
662      * Set the content type (and optionally the character encoding)
663      * associated with this Request. For example,
664      * <code>text/html; charset=ISO-8859-4</code>.
665      *
666      * @param type The new content type
667      */

668     public void setContentType(String JavaDoc type) {
669         // Not used
670
}
671
672
673     /**
674      * Set the protocol name and version associated with this Request.
675      *
676      * @param protocol Protocol name and version
677      */

678     public void setProtocol(String JavaDoc protocol) {
679         // Not used
680
}
681
682
683     /**
684      * Set the IP address of the remote client associated with this Request.
685      *
686      * @param remoteAddr The remote IP address
687      */

688     public void setRemoteAddr(String JavaDoc remoteAddr) {
689         // Not used
690
}
691
692
693     /**
694      * Set the fully qualified name of the remote client associated with this
695      * Request.
696      *
697      * @param remoteHost The remote host name
698      */

699     public void setRemoteHost(String JavaDoc remoteHost) {
700         // Not used
701
}
702
703
704     /**
705      * Set the name of the scheme associated with this request. Typical values
706      * are <code>http</code>, <code>https</code>, and <code>ftp</code>.
707      *
708      * @param scheme The scheme
709      */

710     public void setScheme(String JavaDoc scheme) {
711         // Not used
712
}
713
714
715     /**
716      * Set the value to be returned by <code>isSecure()</code>
717      * for this Request.
718      *
719      * @param secure The new isSecure value
720      */

721     public void setSecure(boolean secure) {
722         this.secure = secure;
723     }
724
725
726     /**
727      * Set the name of the server (virtual host) to process this request.
728      *
729      * @param name The server name
730      */

731     public void setServerName(String JavaDoc name) {
732         coyoteRequest.serverName().setString(name);
733     }
734
735
736     /**
737      * Set the port number of the server to process this request.
738      *
739      * @param port The server port
740      */

741     public void setServerPort(int port) {
742         coyoteRequest.setServerPort(port);
743     }
744
745
746     // ------------------------------------------------- ServletRequest Methods
747

748
749     /**
750      * Return the specified request attribute if it exists; otherwise, return
751      * <code>null</code>.
752      *
753      * @param name Name of the request attribute to return
754      */

755     public Object JavaDoc getAttribute(String JavaDoc name) {
756         Object JavaDoc attr=attributes.get(name);
757
758         if(attr!=null)
759             return(attr);
760
761         attr = coyoteRequest.getAttribute(name);
762         if(attr != null) {
763             attributes.put(name, attr);
764             return attr;
765         }
766         // XXX Should move to Globals
767
if(Constants.SSL_CERTIFICATE_ATTR.equals(name)) {
768             coyoteRequest.action(ActionCode.ACTION_REQ_SSL_CERTIFICATE, null);
769             attr = getAttribute(Globals.CERTIFICATES_ATTR);
770             if(attr != null)
771                 attributes.put(name, attr);
772         }
773         return attr;
774     }
775
776     /**
777      * Return the names of all request attributes for this Request, or an
778      * empty <code>Enumeration</code> if there are none.
779      */

780     public Enumeration JavaDoc getAttributeNames() {
781         return (new Enumerator(attributes.keySet()));
782     }
783
784
785     /**
786      * Return the character encoding for this Request.
787      */

788     public String JavaDoc getCharacterEncoding() {
789       return (coyoteRequest.getCharacterEncoding());
790     }
791
792
793     /**
794      * Return the content length for this Request.
795      */

796     public int getContentLength() {
797         return (coyoteRequest.getContentLength());
798     }
799
800
801     /**
802      * Return the content type for this Request.
803      */

804     public String JavaDoc getContentType() {
805         return (coyoteRequest.getContentType());
806     }
807
808
809     /**
810      * Return the servlet input stream for this Request. The default
811      * implementation returns a servlet input stream created by
812      * <code>createInputStream()</code>.
813      *
814      * @exception IllegalStateException if <code>getReader()</code> has
815      * already been called for this request
816      * @exception IOException if an input/output error occurs
817      */

818     public ServletInputStream JavaDoc getInputStream() throws IOException JavaDoc {
819
820         if (usingReader)
821             throw new IllegalStateException JavaDoc
822                 (sm.getString("coyoteRequest.getInputStream.ise"));
823
824         usingInputStream = true;
825         return inputStream;
826
827     }
828
829
830     /**
831      * Return the preferred Locale that the client will accept content in,
832      * based on the value for the first <code>Accept-Language</code> header
833      * that was encountered. If the request did not specify a preferred
834      * language, the server's default Locale is returned.
835      */

836     public Locale JavaDoc getLocale() {
837
838         if (!localesParsed)
839             parseLocales();
840
841         if (locales.size() > 0) {
842             return ((Locale JavaDoc) locales.get(0));
843         } else {
844             return (defaultLocale);
845         }
846
847     }
848
849
850     /**
851      * Return the set of preferred Locales that the client will accept
852      * content in, based on the values for any <code>Accept-Language</code>
853      * headers that were encountered. If the request did not specify a
854      * preferred language, the server's default Locale is returned.
855      */

856     public Enumeration JavaDoc getLocales() {
857
858         if (!localesParsed)
859             parseLocales();
860
861         if (locales.size() > 0)
862             return (new Enumerator(locales));
863         ArrayList JavaDoc results = new ArrayList JavaDoc();
864         results.add(defaultLocale);
865         return (new Enumerator(results));
866
867     }
868
869
870     /**
871      * Return the value of the specified request parameter, if any; otherwise,
872      * return <code>null</code>. If there is more than one value defined,
873      * return only the first one.
874      *
875      * @param name Name of the desired request parameter
876      */

877     public String JavaDoc getParameter(String JavaDoc name) {
878
879         if (!requestParametersParsed)
880             parseRequestParameters();
881
882         return coyoteRequest.getParameters().getParameter(name);
883
884     }
885
886
887
888     /**
889      * Returns a <code>Map</code> of the parameters of this request.
890      * Request parameters are extra information sent with the request.
891      * For HTTP servlets, parameters are contained in the query string
892      * or posted form data.
893      *
894      * @return A <code>Map</code> containing parameter names as keys
895      * and parameter values as map values.
896      */

897     public Map JavaDoc getParameterMap() {
898
899         if (parameterMap.isLocked())
900             return parameterMap;
901
902         Enumeration JavaDoc paramNames = getParameterNames();
903         while (paramNames.hasMoreElements()) {
904             String JavaDoc name = paramNames.nextElement().toString();
905             String JavaDoc[] values = getParameterValues(name);
906             parameterMap.put(name, values);
907         }
908
909         parameterMap.setLocked(true);
910
911         return parameterMap;
912
913     }
914
915
916     /**
917      * Return the names of all defined request parameters for this request.
918      */

919     public Enumeration JavaDoc getParameterNames() {
920
921         if (!requestParametersParsed)
922             parseRequestParameters();
923
924         return coyoteRequest.getParameters().getParameterNames();
925
926     }
927
928
929     /**
930      * Return the defined values for the specified request parameter, if any;
931      * otherwise, return <code>null</code>.
932      *
933      * @param name Name of the desired request parameter
934      */

935     public String JavaDoc[] getParameterValues(String JavaDoc name) {
936
937         if (!requestParametersParsed)
938             parseRequestParameters();
939
940         return coyoteRequest.getParameters().getParameterValues(name);
941
942     }
943
944
945     /**
946      * Return the protocol and version used to make this Request.
947      */

948     public String JavaDoc getProtocol() {
949         return coyoteRequest.protocol().toString();
950     }
951
952
953     /**
954      * Read the Reader wrapping the input stream for this Request. The
955      * default implementation wraps a <code>BufferedReader</code> around the
956      * servlet input stream returned by <code>createInputStream()</code>.
957      *
958      * @exception IllegalStateException if <code>getInputStream()</code>
959      * has already been called for this request
960      * @exception IOException if an input/output error occurs
961      */

962     public BufferedReader JavaDoc getReader() throws IOException JavaDoc {
963
964         if (usingInputStream)
965             throw new IllegalStateException JavaDoc
966                 (sm.getString("coyoteRequest.getReader.ise"));
967
968         usingReader = true;
969         if (reader == null) {
970             String JavaDoc encoding = getCharacterEncoding();
971             if (encoding == null) {
972                 encoding =
973                     org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
974             }
975             InputStreamReader JavaDoc r = new InputStreamReader JavaDoc(inputStream, encoding);
976             reader = new BufferedReader JavaDoc(r);
977         }
978         return (reader);
979
980     }
981
982
983     /**
984      * Return the real path of the specified virtual path.
985      *
986      * @param path Path to be translated
987      *
988      * @deprecated As of version 2.1 of the Java Servlet API, use
989      * <code>ServletContext.getRealPath()</code>.
990      */

991     public String JavaDoc getRealPath(String JavaDoc path) {
992
993         if (context == null)
994             return (null);
995         ServletContext JavaDoc servletContext = context.getServletContext();
996         if (servletContext == null)
997             return (null);
998         else {
999             try {
1000                return (servletContext.getRealPath(path));
1001            } catch (IllegalArgumentException JavaDoc e) {
1002                return (null);
1003            }
1004        }
1005
1006    }
1007
1008
1009    /**
1010     * Return the remote IP address making this Request.
1011     */

1012    public String JavaDoc getRemoteAddr() {
1013        if (remoteAddr == null) {
1014            if (socket != null) {
1015                InetAddress JavaDoc inet = socket.getInetAddress();
1016                remoteAddr = inet.getHostAddress();
1017            } else {
1018                coyoteRequest.action
1019                    (ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, coyoteRequest);
1020                remoteAddr = coyoteRequest.remoteAddr().toString();
1021            }
1022        }
1023        return remoteAddr;
1024    }
1025
1026
1027    /**
1028     * Return the remote host name making this Request.
1029     */

1030    public String JavaDoc getRemoteHost() {
1031        if (remoteHost == null) {
1032            if (!connector.getEnableLookups()) {
1033                remoteHost = getRemoteAddr();
1034            } else if (socket != null) {
1035                InetAddress JavaDoc inet = socket.getInetAddress();
1036                remoteHost = inet.getHostName();
1037            } else {
1038                coyoteRequest.action
1039                    (ActionCode.ACTION_REQ_HOST_ATTRIBUTE, coyoteRequest);
1040                remoteHost = coyoteRequest.remoteHost().toString();
1041            }
1042        }
1043        return remoteHost;
1044    }
1045
1046
1047    /**
1048     * Return a RequestDispatcher that wraps the resource at the specified
1049     * path, which may be interpreted as relative to the current request path.
1050     *
1051     * @param path Path of the resource to be wrapped
1052     */

1053    public RequestDispatcher JavaDoc getRequestDispatcher(String JavaDoc path) {
1054
1055        if (context == null)
1056            return (null);
1057
1058        // If the path is already context-relative, just pass it through
1059
if (path == null)
1060            return (null);
1061        else if (path.startsWith("/"))
1062            return (context.getServletContext().getRequestDispatcher(path));
1063
1064        // Convert a request-relative path to a context-relative one
1065
String JavaDoc servletPath = (String JavaDoc) getAttribute(Globals.SERVLET_PATH_ATTR);
1066        if (servletPath == null)
1067            servletPath = getServletPath();
1068
1069        // Add the path info, if there is any
1070
String JavaDoc pathInfo = getPathInfo();
1071        String JavaDoc requestPath = null;
1072
1073        if (pathInfo == null) {
1074            requestPath = servletPath;
1075        } else {
1076            requestPath = servletPath + pathInfo;
1077        }
1078
1079        int pos = requestPath.lastIndexOf('/');
1080        String JavaDoc relative = null;
1081        if (pos >= 0) {
1082            relative = RequestUtil.normalize
1083                (requestPath.substring(0, pos + 1) + path);
1084        } else {
1085            relative = RequestUtil.normalize(requestPath + path);
1086        }
1087
1088        return (context.getServletContext().getRequestDispatcher(relative));
1089
1090    }
1091
1092
1093    /**
1094     * Return the scheme used to make this Request.
1095     */

1096    public String JavaDoc getScheme() {
1097        return (coyoteRequest.scheme().toString());
1098    }
1099
1100
1101    /**
1102     * Return the server name responding to this Request.
1103     */

1104    public String JavaDoc getServerName() {
1105        return (coyoteRequest.serverName().toString());
1106    }
1107
1108
1109    /**
1110     * Return the server port responding to this Request.
1111     */

1112    public int getServerPort() {
1113        return (coyoteRequest.getServerPort());
1114    }
1115
1116
1117    /**
1118     * Was this request received on a secure connection?
1119     */

1120    public boolean isSecure() {
1121        return (secure);
1122    }
1123
1124
1125    /**
1126     * Remove the specified request attribute if it exists.
1127     *
1128     * @param name Name of the request attribute to remove
1129     */

1130    public void removeAttribute(String JavaDoc name) {
1131        attributes.remove(name);
1132    }
1133
1134
1135    /**
1136     * Set the specified request attribute to the specified value.
1137     *
1138     * @param name Name of the request attribute to set
1139     * @param value The associated value
1140     */

1141    public void setAttribute(String JavaDoc name, Object JavaDoc value) {
1142    
1143        // Name cannot be null
1144
if (name == null)
1145            throw new IllegalArgumentException JavaDoc
1146                (sm.getString("coyoteRequest.setAttribute.namenull"));
1147
1148        // Null value is the same as removeAttribute()
1149
if (value == null) {
1150            removeAttribute(name);
1151            return;
1152        }
1153
1154        attributes.put(name, value);
1155
1156    }
1157
1158
1159    /**
1160     * Overrides the name of the character encoding used in the body of
1161     * this request. This method must be called prior to reading request
1162     * parameters or reading input using <code>getReader()</code>.
1163     *
1164     * @param enc The character encoding to be used
1165     *
1166     * @exception UnsupportedEncodingException if the specified encoding
1167     * is not supported
1168     *
1169     * @since Servlet 2.3
1170     */

1171    public void setCharacterEncoding(String JavaDoc enc)
1172        throws UnsupportedEncodingException JavaDoc {
1173
1174        // Ensure that the specified encoding is valid
1175
byte buffer[] = new byte[1];
1176        buffer[0] = (byte) 'a';
1177        String JavaDoc dummy = new String JavaDoc(buffer, enc);
1178
1179        // Save the validated encoding
1180
coyoteRequest.setCharacterEncoding(enc);
1181
1182    }
1183
1184
1185    // ---------------------------------------------------- HttpRequest Methods
1186

1187
1188    /**
1189     * Add a Cookie to the set of Cookies associated with this Request.
1190     *
1191     * @param cookie The new cookie
1192     */

1193    public void addCookie(Cookie JavaDoc cookie) {
1194
1195        // For compatibility only
1196

1197        int size = 0;
1198        if (cookies != null) {
1199            size = cookies.length;
1200        }
1201
1202        Cookie JavaDoc[] newCookies = new Cookie JavaDoc[size + 1];
1203        for (int i = 0; i < size; i++) {
1204            newCookies[i] = cookies[i];
1205        }
1206        newCookies[size] = cookie;
1207
1208        cookies = newCookies;
1209
1210    }
1211
1212
1213    /**
1214     * Add a Header to the set of Headers associated with this Request.
1215     *
1216     * @param name The new header name
1217     * @param value The new header value
1218     */

1219    public void addHeader(String JavaDoc name, String JavaDoc value) {
1220        // Not used
1221
}
1222
1223
1224    /**
1225     * Add a Locale to the set of preferred Locales for this Request. The
1226     * first added Locale will be the first one returned by getLocales().
1227     *
1228     * @param locale The new preferred Locale
1229     */

1230    public void addLocale(Locale JavaDoc locale) {
1231        locales.add(locale);
1232    }
1233
1234
1235    /**
1236     * Add a parameter name and corresponding set of values to this Request.
1237     * (This is used when restoring the original request on a form based
1238     * login).
1239     *
1240     * @param name Name of this request parameter
1241     * @param values Corresponding values for this request parameter
1242     */

1243    public void addParameter(String JavaDoc name, String JavaDoc values[]) {
1244        coyoteRequest.getParameters().addParameterValues(name, values);
1245    }
1246
1247
1248    /**
1249     * Clear the collection of Cookies associated with this Request.
1250     */

1251    public void clearCookies() {
1252        cookies = null;
1253    }
1254
1255
1256    /**
1257     * Clear the collection of Headers associated with this Request.
1258     */

1259    public void clearHeaders() {
1260        // Not used
1261
}
1262
1263
1264    /**
1265     * Clear the collection of Locales associated with this Request.
1266     */

1267    public void clearLocales() {
1268        locales.clear();
1269    }
1270
1271
1272    /**
1273     * Clear the collection of parameters associated with this Request.
1274     */

1275    public void clearParameters() {
1276        // Not used
1277
}
1278
1279
1280    /**
1281     * Set the authentication type used for this request, if any; otherwise
1282     * set the type to <code>null</code>. Typical values are "BASIC",
1283     * "DIGEST", or "SSL".
1284     *
1285     * @param type The authentication type used
1286     */

1287    public void setAuthType(String JavaDoc type) {
1288        this.authType = type;
1289    }
1290
1291
1292    /**
1293     * Set the context path for this Request. This will normally be called
1294     * when the associated Context is mapping the Request to a particular
1295     * Wrapper.
1296     *
1297     * @param path The context path
1298     */

1299    public void setContextPath(String JavaDoc path) {
1300
1301        if (path == null) {
1302            this.contextPath = "";
1303        } else {
1304            this.contextPath = path;
1305        }
1306
1307    }
1308
1309
1310    /**
1311     * Set the HTTP request method used for this Request.
1312     *
1313     * @param method The request method
1314     */

1315    public void setMethod(String JavaDoc method) {
1316        // Not used
1317
}
1318
1319
1320    /**
1321     * Set the query string for this Request. This will normally be called
1322     * by the HTTP Connector, when it parses the request headers.
1323     *
1324     * @param query The query string
1325     */

1326    public void setQueryString(String JavaDoc query) {
1327        // Not used
1328
}
1329
1330
1331    /**
1332     * Set the path information for this Request. This will normally be called
1333     * when the associated Context is mapping the Request to a particular
1334     * Wrapper.
1335     *
1336     * @param path The path information
1337     */

1338    public void setPathInfo(String JavaDoc path) {
1339        this.pathInfo = path;
1340    }
1341
1342
1343    /**
1344     * Set a flag indicating whether or not the requested session ID for this
1345     * request came in through a cookie. This is normally called by the
1346     * HTTP Connector, when it parses the request headers.
1347     *
1348     * @param flag The new flag
1349     */

1350    public void setRequestedSessionCookie(boolean flag) {
1351
1352        this.requestedSessionCookie = flag;
1353
1354    }
1355
1356
1357    /**
1358     * Set the requested session ID for this request. This is normally called
1359     * by the HTTP Connector, when it parses the request headers.
1360     *
1361     * @param id The new session id
1362     */

1363    public void setRequestedSessionId(String JavaDoc id) {
1364
1365        this.requestedSessionId = id;
1366
1367    }
1368
1369
1370    /**
1371     * Set a flag indicating whether or not the requested session ID for this
1372     * request came in through a URL. This is normally called by the
1373     * HTTP Connector, when it parses the request headers.
1374     *
1375     * @param flag The new flag
1376     */

1377    public void setRequestedSessionURL(boolean flag) {
1378
1379        this.requestedSessionURL = flag;
1380
1381    }
1382
1383
1384    /**
1385     * Set the unparsed request URI for this Request. This will normally be
1386     * called by the HTTP Connector, when it parses the request headers.
1387     *
1388     * @param uri The request URI
1389     */

1390    public void setRequestURI(String JavaDoc uri) {
1391        // Not used
1392
}
1393
1394
1395    /**
1396     * Set the decoded request URI.
1397     *
1398     * @param uri The decoded request URI
1399     */

1400    public void setDecodedRequestURI(String JavaDoc uri) {
1401        // Not used
1402
}
1403
1404
1405    /**
1406     * Get the decoded request URI.
1407     *
1408     * @return the URL decoded request URI
1409     */

1410    public String JavaDoc getDecodedRequestURI() {
1411        return (coyoteRequest.decodedURI().toString());
1412    }
1413
1414
1415    /**
1416     * Set the servlet path for this Request. This will normally be called
1417     * when the associated Context is mapping the Request to a particular
1418     * Wrapper.
1419     *
1420     * @param path The servlet path
1421     */

1422    public void setServletPath(String JavaDoc path) {
1423        this.servletPath = path;
1424    }
1425
1426
1427    /**
1428     * Set the Principal who has been authenticated for this Request. This
1429     * value is also used to calculate the value to be returned by the
1430     * <code>getRemoteUser()</code> method.
1431     *
1432     * @param principal The user Principal
1433     */

1434    public void setUserPrincipal(Principal JavaDoc principal) {
1435        this.userPrincipal = principal;
1436    }
1437
1438
1439    // --------------------------------------------- HttpServletRequest Methods
1440

1441
1442    /**
1443     * Return the authentication type used for this Request.
1444     */

1445    public String JavaDoc getAuthType() {
1446        return (authType);
1447    }
1448
1449
1450    /**
1451     * Return the portion of the request URI used to select the Context
1452     * of the Request.
1453     */

1454    public String JavaDoc getContextPath() {
1455        return (contextPath);
1456    }
1457
1458
1459    /**
1460     * Return the set of Cookies received with this Request.
1461     */

1462    public Cookie JavaDoc[] getCookies() {
1463
1464        return cookies;
1465
1466    }
1467
1468
1469    /**
1470     * Set the set of cookies recieved with this Request.
1471     */

1472    public void setCookies(Cookie JavaDoc[] cookies) {
1473
1474        this.cookies = cookies;
1475
1476    }
1477
1478
1479    /**
1480     * Return the value of the specified date header, if any; otherwise
1481     * return -1.
1482     *
1483     * @param name Name of the requested date header
1484     *
1485     * @exception IllegalArgumentException if the specified header value
1486     * cannot be converted to a date
1487     */

1488    public long getDateHeader(String JavaDoc name) {
1489
1490        String JavaDoc value = getHeader(name);
1491        if (value == null)
1492            return (-1L);
1493
1494        // Work around a bug in SimpleDateFormat in pre-JDK1.2b4
1495
// (Bug Parade bug #4106807)
1496
value += " ";
1497
1498        // Attempt to convert the date header in a variety of formats
1499
for (int i = 0; i < formats.length; i++) {
1500            try {
1501                Date JavaDoc date = formats[i].parse(value);
1502                return (date.getTime());
1503            } catch (ParseException JavaDoc e) {
1504                ;
1505            }
1506        }
1507        throw new IllegalArgumentException JavaDoc(value);
1508
1509    }
1510
1511
1512    /**
1513     * Return the first value of the specified header, if any; otherwise,
1514     * return <code>null</code>
1515     *
1516     * @param name Name of the requested header
1517     */

1518    public String JavaDoc getHeader(String JavaDoc name) {
1519        return coyoteRequest.getHeader(name);
1520    }
1521
1522
1523    /**
1524     * Return all of the values of the specified header, if any; otherwise,
1525     * return an empty enumeration.
1526     *
1527     * @param name Name of the requested header
1528     */

1529    public Enumeration JavaDoc getHeaders(String JavaDoc name) {
1530        return coyoteRequest.getMimeHeaders().values(name);
1531    }
1532
1533
1534    /**
1535     * Return the names of all headers received with this request.
1536     */

1537    public Enumeration JavaDoc getHeaderNames() {
1538        return coyoteRequest.getMimeHeaders().names();
1539    }
1540
1541
1542    /**
1543     * Return the value of the specified header as an integer, or -1 if there
1544     * is no such header for this request.
1545     *
1546     * @param name Name of the requested header
1547     *
1548     * @exception IllegalArgumentException if the specified header value
1549     * cannot be converted to an integer
1550     */

1551    public int getIntHeader(String JavaDoc name) {
1552
1553        String JavaDoc value = getHeader(name);
1554        if (value == null) {
1555            return (-1);
1556        } else {
1557            return (Integer.parseInt(value));
1558        }
1559
1560    }
1561
1562
1563    /**
1564     * Return the HTTP request method used in this Request.
1565     */

1566    public String JavaDoc getMethod() {
1567        return coyoteRequest.method().toString();
1568    }
1569
1570
1571    /**
1572     * Return the path information associated with this Request.
1573     */

1574    public String JavaDoc getPathInfo() {
1575        return (pathInfo);
1576    }
1577
1578
1579    /**
1580     * Return the extra path information for this request, translated
1581     * to a real path.
1582     */

1583    public String JavaDoc getPathTranslated() {
1584
1585        if (context == null)
1586            return (null);
1587
1588        if (pathInfo == null) {
1589            return (null);
1590        } else {
1591            return (context.getServletContext().getRealPath(pathInfo));
1592        }
1593
1594    }
1595
1596
1597    /**
1598     * Return the query string associated with this request.
1599     */

1600    public String JavaDoc getQueryString() {
1601        String JavaDoc queryString = coyoteRequest.queryString().toString();
1602        if (queryString.equals("")) {
1603            return (null);
1604        } else {
1605            return queryString;
1606        }
1607    }
1608
1609
1610    /**
1611     * Return the name of the remote user that has been authenticated
1612     * for this Request.
1613     */

1614    public String JavaDoc getRemoteUser() {
1615
1616        if (userPrincipal != null) {
1617            return (userPrincipal.getName());
1618        } else {
1619            return (null);
1620        }
1621
1622    }
1623
1624
1625    /**
1626     * Return the session identifier included in this request, if any.
1627     */

1628    public String JavaDoc getRequestedSessionId() {
1629        return (requestedSessionId);
1630    }
1631
1632
1633    /**
1634     * Return the request URI for this request.
1635     */

1636    public String JavaDoc getRequestURI() {
1637        return coyoteRequest.requestURI().toString();
1638    }
1639
1640
1641    /**
1642     * Reconstructs the URL the client used to make the request.
1643     * The returned URL contains a protocol, server name, port
1644     * number, and server path, but it does not include query
1645     * string parameters.
1646     * <p>
1647     * Because this method returns a <code>StringBuffer</code>,
1648     * not a <code>String</code>, you can modify the URL easily,
1649     * for example, to append query parameters.
1650     * <p>
1651     * This method is useful for creating redirect messages and
1652     * for reporting errors.
1653     *
1654     * @return A <code>StringBuffer</code> object containing the
1655     * reconstructed URL
1656     */

1657    public StringBuffer JavaDoc getRequestURL() {
1658
1659        StringBuffer JavaDoc url = new StringBuffer JavaDoc();
1660        String JavaDoc scheme = getScheme();
1661        int port = getServerPort();
1662        if (port < 0)
1663            port = 80; // Work around java.net.URL bug
1664

1665        url.append(scheme);
1666        url.append("://");
1667        url.append(getServerName());
1668        if ((scheme.equals("http") && (port != 80))
1669            || (scheme.equals("https") && (port != 443))) {
1670            url.append(':');
1671            url.append(port);
1672        }
1673        url.append(getRequestURI());
1674
1675        return (url);
1676
1677    }
1678
1679
1680    /**
1681     * Return the portion of the request URI used to select the servlet
1682     * that will process this request.
1683     */

1684    public String JavaDoc getServletPath() {
1685        return (servletPath);
1686    }
1687
1688
1689    /**
1690     * Return the session associated with this Request, creating one
1691     * if necessary.
1692     */

1693    public HttpSession JavaDoc getSession() {
1694        return (getSession(true));
1695    }
1696
1697
1698    /**
1699     * Return the session associated with this Request, creating one
1700     * if necessary and requested.
1701     *
1702     * @param create Create a new session if one does not exist
1703     */

1704    public HttpSession JavaDoc getSession(boolean create) {
1705
1706        if (System.getSecurityManager() != null) {
1707            PrivilegedGetSession dp = new PrivilegedGetSession(create);
1708            return (HttpSession JavaDoc) AccessController.doPrivileged(dp);
1709        }
1710        return doGetSession(create);
1711
1712    }
1713
1714
1715    /**
1716     * Return <code>true</code> if the session identifier included in this
1717     * request came from a cookie.
1718     */

1719    public boolean isRequestedSessionIdFromCookie() {
1720
1721        if (requestedSessionId != null)
1722            return (requestedSessionCookie);
1723        else
1724            return (false);
1725
1726    }
1727
1728
1729    /**
1730     * Return <code>true</code> if the session identifier included in this
1731     * request came from the request URI.
1732     */

1733    public boolean isRequestedSessionIdFromURL() {
1734
1735        if (requestedSessionId != null)
1736            return (requestedSessionURL);
1737        else
1738            return (false);
1739
1740    }
1741
1742
1743    /**
1744     * Return <code>true</code> if the session identifier included in this
1745     * request came from the request URI.
1746     *
1747     * @deprecated As of Version 2.1 of the Java Servlet API, use
1748     * <code>isRequestedSessionIdFromURL()</code> instead.
1749     */

1750    public boolean isRequestedSessionIdFromUrl() {
1751        return (isRequestedSessionIdFromURL());
1752    }
1753
1754
1755    /**
1756     * Return <code>true</code> if the session identifier included in this
1757     * request identifies a valid session.
1758     */

1759    public boolean isRequestedSessionIdValid() {
1760
1761        if (requestedSessionId == null)
1762            return (false);
1763        if (context == null)
1764            return (false);
1765        Manager manager = context.getManager();
1766        if (manager == null)
1767            return (false);
1768        Session JavaDoc session = null;
1769        try {
1770            session = manager.findSession(requestedSessionId);
1771        } catch (IOException JavaDoc e) {
1772            session = null;
1773        }
1774        if ((session != null) && session.isValid())
1775            return (true);
1776        else
1777            return (false);
1778
1779    }
1780
1781
1782    /**
1783     * Return <code>true</code> if the authenticated user principal
1784     * possesses the specified role name.
1785     *
1786     * @param role Role name to be validated
1787     */

1788    public boolean isUserInRole(String JavaDoc role) {
1789
1790        // Have we got an authenticated principal at all?
1791
if (userPrincipal == null)
1792            return (false);
1793
1794        // Identify the Realm we will use for checking role assignmenets
1795
if (context == null)
1796            return (false);
1797        Realm realm = context.getRealm();
1798        if (realm == null)
1799            return (false);
1800
1801        // Check for a role alias defined in a <security-role-ref> element
1802
if (wrapper != null) {
1803            String JavaDoc realRole = wrapper.findSecurityReference(role);
1804            if ((realRole != null) &&
1805                realm.hasRole(userPrincipal, realRole))
1806                return (true);
1807        }
1808
1809        // Check for a role defined directly as a <security-role>
1810
return (realm.hasRole(userPrincipal, role));
1811
1812    }
1813
1814
1815    /**
1816     * Return the principal that has been authenticated for this Request.
1817     */

1818    public Principal JavaDoc getUserPrincipal() {
1819        return (userPrincipal);
1820    }
1821
1822
1823    // ------------------------------------------------------ Protected Methods
1824

1825
1826    protected HttpSession JavaDoc doGetSession(boolean create) {
1827
1828        // There cannot be a session if no context has been assigned yet
1829
if (context == null)
1830            return (null);
1831
1832        // Return the current session if it exists and is valid
1833
if ((session != null) && !session.isValid())
1834            session = null;
1835        if (session != null)
1836            return (session.getSession());
1837
1838        // Return the requested session if it exists and is valid
1839
Manager manager = null;
1840        if (context != null)
1841            manager = context.getManager();
1842        if (manager == null)
1843            return (null); // Sessions are not supported
1844
if (requestedSessionId != null) {
1845            try {
1846                session = manager.findSession(requestedSessionId);
1847            } catch (IOException JavaDoc e) {
1848                session = null;
1849            }
1850            if ((session != null) && !session.isValid())
1851                session = null;
1852            if (session != null) {
1853                return (session.getSession());
1854            }
1855        }
1856
1857        // Create a new session if requested and the response is not committed
1858
if (!create)
1859            return (null);
1860        if ((context != null) && (response != null) &&
1861            context.getCookies() &&
1862            response.getResponse().isCommitted()) {
1863            throw new IllegalStateException JavaDoc
1864              (sm.getString("coyoteRequest.sessionCreateCommitted"));
1865        }
1866
1867        session = manager.createSession();
1868
1869        // Creating a new session cookie based on that session
1870
if ((session != null) && (getContext() != null)
1871            && getContext().getCookies()) {
1872            Cookie JavaDoc cookie = new Cookie JavaDoc(Globals.SESSION_COOKIE_NAME,
1873                                       session.getId());
1874            cookie.setMaxAge(-1);
1875            String JavaDoc contextPath = null;
1876            if (context != null)
1877                contextPath = context.getPath();
1878            if ((contextPath != null) && (contextPath.length() > 0))
1879                cookie.setPath(contextPath);
1880            else
1881                cookie.setPath("/");
1882            if (isSecure())
1883                cookie.setSecure(true);
1884            ((HttpServletResponse JavaDoc) response).addCookie(cookie);
1885        }
1886
1887        if (session != null)
1888            return (session.getSession());
1889        else
1890            return (null);
1891
1892    }
1893
1894
1895    /**
1896     * Parse request parameters.
1897     */

1898    protected void parseRequestParameters() {
1899
1900        requestParametersParsed = true;
1901
1902        Parameters parameters = coyoteRequest.getParameters();
1903
1904        String JavaDoc enc = coyoteRequest.getCharacterEncoding();
1905        boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
1906        if (enc != null) {
1907            parameters.setEncoding(enc);
1908            if (useBodyEncodingForURI) {
1909                parameters.setQueryStringEncoding(enc);
1910            }
1911        } else {
1912            parameters.setEncoding
1913                (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
1914            if (useBodyEncodingForURI) {
1915                parameters.setQueryStringEncoding
1916                    (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
1917            }
1918        }
1919
1920        parameters.handleQueryParameters();
1921
1922        if (usingInputStream || usingReader)
1923            return;
1924
1925        if (!getMethod().equalsIgnoreCase("POST"))
1926            return;
1927
1928        String JavaDoc contentType = getContentType();
1929        if (contentType == null)
1930            contentType = "";
1931        int semicolon = contentType.indexOf(';');
1932        if (semicolon >= 0) {
1933            contentType = contentType.substring(0, semicolon).trim();
1934        } else {
1935            contentType = contentType.trim();
1936        }
1937        if (!("application/x-www-form-urlencoded".equals(contentType)))
1938            return;
1939
1940        int len = getContentLength();
1941
1942        if (len > 0) {
1943            try {
1944                byte[] formData = null;
1945                if (len < CACHED_POST_LEN) {
1946                    if (postData == null)
1947                        postData = new byte[CACHED_POST_LEN];
1948                    formData = postData;
1949                } else {
1950                    formData = new byte[len];
1951                }
1952                int actualLen = readPostBody(formData, len);
1953                if (actualLen == len) {
1954                    parameters.processParameters(formData, 0, len);
1955                }
1956            } catch (Throwable JavaDoc t) {
1957                ; // Ignore
1958
}
1959        }
1960
1961    }
1962
1963
1964    /**
1965     * Read post body in an array.
1966     */

1967    protected int readPostBody(byte body[], int len)
1968        throws IOException JavaDoc {
1969
1970        int offset = 0;
1971        do {
1972            int inputLen = getStream().read(body, offset, len - offset);
1973            if (inputLen <= 0) {
1974                return offset;
1975            }
1976            offset += inputLen;
1977        } while ((len - offset) > 0);
1978        return len;
1979
1980    }
1981
1982
1983    /**
1984     * Parse request locales.
1985     */

1986    protected void parseLocales() {
1987
1988        localesParsed = true;
1989
1990        Enumeration JavaDoc values = getHeaders("accept-language");
1991
1992        while (values.hasMoreElements()) {
1993            String JavaDoc value = values.nextElement().toString();
1994            parseLocalesHeader(value);
1995        }
1996
1997    }
1998
1999
2000    /**
2001     * Parse accept-language header value.
2002     */

2003    protected void parseLocalesHeader(String JavaDoc value) {
2004
2005        // Store the accumulated languages that have been requested in
2006
// a local collection, sorted by the quality value (so we can
2007
// add Locales in descending order). The values will be ArrayLists
2008
// containing the corresponding Locales to be added
2009
TreeMap JavaDoc locales = new TreeMap JavaDoc();
2010
2011        // Preprocess the value to remove all whitespace
2012
int white = value.indexOf(' ');
2013        if (white < 0)
2014            white = value.indexOf('\t');
2015        if (white >= 0) {
2016            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
2017            int len = value.length();
2018            for (int i = 0; i < len; i++) {
2019                char ch = value.charAt(i);
2020                if ((ch != ' ') && (ch != '\t'))
2021                    sb.append(ch);
2022            }
2023            value = sb.toString();
2024        }
2025
2026        // Process each comma-delimited language specification
2027
parser.setString(value); // ASSERT: parser is available to us
2028
int length = parser.getLength();
2029        while (true) {
2030
2031            // Extract the next comma-delimited entry
2032
int start = parser.getIndex();
2033            if (start >= length)
2034                break;
2035            int end = parser.findChar(',');
2036            String JavaDoc entry = parser.extract(start, end).trim();
2037            parser.advance(); // For the following entry
2038

2039            // Extract the quality factor for this entry
2040
double quality = 1.0;
2041            int semi = entry.indexOf(";q=");
2042            if (semi >= 0) {
2043                try {
2044                    quality = Double.parseDouble(entry.substring(semi + 3));
2045                } catch (NumberFormatException JavaDoc e) {
2046                    quality = 0.0;
2047                }
2048                entry = entry.substring(0, semi);
2049            }
2050
2051            // Skip entries we are not going to keep track of
2052
if (quality < 0.00005)
2053                continue; // Zero (or effectively zero) quality factors
2054
if ("*".equals(entry))
2055                continue; // FIXME - "*" entries are not handled
2056

2057            // Extract the language and country for this entry
2058
String JavaDoc language = null;
2059            String JavaDoc country = null;
2060            String JavaDoc variant = null;
2061            int dash = entry.indexOf('-');
2062            if (dash < 0) {
2063                language = entry;
2064                country = "";
2065                variant = "";
2066            } else {
2067                language = entry.substring(0, dash);
2068                country = entry.substring(dash + 1);
2069                int vDash = country.indexOf('-');
2070                if (vDash > 0) {
2071                    String JavaDoc cTemp = country.substring(0, vDash);
2072                    variant = country.substring(vDash + 1);
2073                    country = cTemp;
2074                } else {
2075                    variant = "";
2076                }
2077            }
2078
2079            // Add a new Locale to the list of Locales for this quality level
2080
Locale JavaDoc locale = new Locale JavaDoc(language, country, variant);
2081            Double JavaDoc key = new Double JavaDoc(-quality); // Reverse the order
2082
ArrayList JavaDoc values = (ArrayList JavaDoc) locales.get(key);
2083            if (values == null) {
2084                values = new ArrayList JavaDoc();
2085                locales.put(key, values);
2086            }
2087            values.add(locale);
2088
2089        }
2090
2091        // Process the quality values in highest->lowest order (due to
2092
// negating the Double value when creating the key)
2093
Iterator JavaDoc keys = locales.keySet().iterator();
2094        while (keys.hasNext()) {
2095            Double JavaDoc key = (Double JavaDoc) keys.next();
2096            ArrayList JavaDoc list = (ArrayList JavaDoc) locales.get(key);
2097            Iterator JavaDoc values = list.iterator();
2098            while (values.hasNext()) {
2099                Locale JavaDoc locale = (Locale JavaDoc) values.next();
2100                addLocale(locale);
2101            }
2102        }
2103
2104    }
2105
2106
2107}
2108
Popular Tags