View Javadoc

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