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