View Javadoc

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