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