View Javadoc

1   //========================================================================
2   //$Id: Request.java,v 1.15 2005/11/16 22:02:40 gregwilkins Exp $
3   //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at 
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
14  //========================================================================
15  
16  package org.mortbay.jetty;
17  
18  import java.io.BufferedReader;
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.InputStreamReader;
22  import java.io.UnsupportedEncodingException;
23  import java.net.InetAddress;
24  import java.nio.ByteBuffer;
25  import java.security.Principal;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.Enumeration;
29  import java.util.EventListener;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.List;
33  import java.util.Locale;
34  import java.util.Map;
35  
36  import javax.servlet.RequestDispatcher;
37  import javax.servlet.ServletContext;
38  import javax.servlet.ServletInputStream;
39  import javax.servlet.ServletRequestAttributeEvent;
40  import javax.servlet.ServletRequestAttributeListener;
41  import javax.servlet.ServletRequestWrapper;
42  import javax.servlet.ServletResponse;
43  import javax.servlet.http.Cookie;
44  import javax.servlet.http.HttpServletRequest;
45  import javax.servlet.http.HttpSession;
46  
47  import org.mortbay.io.Buffer;
48  import org.mortbay.io.BufferUtil;
49  import org.mortbay.io.EndPoint;
50  import org.mortbay.io.Portable;
51  import org.mortbay.io.nio.DirectNIOBuffer;
52  import org.mortbay.io.nio.IndirectNIOBuffer;
53  import org.mortbay.io.nio.NIOBuffer;
54  import org.mortbay.jetty.handler.ContextHandler;
55  import org.mortbay.jetty.handler.ContextHandler.SContext;
56  import org.mortbay.jetty.security.Authenticator;
57  import org.mortbay.jetty.security.SecurityHandler;
58  import org.mortbay.jetty.security.UserRealm;
59  import org.mortbay.log.Log;
60  import org.mortbay.util.Attributes;
61  import org.mortbay.util.AttributesMap;
62  import org.mortbay.util.LazyList;
63  import org.mortbay.util.MultiMap;
64  import org.mortbay.util.StringUtil;
65  import org.mortbay.util.URIUtil;
66  import org.mortbay.util.UrlEncoded;
67  import org.mortbay.util.ajax.Continuation;
68  
69  /* ------------------------------------------------------------ */
70  /** Jetty Request.
71   * <p>
72   * Implements {@link javax.servlet.HttpServletRequest} from the {@link javax.servlet} package.   
73   * </p>
74   * <p>
75   * The standard interface of mostly getters,
76   * is extended with setters so that the request is mutable by the handlers that it is
77   * passed to.  This allows the request object to be as lightweight as possible and not
78   * actually implement any significant behaviour. For example<ul>
79   * 
80   * <li>The {@link getContextPath} method will return null, until the requeset has been 
81   * passed to a {@link ContextHandler} which matches the {@link getPathInfo} with a context
82   * path and calls {@link setContextPath} as a result.</li>
83   * 
84   * <li>the HTTP session methods
85   * will all return null sessions until such time as a request has been passed to
86   * a {@link org.mortbay.jetty.servlet.SessionHandler} which checks for session cookies
87   * and enables the ability to create new sessions.</li>
88   * 
89   * <li>The {@link getServletPath} method will return null until the request has been
90   * passed to a {@link org.mortbay.jetty.servlet.ServletHandler} and the pathInfo matched
91   * against the servlet URL patterns and {@link setServletPath} called as a result.</li>
92   * </ul>
93   * 
94   * A request instance is created for each {@link HttpConnection} accepted by the server 
95   * and recycled for each HTTP request received via that connection. An effort is made
96   * to avoid reparsing headers and cookies that are likely to be the same for 
97   * requests from the same connection.
98   * 
99   * @author gregw
100  *
101  */
102 public class Request implements HttpServletRequest
103 {
104     private static final byte STATE_DELIMITER = 1;
105     private static final byte STATE_NAME = 2;
106     private static final byte STATE_VALUE = 4;
107     private static final byte STATE_QUOTED_VALUE = 8;
108     private static final byte STATE_UNQUOTED_VALUE = 16;
109 
110     private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault());
111     private static final int __NONE=0, _STREAM=1, __READER=2;
112     
113     private boolean _handled =false;
114     private HttpConnection _connection;
115     private EndPoint _endp;
116     private Map _roleMap;
117     
118     private Attributes _attributes;
119     private String _authType;
120     private String _characterEncoding;
121     private String _queryEncoding;
122     private String _serverName;
123     private String _remoteAddr;
124     private String _remoteHost;
125     private String _method;
126     private String _pathInfo;
127     private int _port;
128     private String _protocol=HttpVersions.HTTP_1_1;
129     private String _queryString;
130     private String _requestedSessionId;
131     private boolean _requestedSessionIdFromCookie=false;
132     private String _requestURI;
133     private String _scheme=URIUtil.HTTP;
134     private String _contextPath;
135     private String _servletPath;
136     private String _servletName;
137     private HttpURI _uri;
138     private Principal _userPrincipal;
139     private MultiMap _parameters;
140     private MultiMap _baseParameters;
141     private boolean _paramsExtracted;
142     private int _inputState=__NONE;
143     private BufferedReader _reader;
144     private String _readerEncoding;
145     private boolean _dns=false;
146     private ContextHandler.SContext _context;
147     private HttpSession _session;
148     private SessionManager _sessionManager;
149     private boolean _cookiesExtracted=false;
150     private Cookie[] _cookies;
151     private String[] _lastCookies;
152     private long _timeStamp;
153     private Buffer _timeStampBuffer;
154     private Continuation _continuation;
155     private Object _requestAttributeListeners;
156     private Map _savedNewSessions;
157     private UserRealm _userRealm;
158     
159     /* ------------------------------------------------------------ */
160     /**
161      * 
162      */
163     public Request()
164     {
165     }
166 
167     /* ------------------------------------------------------------ */
168     /**
169      * 
170      */
171     public Request(HttpConnection connection)
172     {
173         _connection=connection;
174         _endp=connection.getEndPoint();
175         _dns=_connection.getResolveNames();
176     }
177 
178     /* ------------------------------------------------------------ */
179     protected void setConnection(HttpConnection connection)
180     {
181         _connection=connection;
182         _endp=connection.getEndPoint();
183         _dns=connection.getResolveNames();
184     }
185     
186     /* ------------------------------------------------------------ */
187     protected void recycle()
188     {
189         _handled=false;
190         if (_context!=null)
191             throw new IllegalStateException("Request in context!");
192         if(_attributes!=null)
193             _attributes.clearAttributes();
194         _authType=null;
195         _characterEncoding=null;
196         _queryEncoding=null;
197         _context=null;
198         _serverName=null;
199         _method=null;
200         _pathInfo=null;
201         _port=0;
202         _protocol=HttpVersions.HTTP_1_1;
203         _queryString=null;
204         _requestedSessionId=null;
205         _requestedSessionIdFromCookie=false;
206         _session=null;
207         _requestURI=null;
208         _scheme=URIUtil.HTTP;
209         _servletPath=null;
210         _timeStamp=0;
211         _timeStampBuffer=null;
212         _uri=null;
213         _userPrincipal=null;
214         if (_baseParameters!=null)
215             _baseParameters.clear();
216         _parameters=null;
217         _paramsExtracted=false;
218         _inputState=__NONE;
219         
220         _cookiesExtracted=false;
221         if (_savedNewSessions!=null)
222             _savedNewSessions.clear();
223         _savedNewSessions=null;
224         if (_continuation!=null && _continuation.isPending())
225             _continuation.reset();
226     }
227 
228     /* ------------------------------------------------------------ */
229     /**
230      * Get Request TimeStamp
231      * 
232      * @return The time that the request was received.
233      */
234     public Buffer getTimeStampBuffer()
235     {
236         if (_timeStampBuffer == null && _timeStamp > 0)
237                 _timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp);
238         return _timeStampBuffer;
239     }
240 
241     /* ------------------------------------------------------------ */
242     /**
243      * Get Request TimeStamp
244      * 
245      * @return The time that the request was received.
246      */
247     public long getTimeStamp()
248     {
249         return _timeStamp;
250     }
251 
252     /* ------------------------------------------------------------ */
253     public void setTimeStamp(long ts)
254     {
255         _timeStamp = ts;
256     }
257 
258     /* ------------------------------------------------------------ */
259     public boolean isHandled()
260     {
261         return _handled;
262     }
263 
264     /* ------------------------------------------------------------ */
265     public void setHandled(boolean h)
266     {
267         _handled=h;
268     }
269     
270     
271     /* ------------------------------------------------------------ */
272     /* 
273      * @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
274      */
275     public Object getAttribute(String name)
276     {
277         if ("org.mortbay.jetty.ajax.Continuation".equals(name))
278             return getContinuation(true);
279             
280         if (_attributes==null)
281             return null;
282         return _attributes.getAttribute(name);
283     }
284 
285     /* ------------------------------------------------------------ */
286     /* 
287      * @see javax.servlet.ServletRequest#getAttributeNames()
288      */
289     public Enumeration getAttributeNames()
290     {
291         if (_attributes==null)
292             return Collections.enumeration(Collections.EMPTY_LIST);
293         return AttributesMap.getAttributeNamesCopy(_attributes);
294     }
295 
296     /* ------------------------------------------------------------ */
297     /* 
298      * @see javax.servlet.http.HttpServletRequest#getAuthType()
299      */
300     public String getAuthType()
301     {
302         return _authType;
303     }
304 
305     /* ------------------------------------------------------------ */
306     /* 
307      * @see javax.servlet.ServletRequest#getCharacterEncoding()
308      */
309     public String getCharacterEncoding()
310     {
311         return _characterEncoding;
312     }
313     
314 
315     /* ------------------------------------------------------------ */
316     /* 
317      * @see javax.servlet.ServletRequest#getContentLength()
318      */
319     public int getContentLength()
320     {
321         return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER);
322     }
323 
324     /* ------------------------------------------------------------ */
325     /* 
326      * @see javax.servlet.ServletRequest#getContentType()
327      */
328     public String getContentType()
329     {
330         return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_BUFFER);
331     }
332 
333     /* ------------------------------------------------------------ */
334     /* 
335      * @see javax.servlet.ServletRequest#getContentType()
336      */
337     public void setContentType(String contentType)
338     {
339         _connection.getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,contentType);
340         
341     }
342 
343     /* ------------------------------------------------------------ */
344     /* 
345      * @see javax.servlet.http.HttpServletRequest#getContextPath()
346      */
347     public String getContextPath()
348     {
349         return _contextPath;
350     }
351 
352     /* ------------------------------------------------------------ */
353     /* 
354      * @see javax.servlet.http.HttpServletRequest#getCookies()
355      */
356     public Cookie[] getCookies()
357     {
358         if (_cookiesExtracted) return _cookies;
359 
360         try
361         {
362             // Handle no cookies
363             if (!_connection.getRequestFields().containsKey(HttpHeaders.COOKIE_BUFFER))
364             {
365                 _cookies = null;
366                 _cookiesExtracted = true;
367                 _lastCookies = null;
368                 return _cookies;
369             }
370 
371             // Check if cookie headers match last cookies
372             if (_lastCookies != null)
373             {
374                 int last = 0;
375                 Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER);
376                 while (enm.hasMoreElements())
377                 {
378                     String c = (String)enm.nextElement();
379                     if (last >= _lastCookies.length || !c.equals(_lastCookies[last]))
380                     {
381                         _lastCookies = null;
382                         break;
383                     }
384                     last++;
385                 }
386                 if (_lastCookies != null && _lastCookies.length==last)
387                 {
388                     _cookiesExtracted = true;
389                     return _cookies;
390                 }
391             }
392 
393             // Get ready to parse cookies (Expensive!!!)
394             Object cookies = null;
395             Object lastCookies = null;
396 
397             int version = 0;
398 
399             // For each cookie header
400             Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER);
401             while (enm.hasMoreElements())
402             {
403                 // Save a copy of the unparsed header as cache.
404                 String hdr = (String)enm.nextElement();
405                 lastCookies = LazyList.add(lastCookies, hdr);
406 
407                 // Parse the header
408                 String name = null;
409                 String value = null;
410 
411                 Cookie cookie = null;
412 
413                 byte state = STATE_NAME;
414                 for (int i = 0, tokenstart = 0, length = hdr.length(); i < length; i++)
415                 {
416                     char c = hdr.charAt(i);
417                     switch (c)
418                     {
419                         case ',':
420                         case ';':
421                             switch (state)
422                             {
423                                 case STATE_DELIMITER:
424                                     state = STATE_NAME;
425                                     tokenstart = i + 1;
426                                     break;
427                                 case STATE_UNQUOTED_VALUE:
428                                     state = STATE_NAME;
429                                     value = hdr.substring(tokenstart, i).trim();
430                                     if(isRequestedSessionIdFromURL())
431                                         value = URIUtil.decodePath(value);
432                                     tokenstart = i + 1;
433                                     break;
434                                 case STATE_NAME:
435                                     name = hdr.substring(tokenstart, i);
436                                     value = "";
437                                     tokenstart = i + 1;
438                                     break;
439                                 case STATE_VALUE:
440                                     state = STATE_NAME;
441                                     value = "";
442                                     tokenstart = i + 1;
443                                     break;
444                             }
445                             break;
446                         case '=':
447                             switch (state)
448                             {
449                                 case STATE_NAME:
450                                     state = STATE_VALUE;
451                                     name = hdr.substring(tokenstart, i);
452                                     tokenstart = i + 1;
453                                     break;
454                                 case STATE_VALUE:
455                                     state = STATE_UNQUOTED_VALUE;
456                                     tokenstart = i;
457                                     break;
458                             }
459                             break;
460                         case '"':
461                             switch (state)
462                             {
463                                 case STATE_VALUE:
464                                     state = STATE_QUOTED_VALUE;
465                                     tokenstart = i + 1;
466                                     break;
467                                 case STATE_QUOTED_VALUE:
468                                     state = STATE_DELIMITER;
469                                     value = hdr.substring(tokenstart, i);
470                                     break;
471                             }
472                             break;
473                         case ' ':
474                         case '\t':
475                             break;
476                         default:
477                             switch (state)
478                             {
479                                 case STATE_VALUE:
480                                     state = STATE_UNQUOTED_VALUE;
481                                     tokenstart = i;
482                                     break;
483                                 case STATE_DELIMITER:
484                                     state = STATE_NAME;
485                                     tokenstart = i;
486                                     break;
487                             }
488                     }
489 
490                     if (i + 1 == length)
491                     {
492                         switch (state)
493                         {
494                             case STATE_UNQUOTED_VALUE:
495                                 value = hdr.substring(tokenstart).trim();
496                                 if(isRequestedSessionIdFromURL())
497                                     value = URIUtil.decodePath(value);
498                                 break;
499                             case STATE_NAME:
500                                 name = hdr.substring(tokenstart);
501                                 value = "";
502                                 break;
503                             case STATE_VALUE:
504                                 value = "";
505                                 break;
506                         }
507                     }
508 
509                     if (name != null && value != null)
510                     {
511                         name = name.trim();
512 
513                         try
514                         {
515                             if (name.startsWith("$"))
516                             {
517                                 String lowercaseName = name.toLowerCase();
518                                 if ("$path".equals(lowercaseName))
519                                 {
520                                     cookie.setPath(value);
521                                 }
522                                 else if ("$domain".equals(lowercaseName))
523                                 {
524                                     cookie.setDomain(value);
525                                 }
526                                 else if ("$version".equals(lowercaseName))
527                                 {
528                                     version = Integer.parseInt(value);
529                                 }
530                             }
531                             else
532                             {
533                                 cookie = new Cookie(name, value);
534 
535                                 if (version > 0)
536                                 {
537                                     cookie.setVersion(version);
538                                 }
539 
540                                 cookies = LazyList.add(cookies, cookie);
541                             }
542                         }
543                         catch (Exception e)
544                         {
545                             Log.ignore(e);
546                         }
547 
548                         name = null;
549                         value = null;
550                     }
551                 }
552             }
553 
554             int l = LazyList.size(cookies);
555             _cookiesExtracted = true;
556             if (l>0)
557             {
558                 if (_cookies == null || _cookies.length != l) _cookies = new Cookie[l];
559                 for (int i = 0; i < l; i++)
560                     _cookies[i] = (Cookie) LazyList.get(cookies, i);
561 
562                 l = LazyList.size(lastCookies);
563                 _lastCookies = new String[l];
564                 for (int i = 0; i < l; i++)
565                     _lastCookies[i] = (String) LazyList.get(lastCookies, i);
566             }
567         }
568         catch (Exception e)
569         {
570             Log.warn(e);
571         }
572 
573         if (_cookies==null || _cookies.length==0)
574             return null;
575         return _cookies;
576     }
577 
578     /* ------------------------------------------------------------ */
579     /* 
580      * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String)
581      */
582     public long getDateHeader(String name)
583     {
584         return _connection.getRequestFields().getDateField(name);
585     }
586 
587     /* ------------------------------------------------------------ */
588     /* 
589      * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
590      */
591     public String getHeader(String name)
592     {
593         return _connection.getRequestFields().getStringField(name);
594     }
595 
596     /* ------------------------------------------------------------ */
597     /* 
598      * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
599      */
600     public Enumeration getHeaderNames()
601     {
602         return _connection.getRequestFields().getFieldNames();
603     }
604 
605     /* ------------------------------------------------------------ */
606     /* 
607      * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
608      */
609     public Enumeration getHeaders(String name)
610     {
611         Enumeration e = _connection.getRequestFields().getValues(name);
612         if (e==null)
613             return Collections.enumeration(Collections.EMPTY_LIST);
614         return e;
615     }
616 
617     /* ------------------------------------------------------------ */
618     /* 
619      * @see javax.servlet.ServletRequest#getInputStream()
620      */
621     public ServletInputStream getInputStream() throws IOException
622     {
623         if (_inputState!=__NONE && _inputState!=_STREAM)
624             throw new IllegalStateException("READER");
625         _inputState=_STREAM;
626         return _connection.getInputStream();
627     }
628 
629     /* ------------------------------------------------------------ */
630     /* 
631      * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String)
632      */
633     public int getIntHeader(String name)
634     {
635         return (int)_connection.getRequestFields().getLongField(name);
636     }
637 
638     /* ------------------------------------------------------------ */
639     /* 
640      * @see javax.servlet.ServletRequest#getLocalAddr()
641      */
642     public String getLocalAddr()
643     {
644         return _endp==null?null:_endp.getLocalAddr();
645     }
646 
647     /* ------------------------------------------------------------ */
648     /* 
649      * @see javax.servlet.ServletRequest#getLocale()
650      */
651     public Locale getLocale()
652     {
653         Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE, HttpFields.__separators);
654         
655         // handle no locale
656         if (enm == null || !enm.hasMoreElements())
657             return Locale.getDefault();
658         
659         // sort the list in quality order
660         List acceptLanguage = HttpFields.qualityList(enm);
661         if (acceptLanguage.size()==0)
662             return  Locale.getDefault();
663         
664         int size=acceptLanguage.size();
665         
666         // convert to locals
667         for (int i=0; i<size; i++)
668         {
669             String language = (String)acceptLanguage.get(i);
670             language=HttpFields.valueParameters(language,null);
671             String country = "";
672             int dash = language.indexOf('-');
673             if (dash > -1)
674             {
675                 country = language.substring(dash + 1).trim();
676                 language = language.substring(0,dash).trim();
677             }
678             return new Locale(language,country);
679         }
680         
681         return  Locale.getDefault();
682     }
683 
684     /* ------------------------------------------------------------ */
685     /* 
686      * @see javax.servlet.ServletRequest#getLocales()
687      */
688     public Enumeration getLocales()
689     {
690 
691         Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE, HttpFields.__separators);
692         
693         // handle no locale
694         if (enm == null || !enm.hasMoreElements())
695             return Collections.enumeration(__defaultLocale);
696         
697         // sort the list in quality order
698         List acceptLanguage = HttpFields.qualityList(enm);
699         
700         if (acceptLanguage.size()==0)
701             return
702             Collections.enumeration(__defaultLocale);
703         
704         Object langs = null;
705         int size=acceptLanguage.size();
706         
707         // convert to locals
708         for (int i=0; i<size; i++)
709         {
710             String language = (String)acceptLanguage.get(i);
711             language=HttpFields.valueParameters(language,null);
712             String country = "";
713             int dash = language.indexOf('-');
714             if (dash > -1)
715             {
716                 country = language.substring(dash + 1).trim();
717                 language = language.substring(0,dash).trim();
718             }
719             langs=LazyList.ensureSize(langs,size);
720             langs=LazyList.add(langs,new Locale(language,country));
721         }
722         
723         if (LazyList.size(langs)==0)
724             return Collections.enumeration(__defaultLocale);
725         
726         return Collections.enumeration(LazyList.getList(langs));
727     }
728 
729     /* ------------------------------------------------------------ */
730     /* 
731      * @see javax.servlet.ServletRequest#getLocalName()
732      */
733     public String getLocalName()
734     {
735         if (_dns)
736             return _endp==null?null:_endp.getLocalHost();
737         return _endp==null?null:_endp.getLocalAddr();
738     }
739 
740     /* ------------------------------------------------------------ */
741     /* 
742      * @see javax.servlet.ServletRequest#getLocalPort()
743      */
744     public int getLocalPort()
745     {
746         return _endp==null?0:_endp.getLocalPort();
747     }
748 
749     /* ------------------------------------------------------------ */
750     /* 
751      * @see javax.servlet.http.HttpServletRequest#getMethod()
752      */
753     public String getMethod()
754     {
755         return _method;
756     }
757 
758     /* ------------------------------------------------------------ */
759     /* 
760      * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
761      */
762     public String getParameter(String name)
763     {
764         if (!_paramsExtracted) 
765             extractParameters();
766         return (String) _parameters.getValue(name, 0);
767     }
768 
769     /* ------------------------------------------------------------ */
770     /* 
771      * @see javax.servlet.ServletRequest#getParameterMap()
772      */
773     public Map getParameterMap()
774     {
775         if (!_paramsExtracted) 
776             extractParameters();
777         
778         return Collections.unmodifiableMap(_parameters.toStringArrayMap());
779     }
780 
781     /* ------------------------------------------------------------ */
782     /* 
783      * @see javax.servlet.ServletRequest#getParameterNames()
784      */
785     public Enumeration getParameterNames()
786     {
787         if (!_paramsExtracted) 
788             extractParameters();
789         return Collections.enumeration(_parameters.keySet());
790     }
791 
792     /* ------------------------------------------------------------ */
793     /* 
794      * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
795      */
796     public String[] getParameterValues(String name)
797     {
798         if (!_paramsExtracted) 
799             extractParameters();
800         List vals = _parameters.getValues(name);
801         if (vals==null)
802             return null;
803         return (String[])vals.toArray(new String[vals.size()]);
804     }
805 
806     /* ------------------------------------------------------------ */
807     /* 
808      * @see javax.servlet.http.HttpServletRequest#getPathInfo()
809      */
810     public String getPathInfo()
811     {
812         return _pathInfo;
813     }
814 
815     /* ------------------------------------------------------------ */
816     /* 
817      * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
818      */
819     public String getPathTranslated()
820     {
821         if (_pathInfo==null || _context==null)
822             return null;
823         return _context.getRealPath(_pathInfo);
824     }
825 
826     /* ------------------------------------------------------------ */
827     /* 
828      * @see javax.servlet.ServletRequest#getProtocol()
829      */
830     public String getProtocol()
831     {
832         return _protocol;
833     }
834 
835     /* ------------------------------------------------------------ */
836     /* 
837      * @see javax.servlet.ServletRequest#getReader()
838      */
839     public BufferedReader getReader() throws IOException
840     {
841         if (_inputState!=__NONE && _inputState!=__READER)
842             throw new IllegalStateException("STREAMED");
843 
844         if (_inputState==__READER)
845             return _reader;
846         
847         String encoding=getCharacterEncoding();
848         if (encoding==null)
849             encoding=StringUtil.__ISO_8859_1;
850         
851         if (_reader==null || !encoding.equalsIgnoreCase(_readerEncoding))
852         {
853             final ServletInputStream in = getInputStream();
854             _readerEncoding=encoding;
855             _reader=new BufferedReader(new InputStreamReader(in,encoding))
856             {
857                 public void close() throws IOException
858                 {
859                     in.close();
860                 }   
861             };
862         }
863         _inputState=__READER;
864         return _reader;
865     }
866 
867     /* ------------------------------------------------------------ */
868     /* 
869      * @see javax.servlet.ServletRequest#getRealPath(java.lang.String)
870      */
871     public String getRealPath(String path)
872     {
873         if (_context==null)
874             return null;
875         return _context.getRealPath(path);
876     }
877 
878     /* ------------------------------------------------------------ */
879     /* 
880      * @see javax.servlet.ServletRequest#getRemoteAddr()
881      */
882     public String getRemoteAddr()
883     {
884         if (_remoteAddr != null)
885             return _remoteAddr;	
886         return _endp==null?null:_endp.getRemoteAddr();
887     }
888 
889     /* ------------------------------------------------------------ */
890     /* 
891      * @see javax.servlet.ServletRequest#getRemoteHost()
892      */
893     public String getRemoteHost()
894     {
895         if (_dns)
896         {
897             if (_remoteHost != null)
898             {
899                 return _remoteHost;
900             }
901             return _endp==null?null:_endp.getRemoteHost();
902         }
903         return getRemoteAddr();
904     }
905 
906     /* ------------------------------------------------------------ */
907     /* 
908      * @see javax.servlet.ServletRequest#getRemotePort()
909      */
910     public int getRemotePort()
911     {
912         return _endp==null?0:_endp.getRemotePort();
913     }
914 
915     /* ------------------------------------------------------------ */
916     /* 
917      * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
918      */
919     public String getRemoteUser()
920     {
921         Principal p = getUserPrincipal();
922         if (p==null)
923             return null;
924         return p.getName();
925     }
926 
927     /* ------------------------------------------------------------ */
928     /* 
929      * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String)
930      */
931     public RequestDispatcher getRequestDispatcher(String path)
932     {
933         if (path == null || _context==null)
934             return null;
935 
936         // handle relative path
937         if (!path.startsWith("/"))
938         {
939             String relTo=URIUtil.addPaths(_servletPath,_pathInfo);
940             int slash=relTo.lastIndexOf("/");
941             if (slash>1)
942                 relTo=relTo.substring(0,slash+1);
943             else
944                 relTo="/";
945             path=URIUtil.addPaths(relTo,path);
946         }
947     
948         return _context.getRequestDispatcher(path);
949     }
950 
951     /* ------------------------------------------------------------ */
952     /* 
953      * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
954      */
955     public String getRequestedSessionId()
956     {
957         return _requestedSessionId;
958     }
959 
960     /* ------------------------------------------------------------ */
961     /* 
962      * @see javax.servlet.http.HttpServletRequest#getRequestURI()
963      */
964     public String getRequestURI()
965     {
966         if (_requestURI==null && _uri!=null)
967             _requestURI=_uri.getPathAndParam();
968         return _requestURI;
969     }
970 
971     /* ------------------------------------------------------------ */
972     /* 
973      * @see javax.servlet.http.HttpServletRequest#getRequestURL()
974      */
975     public StringBuffer getRequestURL()
976     {
977         StringBuffer url = new StringBuffer(48);
978         synchronized (url)
979         {
980             String scheme = getScheme();
981             int port = getServerPort();
982 
983             url.append(scheme);
984             url.append("://");
985             url.append(getServerName());
986             if (_port>0 && 
987                 ((scheme.equalsIgnoreCase(URIUtil.HTTP) && port != 80) || 
988                  (scheme.equalsIgnoreCase(URIUtil.HTTPS) && port != 443)))
989             {
990                 url.append(':');
991                 url.append(_port);
992             }
993             
994             url.append(getRequestURI());
995             return url;
996         }
997     }
998 
999     /* ------------------------------------------------------------ */
1000     /* 
1001      * @see javax.servlet.ServletRequest#getScheme()
1002      */
1003     public String getScheme()
1004     {
1005         return _scheme;
1006     }
1007 
1008     /* ------------------------------------------------------------ */
1009     /* 
1010      * @see javax.servlet.ServletRequest#getServerName()
1011      */
1012     public String getServerName()
1013     {       
1014         // Return already determined host
1015         if (_serverName != null) 
1016             return _serverName;
1017 
1018         // Return host from absolute URI
1019         _serverName = _uri.getHost();
1020         _port = _uri.getPort();
1021         if (_serverName != null) 
1022             return _serverName;
1023 
1024         // Return host from header field
1025         Buffer hostPort = _connection.getRequestFields().get(HttpHeaders.HOST_BUFFER);
1026         if (hostPort!=null)
1027         {
1028             for (int i=hostPort.length();i-->0;)   
1029             {
1030                 if (hostPort.peek(hostPort.getIndex()+i)==':')
1031                 {
1032                     _serverName=BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(), i));
1033                     _port=BufferUtil.toInt(hostPort.peek(hostPort.getIndex()+i+1, hostPort.length()-i-1));
1034                     return _serverName;
1035                 }
1036             }
1037             if (_serverName==null || _port<0)
1038             {
1039                 _serverName=BufferUtil.to8859_1_String(hostPort);
1040                 _port = 0;
1041             }
1042             
1043             return _serverName;
1044         }
1045 
1046         // Return host from connection
1047         if (_connection != null)
1048         {
1049             _serverName = getLocalName();
1050             _port = getLocalPort();
1051             if (_serverName != null && !Portable.ALL_INTERFACES.equals(_serverName)) 
1052                 return _serverName;
1053         }
1054 
1055         // Return the local host
1056         try
1057         {
1058             _serverName = InetAddress.getLocalHost().getHostAddress();
1059         }
1060         catch (java.net.UnknownHostException e)
1061         {
1062             Log.ignore(e);
1063         }
1064         return _serverName;
1065     }
1066 
1067     /* ------------------------------------------------------------ */
1068     /* 
1069      * @see javax.servlet.ServletRequest#getServerPort()
1070      */
1071     public int getServerPort()
1072     {
1073         if (_port<=0)
1074         {
1075             if (_serverName==null)
1076                 getServerName();
1077         
1078             if (_port<=0)
1079             {
1080                 if (_serverName!=null && _uri!=null)
1081                     _port = _uri.getPort();
1082                 else
1083                     _port = _endp==null?0:_endp.getLocalPort();
1084             }
1085         }
1086         
1087         if (_port<=0)
1088         {
1089             if (getScheme().equalsIgnoreCase(URIUtil.HTTPS))
1090                 return 443;
1091             return 80;
1092         }
1093         return _port;
1094     }
1095 
1096     /* ------------------------------------------------------------ */
1097     /* 
1098      * @see javax.servlet.http.HttpServletRequest#getServletPath()
1099      */
1100     public String getServletPath()
1101     {
1102         if (_servletPath==null)
1103             _servletPath="";
1104         return _servletPath;
1105     }
1106     
1107     /* ------------------------------------------------------------ */
1108     /* 
1109      */
1110     public String getServletName()
1111     {
1112         return _servletName;
1113     }
1114 
1115     /* ------------------------------------------------------------ */
1116     /* 
1117      * @see javax.servlet.http.HttpServletRequest#getSession()
1118      */
1119     public HttpSession getSession()
1120     {
1121         return getSession(true);
1122     }
1123 
1124     /* ------------------------------------------------------------ */
1125     /* 
1126      * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
1127      */
1128     public HttpSession getSession(boolean create)
1129     {
1130         if (_sessionManager==null && create)
1131             throw new IllegalStateException("No SessionHandler or SessionManager");
1132         
1133         if (_session != null && _sessionManager!=null && _sessionManager.isValid(_session))
1134             return _session;
1135         
1136         _session=null;
1137         
1138         String id=getRequestedSessionId();
1139         
1140         if (id != null && _sessionManager!=null)
1141         {
1142             _session=_sessionManager.getHttpSession(id);
1143             if (_session == null && !create)
1144                 return null;
1145         }
1146         
1147         if (_session == null && _sessionManager!=null && create )
1148         {
1149             _session=_sessionManager.newHttpSession(this);
1150             Cookie cookie=_sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
1151             if (cookie!=null)
1152                 _connection.getResponse().addCookie(cookie);
1153         }
1154         
1155         return _session;
1156     }
1157 
1158     /* ------------------------------------------------------------ */
1159     /* 
1160      * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
1161      */
1162     public Principal getUserPrincipal()
1163     {
1164         if (_userPrincipal != null && _userPrincipal instanceof SecurityHandler.NotChecked)
1165         {
1166             SecurityHandler.NotChecked not_checked=(SecurityHandler.NotChecked)_userPrincipal;
1167             _userPrincipal = SecurityHandler.__NO_USER;
1168             
1169             Authenticator auth=not_checked.getSecurityHandler().getAuthenticator();
1170             UserRealm realm=not_checked.getSecurityHandler().getUserRealm();
1171             String pathInContext=getPathInfo()==null?getServletPath():(getServletPath()+getPathInfo());
1172             
1173             if (realm != null && auth != null)
1174             {
1175                 try
1176                 {
1177                     auth.authenticate(realm, pathInContext, this, null);
1178                 }
1179                 catch (Exception e)
1180                 {
1181                     Log.ignore(e);
1182                 }
1183             }
1184         }
1185         
1186         if (_userPrincipal == SecurityHandler.__NO_USER) 
1187             return null;
1188         return _userPrincipal;
1189     }
1190 
1191     /* ------------------------------------------------------------ */
1192     /* 
1193      * @see javax.servlet.http.HttpServletRequest#getQueryString()
1194      */
1195     public String getQueryString()
1196     {
1197         if (_queryString==null && _uri!=null)
1198         {
1199             if (_queryEncoding==null)
1200                 _queryString=_uri.getQuery();
1201             else
1202                 _queryString=_uri.getQuery(_queryEncoding);
1203         }
1204         return _queryString;
1205     }
1206     
1207     /* ------------------------------------------------------------ */
1208     /* 
1209      * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
1210      */
1211     public boolean isRequestedSessionIdFromCookie()
1212     {
1213         return _requestedSessionId!=null && _requestedSessionIdFromCookie;
1214     }
1215 
1216     /* ------------------------------------------------------------ */
1217     /* 
1218      * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
1219      */
1220     public boolean isRequestedSessionIdFromUrl()
1221     {
1222         return _requestedSessionId!=null && !_requestedSessionIdFromCookie;
1223     }
1224 
1225     /* ------------------------------------------------------------ */
1226     /* 
1227      * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
1228      */
1229     public boolean isRequestedSessionIdFromURL()
1230     {
1231         return _requestedSessionId!=null && !_requestedSessionIdFromCookie;
1232     }
1233 
1234     /* ------------------------------------------------------------ */
1235     /* 
1236      * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
1237      */
1238     public boolean isRequestedSessionIdValid()
1239     {	
1240         if (_requestedSessionId==null)
1241             return false;
1242         
1243         HttpSession session=getSession(false);
1244         return (session==null?false:_sessionManager.getIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session)));
1245     }
1246 
1247     /* ------------------------------------------------------------ */
1248     /* 
1249      * @see javax.servlet.ServletRequest#isSecure()
1250      */
1251     public boolean isSecure()
1252     {
1253         return _connection.isConfidential(this);
1254     }
1255 
1256     /* ------------------------------------------------------------ */
1257     /* 
1258      * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
1259      */
1260     public boolean isUserInRole(String role)
1261     {
1262         if (_roleMap!=null)
1263         {
1264             String r=(String)_roleMap.get(role);
1265             if (r!=null)
1266                 role=r;
1267         }
1268 
1269         Principal principal = getUserPrincipal();
1270         
1271         if (_userRealm!=null && principal!=null)
1272             return _userRealm.isUserInRole(principal, role);
1273         
1274         return false;
1275     }
1276 
1277     /* ------------------------------------------------------------ */
1278     /* 
1279      * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
1280      */
1281     public void removeAttribute(String name)
1282     {
1283         Object old_value=_attributes==null?null:_attributes.getAttribute(name);
1284         
1285         if (_attributes!=null)
1286             _attributes.removeAttribute(name);
1287         
1288         if (old_value!=null)
1289         {
1290             if (_requestAttributeListeners!=null)
1291             {
1292                 ServletRequestAttributeEvent event =
1293                     new ServletRequestAttributeEvent(_context,this,name, old_value);
1294 
1295                 for(int i=0;i<LazyList.size(_requestAttributeListeners);i++)
1296                     ((ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i)).attributeRemoved(event);
1297             }
1298         }
1299     }
1300 
1301     /* ------------------------------------------------------------ */
1302     /* 
1303      * Set a request attribute.
1304      * if the attribute name is "org.mortbay.jetty.Request.queryEncoding" then
1305      * the value is also passed in a call to {@link #setQueryEncoding}.
1306      *
1307      * if the attribute name is "org.mortbay.jetty.ResponseBuffer", then
1308      * the response buffer is flushed with @{link #flushResponseBuffer}  
1309      * 
1310      * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object)
1311      */
1312     public void setAttribute(String name, Object value)
1313     {
1314         Object old_value=_attributes==null?null:_attributes.getAttribute(name);
1315         
1316         if ("org.mortbay.jetty.Request.queryEncoding".equals(name))
1317             setQueryEncoding(value==null?null:value.toString());
1318         else if("org.mortbay.jetty.ResponseBuffer".equals(name))
1319         {
1320             try 
1321             {
1322                 ByteBuffer byteBuffer=(ByteBuffer)value;
1323                 synchronized (byteBuffer)
1324                 {
1325                     NIOBuffer buffer = byteBuffer.isDirect()
1326                         ?(NIOBuffer)new DirectNIOBuffer(byteBuffer,true)
1327                         :(NIOBuffer)new IndirectNIOBuffer(byteBuffer,true);
1328                     ((HttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer);
1329                 }
1330             } 
1331             catch (IOException e)
1332             {
1333                 throw new RuntimeException(e);
1334             }
1335         }
1336 
1337 
1338         if (_attributes==null)
1339             _attributes=new AttributesMap();
1340         _attributes.setAttribute(name, value);
1341         
1342         if (_requestAttributeListeners!=null)
1343         {
1344             ServletRequestAttributeEvent event =
1345                 new ServletRequestAttributeEvent(_context,this,name, old_value==null?value:old_value);
1346 
1347             for(int i=0;i<LazyList.size(_requestAttributeListeners);i++)
1348             {
1349                 ServletRequestAttributeListener l = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i);
1350                 
1351                 if (old_value==null)
1352                     l.attributeAdded(event);
1353                 else if (value==null)
1354                     l.attributeRemoved(event);
1355                 else
1356                     l.attributeReplaced(event);
1357             }
1358         }
1359     }
1360 
1361     /* ------------------------------------------------------------ */
1362     /* 
1363      * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
1364      */
1365     public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException
1366     {
1367         if (_inputState!=__NONE) 
1368             return;
1369 
1370         _characterEncoding=encoding;
1371 
1372         // check encoding is supported
1373         if (!StringUtil.isUTF8(encoding))
1374             "".getBytes(encoding);
1375     }
1376 
1377     /* ------------------------------------------------------------ */
1378     /* 
1379      * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
1380      */
1381     public void setCharacterEncodingUnchecked(String encoding)
1382     {
1383         _characterEncoding=encoding;
1384     }
1385     
1386 
1387     /* ------------------------------------------------------------ */
1388     /*
1389      * Extract Paramters from query string and/or form _content.
1390      */
1391     private void extractParameters()
1392     {
1393         if (_baseParameters == null) 
1394             _baseParameters = new MultiMap(16);
1395         
1396         if (_paramsExtracted) 
1397         {
1398             if (_parameters==null)
1399                 _parameters=_baseParameters;
1400             return;
1401         }
1402         
1403         _paramsExtracted = true;
1404 
1405         // Handle query string
1406         if (_uri!=null && _uri.hasQuery())
1407         {
1408             if (_queryEncoding==null)
1409                 _uri.decodeQueryTo(_baseParameters);
1410             else
1411             {
1412                 try
1413                 {
1414                     _uri.decodeQueryTo(_baseParameters,_queryEncoding);
1415 
1416                 }
1417                 catch (UnsupportedEncodingException e)
1418                 {
1419                     if (Log.isDebugEnabled())
1420                         Log.warn(e);
1421                     else
1422                         Log.warn(e.toString());
1423                 }
1424             }
1425 
1426         }
1427 
1428         // handle any _content.
1429         String encoding = getCharacterEncoding();
1430         String content_type = getContentType();
1431         if (content_type != null && content_type.length() > 0)
1432         {
1433             content_type = HttpFields.valueParameters(content_type, null);
1434             
1435             if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && 
1436                     (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod())))
1437             {
1438                 int content_length = getContentLength();
1439                 if (content_length != 0)
1440                 {
1441                     try
1442                     {
1443                         int maxFormContentSize=-1;
1444                         
1445                         if (_context!=null)
1446                             maxFormContentSize=_context.getContextHandler().getMaxFormContentSize();
1447                         else
1448                         {
1449                             Integer size = (Integer)_connection.getConnector().getServer().getAttribute("org.mortbay.jetty.Request.maxFormContentSize");
1450                             if (size!=null)
1451                                 maxFormContentSize =size.intValue();
1452                         }
1453                         
1454                         if (content_length>maxFormContentSize && maxFormContentSize > 0)
1455                         {
1456                             throw new IllegalStateException("Form too large"+content_length+">"+maxFormContentSize);
1457                         }
1458                         InputStream in = getInputStream();
1459                        
1460                         // Add form params to query params
1461                         UrlEncoded.decodeTo(in, _baseParameters, encoding,content_length<0?maxFormContentSize:-1);
1462                     }
1463                     catch (IOException e)
1464                     {
1465                         if (Log.isDebugEnabled())
1466                             Log.warn(e);
1467                         else
1468                             Log.warn(e.toString());
1469                     }
1470                 }
1471             }
1472         }
1473         
1474         if (_parameters==null)
1475             _parameters=_baseParameters;
1476         else if (_parameters!=_baseParameters)
1477         {
1478             // Merge parameters (needed if parameters extracted after a forward).
1479             Iterator iter = _baseParameters.entrySet().iterator();
1480             while (iter.hasNext())
1481             {
1482                 Map.Entry entry = (Map.Entry)iter.next();
1483                 String name=(String)entry.getKey();
1484                 Object values=entry.getValue();
1485                 for (int i=0;i<LazyList.size(values);i++)
1486                     _parameters.add(name, LazyList.get(values, i));
1487             }
1488         }   
1489     }
1490     
1491     /* ------------------------------------------------------------ */
1492     /**
1493      * @param host The host to set.
1494      */
1495     public void setServerName(String host)
1496     {
1497         _serverName = host;
1498     }
1499     
1500     /* ------------------------------------------------------------ */
1501     /**
1502      * @param port The port to set.
1503      */
1504     public void setServerPort(int port)
1505     {
1506         _port = port;
1507     }
1508     
1509     /* ------------------------------------------------------------ */
1510     /**
1511      * @param addr The address to set.
1512      */
1513     public void setRemoteAddr(String addr)
1514     {
1515         _remoteAddr = addr;
1516     }
1517     
1518     /* ------------------------------------------------------------ */
1519     /**
1520      * @param host The host to set.
1521      */
1522     public void setRemoteHost(String host)
1523     {
1524         _remoteHost = host;
1525     }
1526     
1527     /* ------------------------------------------------------------ */
1528     /**
1529      * @return Returns the uri.
1530      */
1531     public HttpURI getUri()
1532     {
1533         return _uri;
1534     }
1535     
1536     /* ------------------------------------------------------------ */
1537     /**
1538      * @param uri The uri to set.
1539      */
1540     public void setUri(HttpURI uri)
1541     {
1542         _uri = uri;
1543     }
1544     
1545     /* ------------------------------------------------------------ */
1546     /**
1547      * @return Returns the connection.
1548      */
1549     public HttpConnection getConnection()
1550     {
1551         return _connection;
1552     }
1553     
1554     /* ------------------------------------------------------------ */
1555     /**
1556      * @return Returns the inputState.
1557      */
1558     public int getInputState()
1559     {
1560         return _inputState;
1561     }
1562     
1563     /* ------------------------------------------------------------ */
1564     /**
1565      * @param authType The authType to set.
1566      */
1567     public void setAuthType(String authType)
1568     {
1569         _authType = authType;
1570     }
1571     
1572     /* ------------------------------------------------------------ */
1573     /**
1574      * @param cookies The cookies to set.
1575      */
1576     public void setCookies(Cookie[] cookies)
1577     {
1578         _cookies = cookies;
1579     }
1580     
1581     /* ------------------------------------------------------------ */
1582     /**
1583      * @param method The method to set.
1584      */
1585     public void setMethod(String method)
1586     {
1587         _method = method;
1588     }
1589     
1590     /* ------------------------------------------------------------ */
1591     /**
1592      * @param pathInfo The pathInfo to set.
1593      */
1594     public void setPathInfo(String pathInfo)
1595     {
1596         _pathInfo = pathInfo;
1597     }
1598     
1599     /* ------------------------------------------------------------ */
1600     /**
1601      * @param protocol The protocol to set.
1602      */
1603     public void setProtocol(String protocol)
1604     {
1605         _protocol = protocol;
1606     }
1607     
1608     /* ------------------------------------------------------------ */
1609     /**
1610      * @param requestedSessionId The requestedSessionId to set.
1611      */
1612     public void setRequestedSessionId(String requestedSessionId)
1613     {
1614         _requestedSessionId = requestedSessionId;
1615     }
1616     
1617     /* ------------------------------------------------------------ */
1618     /**
1619      * @return Returns the sessionManager.
1620      */
1621     public SessionManager getSessionManager()
1622     {
1623         return _sessionManager;
1624     }
1625     
1626     /* ------------------------------------------------------------ */
1627     /**
1628      * @param sessionManager The sessionManager to set.
1629      */
1630     public void setSessionManager(SessionManager sessionManager)
1631     {
1632         _sessionManager = sessionManager;
1633     }
1634     
1635     /* ------------------------------------------------------------ */
1636     /**
1637      * @param requestedSessionIdCookie The requestedSessionIdCookie to set.
1638      */
1639     public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie)
1640     {
1641         _requestedSessionIdFromCookie = requestedSessionIdCookie;
1642     }
1643     
1644     /* ------------------------------------------------------------ */
1645     /**
1646      * @param session The session to set.
1647      */
1648     public void setSession(HttpSession session)
1649     {
1650         _session = session;
1651     }
1652     
1653     /* ------------------------------------------------------------ */
1654     /**
1655      * @param scheme The scheme to set.
1656      */
1657     public void setScheme(String scheme)
1658     {
1659         _scheme = scheme;
1660     }
1661     
1662     /* ------------------------------------------------------------ */
1663     /**
1664      * @param queryString The queryString to set.
1665      */
1666     public void setQueryString(String queryString)
1667     {
1668         _queryString = queryString;
1669     }
1670     /* ------------------------------------------------------------ */
1671     /**
1672      * @param requestURI The requestURI to set.
1673      */
1674     public void setRequestURI(String requestURI)
1675     {
1676         _requestURI = requestURI;
1677     }
1678     /* ------------------------------------------------------------ */
1679     /**
1680      * Sets the "context path" for this request
1681      * @see HttpServletRequest#getContextPath
1682      */
1683     public void setContextPath(String contextPath)
1684     {
1685         _contextPath = contextPath;
1686     }
1687     
1688     /* ------------------------------------------------------------ */
1689     /**
1690      * @param servletPath The servletPath to set.
1691      */
1692     public void setServletPath(String servletPath)
1693     {
1694         _servletPath = servletPath;
1695     }
1696     
1697     /* ------------------------------------------------------------ */
1698     /**
1699      * @param name The servletName to set.
1700      */
1701     public void setServletName(String name)
1702     {
1703         _servletName = name;
1704     }
1705     
1706     /* ------------------------------------------------------------ */
1707     /**
1708      * @param userPrincipal The userPrincipal to set.
1709      */
1710     public void setUserPrincipal(Principal userPrincipal)
1711     {
1712         _userPrincipal = userPrincipal;
1713     }
1714 
1715     /* ------------------------------------------------------------ */
1716     /**
1717      * @param context
1718      */
1719     public void setContext(SContext context)
1720     {
1721         _context=context;
1722     }
1723 
1724     /* ------------------------------------------------------------ */
1725     /**
1726      * @return The current {@link SContext context} used for this request, or <code>null</code> if {@link #setContext} has not yet
1727      * been called. 
1728      */
1729     public SContext getContext()
1730     {
1731         return _context;
1732     }
1733     
1734     /* ------------------------------------------------------------ */
1735     /**
1736      * Reconstructs the URL the client used to make the request. The returned URL contains a
1737      * protocol, server name, port number, and, but it does not include a path.
1738      * <p>
1739      * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the
1740      * URL easily, for example, to append path and query parameters.
1741      * 
1742      * This method is useful for creating redirect messages and for reporting errors.
1743      * 
1744      * @return "scheme://host:port"
1745      */
1746     public StringBuffer getRootURL()
1747     {
1748         StringBuffer url = new StringBuffer(48);
1749         synchronized (url)
1750         {
1751             String scheme = getScheme();
1752             int port = getServerPort();
1753 
1754             url.append(scheme);
1755             url.append("://");
1756             url.append(getServerName());
1757             
1758             if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443)))
1759             {
1760                 url.append(':');
1761                 url.append(port);
1762             }
1763             return url;
1764         }
1765     }
1766 
1767     /* ------------------------------------------------------------ */
1768     /* 
1769      */
1770     public Attributes getAttributes()
1771     {
1772         if (_attributes==null)
1773             _attributes=new AttributesMap();
1774         return _attributes;
1775     }
1776     
1777     /* ------------------------------------------------------------ */
1778     /* 
1779      */
1780     public void setAttributes(Attributes attributes)
1781     {
1782         _attributes=attributes;
1783     }
1784 
1785     /* ------------------------------------------------------------ */
1786     public Continuation getContinuation()
1787     {
1788         return _continuation;
1789     }
1790     
1791     /* ------------------------------------------------------------ */
1792     public Continuation getContinuation(boolean create)
1793     {
1794         if (_continuation==null && create)
1795             _continuation=getConnection().getConnector().newContinuation();
1796         return _continuation;
1797     }
1798     
1799     /* ------------------------------------------------------------ */
1800     void setContinuation(Continuation cont)
1801     {
1802         _continuation=cont;
1803     }
1804 
1805     /* ------------------------------------------------------------ */
1806     /**
1807      * @return Returns the parameters.
1808      */
1809     public MultiMap getParameters()
1810     {
1811         return _parameters;
1812     }
1813 
1814     /* ------------------------------------------------------------ */
1815     /**
1816      * @param parameters The parameters to set.
1817      */
1818     public void setParameters(MultiMap parameters)
1819     {
1820         _parameters= (parameters==null)?_baseParameters:parameters;
1821         if (_paramsExtracted && _parameters==null)
1822             throw new IllegalStateException();
1823     }
1824     
1825     /* ------------------------------------------------------------ */
1826     public String toString()
1827     {
1828         return getMethod()+" "+_uri+" "+getProtocol()+"\n"+
1829         _connection.getRequestFields().toString();
1830     }
1831 
1832     /* ------------------------------------------------------------ */
1833     public static Request getRequest(HttpServletRequest request)
1834     {
1835         if (request instanceof Request)
1836             return (Request) request;
1837         
1838         while (request instanceof ServletRequestWrapper)
1839             request = (HttpServletRequest)((ServletRequestWrapper)request).getRequest();
1840         
1841         if (request instanceof Request)
1842             return (Request) request;
1843         
1844         return HttpConnection.getCurrentConnection().getRequest();
1845     }
1846     
1847 
1848     /* ------------------------------------------------------------ */
1849     public synchronized void addEventListener(EventListener listener) 
1850     {
1851         if (listener instanceof ServletRequestAttributeListener)
1852             _requestAttributeListeners= LazyList.add(_requestAttributeListeners, listener);
1853     }
1854     
1855     /* ------------------------------------------------------------ */
1856     public synchronized void removeEventListener(EventListener listener) 
1857     {
1858         _requestAttributeListeners= LazyList.remove(_requestAttributeListeners, listener);
1859     }
1860 
1861     /* ------------------------------------------------------------ */
1862     public void saveNewSession(Object key,HttpSession session)
1863     {
1864         if (_savedNewSessions==null)
1865             _savedNewSessions=new HashMap();
1866         _savedNewSessions.put(key,session);
1867     }
1868     /* ------------------------------------------------------------ */
1869     public HttpSession recoverNewSession(Object key)
1870     {
1871         if (_savedNewSessions==null)
1872             return null;
1873         return (HttpSession) _savedNewSessions.get(key);
1874     }
1875 
1876     /* ------------------------------------------------------------ */
1877     /**
1878      * @return Returns the userRealm.
1879      */
1880     public UserRealm getUserRealm()
1881     {
1882         return _userRealm;
1883     }
1884 
1885     /* ------------------------------------------------------------ */
1886     /**
1887      * @param userRealm The userRealm to set.
1888      */
1889     public void setUserRealm(UserRealm userRealm)
1890     {
1891         _userRealm = userRealm;
1892     }
1893 
1894     /* ------------------------------------------------------------ */
1895     public String getQueryEncoding()
1896     {
1897         return _queryEncoding;
1898     }
1899 
1900     /* ------------------------------------------------------------ */
1901     /** Set the character encoding used for the query string.
1902      * This call will effect the return of getQueryString and getParamaters.
1903      * It must be called before any geParameter methods.
1904      * 
1905      * The request attribute "org.mortbay.jetty.Request.queryEncoding"
1906      * may be set as an alternate method of calling setQueryEncoding.
1907      * 
1908      * @param queryEncoding
1909      */
1910     public void setQueryEncoding(String queryEncoding)
1911     {
1912         _queryEncoding=queryEncoding;
1913         _queryString=null;
1914     }
1915 
1916     /* ------------------------------------------------------------ */
1917     public void setRoleMap(Map map)
1918     {
1919         _roleMap=map;
1920     }
1921 
1922     /* ------------------------------------------------------------ */
1923     public Map getRoleMap()
1924     {
1925         return _roleMap;
1926     }
1927     
1928     /* ------------------------------------------------------------ */
1929     public ServletContext getServletContext()
1930     {
1931         return _context;
1932     }
1933 
1934     /* ------------------------------------------------------------ */
1935     public ServletResponse getServletResponse()
1936     {
1937         return _connection.getResponse();
1938     }
1939 }
1940