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