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