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