Annotation of java/classes/org/w3c/jigsaw/servlet/JigsawHttpServletRequest.java, revision 1.57

1.1       abaird      1: // JigsawHttpServletRequest.java
1.57    ! ylafon      2: // $Id: JigsawHttpServletRequest.java,v 1.56 2000/08/16 13:40:00 bmahe Exp $
1.1       abaird      3: // (c) COPYRIGHT MIT and INRIA, 1996.
                      4: // Please first read the full copyright statement in file COPYRIGHT.html
                      5: 
1.16      bmahe       6: package org.w3c.jigsaw.servlet;
1.1       abaird      7: 
1.57    ! ylafon      8: import java.io.BufferedReader;
        !             9: import java.io.IOException;
        !            10: import java.io.InputStream;
        !            11: import java.io.InputStreamReader;
        !            12: import java.io.Reader;
        !            13: import java.io.StringReader;
        !            14: import java.io.UnsupportedEncodingException;
        !            15: 
        !            16: import java.util.Enumeration;
        !            17: import java.util.Hashtable;
        !            18: import java.util.Locale;
        !            19: import java.util.Vector;
        !            20: 
1.47      bmahe      21: import java.security.Principal;
1.1       abaird     22: 
1.57    ! ylafon     23: import javax.servlet.RequestDispatcher;
        !            24: import javax.servlet.Servlet;
        !            25: import javax.servlet.ServletInputStream;
        !            26: 
        !            27: import javax.servlet.http.Cookie;
        !            28: import javax.servlet.http.HttpServletRequest;
        !            29: import javax.servlet.http.HttpSession;
        !            30: 
        !            31: import org.w3c.util.ArrayEnumeration;
        !            32: import org.w3c.util.EmptyEnumeration;
        !            33: import org.w3c.util.ObservableProperties;
        !            34: 
        !            35: import org.w3c.jigsaw.http.Client;
        !            36: import org.w3c.jigsaw.http.Request;
        !            37: import org.w3c.jigsaw.http.httpd;
1.1       abaird     38: 
1.16      bmahe      39: import org.w3c.jigsaw.forms.URLDecoder;
                     40: import org.w3c.jigsaw.forms.URLDecoderException;
1.46      bmahe      41: import org.w3c.jigsaw.resources.VirtualHostResource;
1.57    ! ylafon     42: 
        !            43: import org.w3c.www.http.ContentLengthInputStream;
        !            44: import org.w3c.www.http.HeaderDescription;
        !            45: import org.w3c.www.http.HeaderValue;
        !            46: import org.w3c.www.http.HttpAcceptLanguage;
        !            47: import org.w3c.www.http.HttpCookie;
        !            48: import org.w3c.www.http.HttpCookieList;
        !            49: import org.w3c.www.http.HttpEntityMessage;
        !            50: import org.w3c.www.http.HttpMessage;
        !            51: import org.w3c.www.http.HttpRequestMessage;
        !            52: 
        !            53: import org.w3c.www.mime.MimeType;
        !            54: 
1.16      bmahe      55: import org.w3c.jigsaw.auth.AuthFilter; // for auth infos access
1.2       abaird     56: 
1.57    ! ylafon     57: import org.w3c.tools.resources.InvalidResourceException;
        !            58: import org.w3c.tools.resources.Resource;
        !            59: import org.w3c.tools.resources.ResourceReference;
1.14      bmahe      60: 
1.6       abaird     61: class HeaderNames implements Enumeration {
1.18      bmahe      62:     // The HeaderDescription enumeration
                     63:     Enumeration e = null;
1.6       abaird     64: 
1.18      bmahe      65:     public boolean hasMoreElements() {
                     66:        return e.hasMoreElements();
                     67:     }
                     68: 
                     69:     public Object nextElement() {
                     70:        HeaderDescription d = (HeaderDescription) e.nextElement();
                     71:        return d.getName();
                     72:     }
                     73: 
                     74:     HeaderNames(Enumeration e) {
                     75:        this.e = e ;
                     76:     }
1.6       abaird     77: 
                     78: }
                     79: 
1.2       abaird     80: /**
                     81:  *  @author Alexandre Rafalovitch <alex@access.com.au>
                     82:  *  @author Anselm Baird-Smith <abaird@w3.org>
1.12      bmahe      83:  *  @author Benoit Mahe <bmahe@sophia.inria.fr>
1.2       abaird     84:  */
1.1       abaird     85: 
                     86: public class JigsawHttpServletRequest implements HttpServletRequest {
1.9       bmahe      87: 
1.25      bmahe      88:     /**
                     89:      * The InputStream state codes.
                     90:      */
                     91: 
                     92:     /**
                     93:      * The initial state of the request InputStream 
                     94:      */
1.18      bmahe      95:     private final static int STREAM_STATE_INITIAL = 0;
1.25      bmahe      96: 
                     97:     /**
                     98:      * One reader has been created and is probably used.
                     99:      */
1.18      bmahe     100:     private final static int STREAM_READER_USED = 1;
1.25      bmahe     101: 
                    102:     /**
                    103:      * The input stream is used
                    104:      */
1.18      bmahe     105:     private final static int INPUT_STREAM_USED = 2;
                    106: 
1.25      bmahe     107:     /**
                    108:      * The inputstream state
                    109:      */
1.18      bmahe     110:     private int stream_state = STREAM_STATE_INITIAL;
                    111: 
                    112:     public final static 
                    113:        String STATE_PARAMETERS = "org.w3c.jigsaw.servlet.stateParam";
                    114: 
                    115:     private static MimeType type = MimeType.APPLICATION_X_WWW_FORM_URLENCODED ;
                    116:     /** 
                    117:      * The initial request.
                    118:      */
                    119:     private Request request = null;
                    120:     /**
                    121:      * The attached servlet.
                    122:      */
                    123:     private Servlet servlet = null;
                    124:     /**
                    125:      * The lazyly computed queryParameters hashtable.
                    126:      */
                    127:     private Hashtable queryParameters = null;
                    128: 
1.25      bmahe     129:     protected JigsawHttpServletResponse response = null;
                    130: 
                    131:     protected JigsawHttpSession httpSession = null;
                    132: 
1.29      bmahe     133:     protected JigsawHttpSessionContext sessionContext = null;
1.25      bmahe     134: 
                    135:     protected String requestedSessionID = null;
                    136: 
1.45      bmahe     137:     private Hashtable mergeParameters(Hashtable source, Hashtable dest) {
                    138:        if (source == null)
                    139:            return dest;
                    140:        if (dest != null) {
                    141:            Enumeration e = source.keys();
                    142:            while (e.hasMoreElements()) {
                    143:                String name = (String)e.nextElement();
                    144:                Object value = dest.get(name);
                    145:                if (value == null)
                    146:                    dest.put(name, source.get(name));
                    147:                else  if (value instanceof String[]) {
                    148:                    String oldValues [] = (String[])value;
                    149:                    String newValues [] = new String[oldValues.length+1];
                    150:                    System.arraycopy(oldValues,0,newValues,0,
                    151:                                     oldValues.length);
                    152:                    newValues[oldValues.length] = (String)source.get(name);
                    153:                    dest.put(name,newValues);
                    154:                } else {
                    155:                    String newValues [] = new String[2];
                    156:                    newValues[0] = (String)source.get(name);
                    157:                    newValues[1] = (String)value;
                    158:                    dest.put(name,newValues);
                    159:                }
                    160:            }
                    161:            return dest;
                    162:        } else {
                    163:            return source;
                    164:        }
                    165:     }
                    166: 
                    167:     private synchronized void prepareQueryParameters() {
1.18      bmahe     168:        if( queryParameters != null )
                    169:            return;
1.45      bmahe     170:        Hashtable postParameters = null;
1.18      bmahe     171:        // What kinf of parameters are we expecting ?
                    172:        if ( request.getMethod().equals("POST") ) {
1.45      bmahe     173:            postParameters = new Hashtable(2);
1.18      bmahe     174:            // POSTed parameters, check content type:
                    175:            if ((! request.hasContentType())
                    176:                || (type.match(request.getContentType()) < 0) ) 
                    177:                return;
                    178:            // Get and decode the request entity:
                    179:            URLDecoder dec = null;
                    180:            try {
                    181:                InputStream in = request.getInputStream() ;
                    182:                // Notify the client that we are willing to continue
                    183:                Client client = request.getClient();
                    184:                if ( client != null ) 
                    185:                    client.sendContinue();
                    186:                dec = new URLDecoder (in, false);
1.45      bmahe     187:                postParameters = dec.parse () ;
1.18      bmahe     188:            } catch (URLDecoderException e) {
1.45      bmahe     189:                postParameters = null;
1.18      bmahe     190:            } catch (IOException ex) {
1.45      bmahe     191:                postParameters = null;
1.18      bmahe     192:            }
1.45      bmahe     193:        }
                    194:        // URL encoded parameters:
1.52      bmahe     195:        String query = getQueryString();
1.45      bmahe     196:        if (query != null) {
                    197:            Reader qis = new StringReader(query);
                    198:            try {
                    199:                queryParameters = new URLDecoder(qis, false).parse();
                    200:            } catch (Exception ex) {
                    201:                throw new RuntimeException("Java implementation bug.");
1.18      bmahe     202:            }
                    203:        }
1.45      bmahe     204:        queryParameters = mergeParameters(postParameters, queryParameters);
1.18      bmahe     205:        // state parameters
                    206:        Hashtable param = (Hashtable)request.getState(STATE_PARAMETERS);
1.45      bmahe     207:        queryParameters = mergeParameters(param, queryParameters);
1.18      bmahe     208:     }
                    209: 
1.31      bmahe     210:     protected String getURLParameter(String name) {
                    211:        Hashtable urlParameters = null;
1.52      bmahe     212:        String query = getQueryString();
1.31      bmahe     213:        if (query != null) {
1.42      bmahe     214:            Reader qis = new StringReader(query);
1.31      bmahe     215:            try {
                    216:                urlParameters = new URLDecoder(qis, false).parse();
                    217:                return (String) urlParameters.get(name);
                    218:            } catch (Exception ex) {
                    219:                throw new RuntimeException("Java implementation bug.");
                    220:            }
                    221:        }
                    222:        return null;
                    223:     }
1.18      bmahe     224: 
                    225:     /**
                    226:      * Return the Charset parameter of content type
                    227:      * @return A String instance
                    228:      */
                    229:     public String getCharacterEncoding() {
                    230:        org.w3c.www.mime.MimeType type = request.getContentType();
                    231:        if ((type != null) && (type.hasParameter("charset"))) {
                    232:            return type.getParameterValue("charset");
                    233:        }
1.19      bmahe     234:        return "ISO-8859-1";
1.18      bmahe     235:     }
                    236: 
                    237:     /**
                    238:      * ServletRequest implementation - Get the length of request data.
                    239:      * @return An int, or <strong>-1</strong>.
                    240:      */
                    241: 
1.52      bmahe     242:     public int getContentLength() {
1.18      bmahe     243:        return request.getContentLength();
                    244:     }
                    245: 
                    246:     /**
                    247:      * ServletRequest implementation - Get the type of the request's body.
                    248:      * @return A String encoded mime type, or <strong>null</strong>.
                    249:      */
                    250: 
1.52      bmahe     251:     public String getContentType() {
1.18      bmahe     252:        org.w3c.www.mime.MimeType t = request.getContentType();
                    253:        return (t == null) ? null : t.toString();
                    254:     }
1.57    ! ylafon    255: 
1.18      bmahe     256:     /**
                    257:      * ServletRequest implementation - Get the protocol of that request.
                    258:      * @return A String encoded version of the protocol.
                    259:      */
                    260: 
1.52      bmahe     261:     public String getProtocol() {
1.18      bmahe     262:        return request.getVersion();
                    263:     }
1.57    ! ylafon    264: 
1.47      bmahe     265:     protected httpd getServer() {
                    266:        return request.getClient().getServer();
                    267:     }
                    268: 
1.18      bmahe     269:    /**
                    270:     * ServletRequest implementation - Get the name of queried server.
                    271:     * @return Name of server, as a String.
                    272:     */
                    273: 
1.52      bmahe     274:    public String getServerName() {
                    275:        String host = request.getHost();
1.53      bmahe     276:        if (host != null) {
                    277:           int idx = host.lastIndexOf(':');
                    278:           if (idx != -1) {
                    279:               return host.substring(0, host.lastIndexOf(':'));
                    280:           } else {
                    281:               return host;
                    282:           }
                    283:        } else {
1.52      bmahe     284:           return getServer().getHost();
1.53      bmahe     285:        }
1.18      bmahe     286:    }
                    287: 
                    288:    /**
                    289:     * ServletRequest implementation - Get the port of queried server.
                    290:     * @return A port number (int).
                    291:     */
                    292: 
1.52      bmahe     293:    public int getServerPort() {
1.39      bmahe     294:        if (request.isProxy()) {
                    295:           String host = request.getHost();
                    296:           if (host != null) {
                    297:               int idx = host.lastIndexOf(':');
                    298:               if (idx == -1)
                    299:                   return 80;
                    300:               return Integer.parseInt(host.substring(idx+1));
                    301:           }
                    302:        }
1.47      bmahe     303:        return getServer().getLocalPort();
1.18      bmahe     304:    }
                    305: 
                    306:    /**
                    307:     * ServletRequest implementation - Get the IP address of requests's sender.
                    308:     * @return Numeric IP address, as a String.
                    309:     */
                    310: 
1.52      bmahe     311:     public String getRemoteAddr() {
1.18      bmahe     312:        return request.getClient().getInetAddress().getHostAddress();
                    313:     }
                    314: 
                    315:     /**
                    316:      * ServletRequest implementation - FQDN of request's sender.
                    317:      * @return Name of client's machine (FQDN).
                    318:      */
                    319: 
1.52      bmahe     320:     public String getRemoteHost() {
1.18      bmahe     321:        return request.getClient().getInetAddress().getHostName();
                    322:     }
                    323: 
                    324:     /**
                    325:      * ServletRequest implementation - Get real path.
                    326:      * Jigsaw realy has no notion of <em>translation</em> stricto
                    327:      * sensu (it has much better in fact ;-). This is a pain here.
1.46      bmahe     328:      * @return the real path.
1.42      bmahe     329:      * @deprecated since jsdk1.2
1.18      bmahe     330:      */
                    331: 
                    332:     public String getRealPath(String name) {
1.47      bmahe     333:        httpd             server  = getServer();
1.46      bmahe     334:        ResourceReference rr_root = server.getRootReference();
1.50      bmahe     335:        return JigsawServletContext.getRealPath(name, 
                    336:                                                rr_root, 
                    337:                                                request.getTargetResource());
1.18      bmahe     338:     }
                    339: 
1.32      bmahe     340:     protected ServletInputStream is = null;
                    341: 
1.18      bmahe     342:     /**
1.32      bmahe     343:      * Returns an input stream for reading binary data in the request body. 
                    344:      * @exception IllegalStateException if getReader has been called on 
                    345:      * this same request. 
                    346:      * @exception IOException on other I/O related errors. 
1.41      ylafon    347:      * @see JigsawHttpServletRequest#getReader
1.32      bmahe     348:      */    
1.18      bmahe     349:     public ServletInputStream getInputStream()
                    350:        throws IOException
                    351:     {
                    352:        if (stream_state == STREAM_READER_USED)
                    353:            throw new IllegalStateException("Reader used");
                    354:        stream_state = INPUT_STREAM_USED;
                    355:        return getJigsawInputStream();
                    356:     }
1.57    ! ylafon    357: 
1.37      bmahe     358:     /**
1.38      bmahe     359:      * @exception IOException if an IO error occurs
1.37      bmahe     360:      */ 
1.18      bmahe     361:     protected ServletInputStream getJigsawInputStream()
                    362:        throws IOException
                    363:     {
                    364:        // If alredy computed return:
                    365:        if ( is != null )
                    366:            return is;
                    367:        // Built it:
                    368:        InputStream stream = null;
                    369:        if ((stream = request.getInputStream()) == null)
                    370:            stream = new ContentLengthInputStream(null, 0);
                    371:        return is = new JigsawServletInputStream(stream);
                    372:     }
                    373: 
                    374:     /**
                    375:      * ServletRequest implementation - Get a parameter value.
                    376:      * @return The String encoded value for the parameter.
                    377:      */
                    378: 
1.52      bmahe     379:     public String getParameter(String name) {
1.18      bmahe     380:        prepareQueryParameters();
                    381:        if ( queryParameters != null ) {
                    382:            Object value = queryParameters.get(name);
                    383:            if (value instanceof String[])
                    384:                return ((String[])value)[0];
                    385:            else return (String)value;
                    386:        }
                    387:        else
                    388:            return null;
                    389:     }
                    390: 
                    391:     /**
                    392:      * ServletRequest implementation - Get the parameters value.
                    393:      * @return The String array encoded value for the parameter.
                    394:      */
1.57    ! ylafon    395: 
1.18      bmahe     396:     public String[] getParameterValues(String parameter) {
                    397:        Vector V = new Vector(23);
                    398:        prepareQueryParameters();
                    399:        if (queryParameters == null) 
                    400:            return null;
                    401:        Object value = queryParameters.get(parameter);
                    402:        if (value == null) return null;
                    403:        if (value instanceof String[])
                    404:            return (String[])value;
                    405:        else {
                    406:            String [] parameterValues = new String[1];
                    407:            parameterValues[0] = (String)value;
                    408:            return parameterValues;
                    409:        }
                    410:     }
                    411: 
                    412:     /**
                    413:      * ServletRequest implementation - List available parameters.
                    414:      * @return An enumeration of parameter names.
                    415:      */
1.57    ! ylafon    416: 
1.52      bmahe     417:     public Enumeration getParameterNames() {
1.18      bmahe     418:        prepareQueryParameters();
                    419:        return ((queryParameters == null)
                    420:                ? new EmptyEnumeration()
                    421:                : queryParameters.keys());
                    422:     }
                    423: 
                    424:     /**
                    425:      * ServletRequest implementation - Get an attribute of the request.
                    426:      * This closely match Jigsaw's notion of request state.
                    427:      * @param name The name of the attribute.
                    428:      * @return An object that gives the value of the attribute.
                    429:      */
                    430: 
                    431:     public Object getAttribute(String name) {
                    432:        return request.getState(name);
                    433:     }
                    434: 
1.42      bmahe     435:     public void setAttribute(String name, Object object) {
                    436:        request.setState(name, object);
                    437:     }
                    438: 
1.47      bmahe     439:     /**
                    440:      * Removes an attribute from this request.  This method is not
                    441:      * generally needed as attributes only persist as long as the request
                    442:      * is being handled.
                    443:      *
                    444:      * <p>Attribute names should follow the same conventions as
                    445:      * package names. Names beginning with <code>java.*</code>,
                    446:      * <code>javax.*</code>, and <code>com.sun.*</code>, are
                    447:      * reserved for use by Sun Microsystems.
                    448:      *
                    449:      * @param name a <code>String</code> specifying 
                    450:      * the name of the attribute to remove
                    451:      */
                    452:     public void removeAttribute(String name) {
                    453:        request.delState(name);
                    454:     }
                    455: 
1.42      bmahe     456:     public Enumeration getAttributeNames() {
                    457:        return request.getStateNames();
                    458:     }
                    459: 
1.18      bmahe     460:     /**
1.47      bmahe     461:      * Returns the preferred <code>Locale</code> that the client will 
                    462:      * accept content in, based on the Accept-Language header.
                    463:      * If the client request doesn't provide an Accept-Language header,
                    464:      * this method returns the default locale for the server.
                    465:      *
                    466:      * @return the preferred <code>Locale</code> for the client
                    467:      */
                    468:     public Locale getLocale() {
                    469:        return (Locale)getLocales().nextElement();
                    470:     }
1.57    ! ylafon    471: 
1.47      bmahe     472:     /**
                    473:      * Returns an <code>Enumeration</code> of <code>Locale</code> objects
                    474:      * indicating, in decreasing order starting with the preferred locale, the
                    475:      * locales that are acceptable to the client based on the Accept-Language
                    476:      * header.
                    477:      * If the client request doesn't provide an Accept-Language header,
                    478:      * this method returns an <code>Enumeration</code> containing one 
                    479:      * <code>Locale</code>, the default locale for the server.
                    480:      *
                    481:      * @return an <code>Enumeration</code> of preferred 
                    482:      * <code>Locale</code> objects for the client
                    483:      */
                    484:     public Enumeration getLocales() {
                    485:        HttpAcceptLanguage languages[] = request.getAcceptLanguage();
                    486:        if (languages == null) {
                    487:            Vector def = new Vector();
                    488:             def.addElement(Locale.getDefault());
                    489:             return def.elements();
                    490:        }
                    491: 
1.48      bmahe     492:        //LinkedList is better, but we must be JDK1.1 compliant
                    493:        Vector locales = new Vector(); 
1.47      bmahe     494: 
                    495:        for (int i = 0 ; i < languages.length ; i++) {
                    496:            HttpAcceptLanguage language = languages[i];
                    497:            double quality = language.getQuality();
                    498:            String lang    = language.getLanguage();
                    499:            String country = "";
                    500:            int    idx     = lang.indexOf('-');
                    501:            if (idx > -1) {
                    502:                country = lang.substring(idx + 1).trim();
                    503:                lang    = lang.substring(0, idx).trim();
                    504:            }
                    505:            // insert the Locale in ordered list
1.48      bmahe     506:            int     qidx = 0;
                    507:            int     size = locales.size();
                    508:            if (size > 0) {
                    509:                QLocale ql   = (QLocale) locales.firstElement();
                    510:                while ((qidx < size) && (ql.getLanguageQuality() >= quality)) {
                    511:                    try {
                    512:                        ql = (QLocale) locales.elementAt(++qidx);
                    513:                    } catch (ArrayIndexOutOfBoundsException ex) {
                    514:                        //end of vector, so append
                    515:                    }
                    516:                }
                    517:                locales.insertElementAt(new QLocale(lang, country, quality),
                    518:                                        qidx);
                    519:            } else {
                    520:                locales.addElement(new QLocale(lang, country, quality));
1.47      bmahe     521:            }
                    522:        }
                    523:        // because Locale is final :(
                    524:        int    size    = locales.size(); 
                    525:        Vector vlocale = new Vector(size);
                    526:        for (int i = 0 ; i < size ; i ++) {
1.48      bmahe     527:            vlocale.addElement(((QLocale)locales.elementAt(i)).getLocale());
1.47      bmahe     528:        }
                    529:        return vlocale.elements();
                    530:     }
                    531: 
                    532:     /**
                    533:      * Returns a boolean indicating whether this request was made using a
                    534:      * secure channel, such as HTTPS.
                    535:      *
                    536:      * @return a boolean indicating if the request was made using a
                    537:      * secure channel
                    538:      */
                    539: 
                    540:     public boolean isSecure() {
                    541:        // only https secure?
                    542:        return (request.getURL().getProtocol().equalsIgnoreCase("https"));
                    543:     }
1.57    ! ylafon    544: 
1.47      bmahe     545:     /**
1.18      bmahe     546:      * HttpServletRequest implementation - Get the request's method.
                    547:      * @return A String instance.
                    548:      */
                    549: 
1.52      bmahe     550:     public  String getMethod() {
1.18      bmahe     551:        return request.getMethod();
                    552:     }
                    553: 
                    554:     /**
                    555:      * HttpServletRequest implementation - Get the request's path info.
                    556:      * @return A String instance or <strong>null</strong>.
                    557:      */
                    558: 
1.52      bmahe     559:     public  String getPathInfo() {
                    560:        if (request.hasState(JigsawRequestDispatcher.PATH_INFO_P)) {
                    561:            String pathinfo = 
                    562:                (String) request.getState(JigsawRequestDispatcher.PATH_INFO_P);
                    563:            return (pathinfo.equals("/")) ? null : pathinfo;
1.50      bmahe     564:        }
1.52      bmahe     565:        return null;
1.18      bmahe     566:     }
1.57    ! ylafon    567: 
1.18      bmahe     568:     /**
                    569:      * HttpServletRequest implementation - Get the request's path translated.
                    570:      * @return A String instance or <strong>null</strong>.
                    571:      */
1.57    ! ylafon    572: 
1.52      bmahe     573:     public  String getPathTranslated() {
1.18      bmahe     574:        String pathinfo = getPathInfo();
1.46      bmahe     575:        if ( pathinfo != null )
                    576:            return getRealPath(pathinfo);
1.18      bmahe     577:        return null;
                    578:     }
                    579: 
                    580:     /**
1.47      bmahe     581:      * Returns the portion of the request URI that indicates the context
                    582:      * of the request.  The context path always comes first in a request
                    583:      * URI.  The path starts with a "/" character but does not end with a "/"
                    584:      * character.  For servlets in the default (root) context, this method
                    585:      * returns "".
                    586:      * @return a <code>String</code> specifying the portion of the request 
                    587:      * URI that indicates the context of the request
                    588:      */
                    589:     public String getContextPath() {
1.56      bmahe     590:        return "";
1.47      bmahe     591:     }
                    592: 
1.52      bmahe     593:     public boolean hasQueryString() {
1.54      bmahe     594:        if (request.hasQueryString()) {
1.52      bmahe     595:            return true;
                    596:        } else {
1.54      bmahe     597:            return request.hasState(JigsawRequestDispatcher.QUERY_STRING_P);
1.52      bmahe     598:        }
                    599:     }
                    600: 
1.47      bmahe     601:     /**
1.18      bmahe     602:      * HttpServletRequest implementation - Get the request's query string.
                    603:      * @return A String instance or <strong>null</strong>.
                    604:      */
1.52      bmahe     605:     public String getQueryString() {
1.54      bmahe     606:        if (request.hasQueryString()) {
                    607:            return request.getQueryString();
                    608:        } else if (request.hasState(JigsawRequestDispatcher.QUERY_STRING_P)) {
1.52      bmahe     609:            return (String) 
                    610:                request.getState(JigsawRequestDispatcher.QUERY_STRING_P);
                    611:        }
1.54      bmahe     612:        return null;
1.18      bmahe     613:     }
1.57    ! ylafon    614: 
1.18      bmahe     615:     /**
                    616:      * HttpServletRequest implementation - Get the request's user (if any).
                    617:      * @return A String instance or <strong>null</strong>.
                    618:      */
                    619: 
1.52      bmahe     620:     public String getRemoteUser() {
1.18      bmahe     621:        return (String) request.getState(AuthFilter.STATE_AUTHUSER);
                    622:     }
1.57    ! ylafon    623: 
1.18      bmahe     624:     /**
1.47      bmahe     625:      * Returns a boolean indicating whether the authenticated user is included
                    626:      * in the specified logical "role".  Roles and role membership can be
                    627:      * defined using deployment descriptors.  If the user has not been
                    628:      * authenticated, the method returns <code>false</code>.
                    629:      *
                    630:      * @param role a <code>String</code> specifying the name of the role
                    631:      * @return a <code>boolean</code> indicating whether the user making this
                    632:      * request belongs to a given role; <code>false</code> if the user has not
                    633:      * been authenticated
                    634:      */
                    635: 
                    636:     public boolean isUserInRole(String role) {
                    637:        throw new RuntimeException("Not Yet Implemented");
                    638:     }
                    639: 
                    640:     /**
                    641:      * Returns a <code>java.security.Principal</code> object containing
                    642:      * the name of the current authenticated user. If the user has not been
                    643:      * authenticated, the method returns <code>null</code>.
                    644:      *
                    645:      * @return a <code>java.security.Principal</code> containing
                    646:      * the name of the user making this request; <code>null</code> if the 
                    647:      * user has not been authenticated
                    648:      */
                    649:     public Principal getUserPrincipal() {
                    650:        return new PrincipalImpl(getRemoteUser());
                    651:     }
                    652: 
                    653:     /**
1.18      bmahe     654:      * HttpServletRequest implementation - Get the request's auth method.
                    655:      * @return A String instance or <strong>null</strong>.
                    656:      */
                    657: 
                    658:     public String getAuthType() {
                    659:        return (String) request.getState(AuthFilter.STATE_AUTHTYPE);
                    660:     }
                    661: 
                    662:     /**
                    663:      * HttpServletRequest implementation - Get a request header as a String.
                    664:      * @return A String instance or <strong>null</strong>.
                    665:      */
                    666: 
                    667:     public String getHeader(String name) {
                    668:        return request.getValue(name);
                    669:     }
                    670: 
                    671:     /**
1.47      bmahe     672:      * Returns all the values of the specified request header
                    673:      * as an <code>Enumeration</code> of <code>String</code> objects.
                    674:      *
                    675:      * <p>Some headers, such as <code>Accept-Language</code> can be sent
                    676:      * by clients as several headers each with a different value rather than
                    677:      * sending the header as a comma separated list.
                    678:      *
                    679:      * <p>WARNING, this can't happen with Jigsaw, all multiple values are
                    680:      * grouped in one, and only one, header. So, this method always return 
                    681:      * ONE header value.
                    682:      *
                    683:      * <p>If the request did not include any headers
                    684:      * of the specified name, this method returns an empty
                    685:      * <code>Enumeration</code>.
                    686:      * The header name is case insensitive. You can use
                    687:      * this method with any request header.
                    688:      *
                    689:      * @param name a <code>String</code> specifying the header name
                    690:      * @return a <code>Enumeration</code> containing the values of the 
                    691:      * requested header, or <code>null</code> if the request does not
                    692:      * have any headers of that name
                    693:      */                        
                    694: 
                    695:     public Enumeration getHeaders(String name) {
                    696:        String value = getHeader(name);
                    697:        String array[] = { value };
                    698:        return new ArrayEnumeration(array);
                    699:     }
                    700: 
                    701:     /**
1.18      bmahe     702:      * HttpServletRequest implementation - Get a request header as an int.
                    703:      * @return An int, or <strong>-1</strong>.
                    704:      */
                    705: 
                    706:     public int getIntHeader(String name) {
                    707:        HeaderValue v = request.getHeaderValue(name);
                    708:        if ( v != null ) {
                    709:            Object o = v.getValue();
                    710:            if ((o != null) && (o instanceof Integer))
                    711:                return ((Integer) o).intValue();
1.1       abaird    712:        }
1.18      bmahe     713:        return -1;
1.1       abaird    714:     }
1.18      bmahe     715: 
                    716:     /**
                    717:      * HttpServletRequest implementation - Get a request header as an date.
                    718:      * @return An long (as a number of milliseconds), or <strong>-1</strong>.
                    719:      */
                    720: 
                    721:     public long getDateHeader(String name) {
                    722:        HeaderValue v = request.getHeaderValue(name, null);
                    723:        if ( v != null ) {
                    724:            Object o = v.getValue();
                    725:            if ((o != null) && (o instanceof Long)) 
                    726:                return ((Long) o).longValue();
1.10      bmahe     727:        }
1.18      bmahe     728:        return (long) -1;
1.1       abaird    729:     }
1.8       bmahe     730: 
1.18      bmahe     731:     /**
                    732:      * HttpServletRequest implementation - Get a all header names.
                    733:      * @return An enumeration.
                    734:      */
                    735: 
                    736:     public Enumeration getHeaderNames() {
                    737:        return new HeaderNames(request.enumerateHeaderDescriptions());
                    738:     }
1.16      bmahe     739: 
1.25      bmahe     740:     /**
                    741:      * Gets, from the first line of the HTTP request, 
                    742:      * the part of this request's URI that is to the left of any query string.
                    743:      */
1.55      bmahe     744:     public String getRequestURI() {
1.39      bmahe     745:        String uri = null;
1.52      bmahe     746:        if (request.hasState(JigsawRequestDispatcher.REQUEST_URI_P)) {
                    747:            uri = (String)
                    748:                request.getState(JigsawRequestDispatcher.REQUEST_URI_P);
1.39      bmahe     749:        } else {
1.52      bmahe     750:            //fixme test
                    751:            if (request.isProxy()) {
                    752:                uri = request.getURL().toExternalForm();
                    753:            } else {
                    754:                uri = request.getURLPath();
                    755:            }
                    756:            if (hasQueryString()) {
                    757:                String query = getQueryString();
                    758:                int idx = uri.lastIndexOf(query);
                    759:                uri = uri.substring(0, idx-1);
                    760:            }
1.39      bmahe     761:        }
                    762:        return uri;
1.18      bmahe     763:     }
1.57    ! ylafon    764: 
1.25      bmahe     765:     /**
1.47      bmahe     766:      * Returns a {@link RequestDispatcher} object that acts as a wrapper for
                    767:      * the resource located at the given path.  
                    768:      * A <code>RequestDispatcher</code> object can be used to forward
                    769:      * a request to the resource or to include the resource in a response.
                    770:      * The resource can be dynamic or static.
                    771:      *
                    772:      * <p>The pathname specified may be relative, although it cannot extend
                    773:      * outside the current servlet context.  If the path begins with 
                    774:      * a "/" it is interpreted as relative to the current context root.  
                    775:      * This method returns <code>null</code> if the servlet container
                    776:      * cannot return a <code>RequestDispatcher</code>.
                    777:      *
                    778:      * <p>The difference between this method and {@link
                    779:      * ServletContext#getRequestDispatcher} is that this method can take a
                    780:      * relative path.
                    781:      *
                    782:      * @param path a <code>String</code> specifying the pathname
                    783:      * to the resource
                    784:      * @return a <code>RequestDispatcher</code> object that acts as a 
                    785:      * wrapper for the resource at the specified path
                    786:      * @see RequestDispatcher
                    787:      * @see ServletContext#getRequestDispatcher
                    788:      */
                    789:     public RequestDispatcher getRequestDispatcher(String path) {
                    790:        if (path == null) {
                    791:            throw new IllegalArgumentException("null");
                    792:        }
1.52      bmahe     793:        String            urlpath = null;
                    794:        ResourceReference rr      = request.getTargetResource();
                    795:        if (! path.startsWith("/")) {
                    796:            String uri = null;
1.47      bmahe     797:            try {
1.52      bmahe     798:                ResourceReference rrp = rr.lock().getParent();
                    799:                try {
                    800:                    Resource r = rrp.lock();
                    801:                    uri = r.getURLPath();
                    802:                } catch (InvalidResourceException irex) {
                    803:                    return null;
                    804:                } finally {
                    805:                    rrp.unlock();
                    806:                }
                    807:            } catch (InvalidResourceException ex) {
1.47      bmahe     808:                return null;
                    809:            } finally {
1.52      bmahe     810:                rr.unlock();
1.47      bmahe     811:            }
1.52      bmahe     812:            urlpath = ( uri.endsWith("/") ? uri+path : uri+"/"+path );
                    813:        } else {
                    814:            urlpath = path;
1.47      bmahe     815:        }
                    816:        return JigsawRequestDispatcher.getRequestDispatcher(urlpath, 
1.52      bmahe     817:                                                            getServer(),
                    818:                                                            rr);
1.47      bmahe     819:     }
                    820: 
                    821:     /**
1.25      bmahe     822:      * Gets the part of this request's URI that refers to the servlet 
                    823:      * being invoked. Analogous to the CGI variable SCRIPT_NAME. 
                    824:      */
1.52      bmahe     825:     public String getServletPath() {
                    826:        if (request.hasState(JigsawRequestDispatcher.SERVLET_PATH_P)) {
                    827:            return (String)
                    828:                request.getState(JigsawRequestDispatcher.SERVLET_PATH_P);
                    829:        } else {
                    830:            ResourceReference rr = request.getTargetResource();
                    831:            try {
                    832:                return rr.lock().getURLPath();
                    833:            } catch (InvalidResourceException ex) {
                    834:                return null;
                    835:            } finally {
                    836:                rr.unlock();
                    837:            }
1.16      bmahe     838:        }
1.18      bmahe     839:     }
1.57    ! ylafon    840: 
1.25      bmahe     841:     /**
                    842:      * @return the scheme of the URL used in this request, for example "http",
                    843:      * "https", or "ftp". Different schemes have different rules
                    844:      * for constructing URLs, as noted in RFC 1738. The URL used to create 
                    845:      * a request may be reconstructed using this scheme, the server name 
                    846:      * and port, and additional information such as URIs.
                    847:      */
1.18      bmahe     848:     public String getScheme() {
                    849:        return request.getURL().getProtocol();
                    850:     }
1.16      bmahe     851: 
1.25      bmahe     852:     /**
                    853:      * Gets the array of cookies found in this request.
1.36      bmahe     854:      * @return the array of cookies found in this request or
                    855:      * <strong>null</strong> if there is no cookie.
1.25      bmahe     856:      */
1.18      bmahe     857:     public Cookie[] getCookies() {
1.19      bmahe     858:        HttpCookieList cookielist = request.getCookie();
1.36      bmahe     859:        Cookie[] Scookies = null;
                    860:        if (cookielist != null) {
                    861:            HttpCookie[] cookies = cookielist.getCookies();
                    862:            Scookies = new Cookie[cookies.length];
                    863:            for (int i = 0 ; i < cookies.length ; i++ ) {
                    864:                Scookies[i] = convertCookie(cookies[i]);
                    865:            }
1.19      bmahe     866:        }
                    867:        return Scookies;
                    868:     }
1.57    ! ylafon    869: 
1.19      bmahe     870:     protected Cookie convertCookie(HttpCookie httpCookie) {
                    871:        Cookie cookie = new Cookie(httpCookie.getName(),
                    872:                                   httpCookie.getValue());
1.40      bmahe     873:        String val = null;
                    874:        if ((val = httpCookie.getDomain()) != null)
                    875:            cookie.setDomain(val);
                    876:        if ((val = httpCookie.getPath()) != null)
                    877:            cookie.setPath(val);
1.19      bmahe     878:        cookie.setVersion(httpCookie.getVersion());
                    879:        return cookie;
                    880:     }
                    881: 
                    882:     protected String getRequestedSessionIdFromCookie() {
                    883:        HttpCookieList cookielist = request.getCookie();
                    884:        if (cookielist != null) {
                    885:            HttpCookie httpCookie = 
1.28      bmahe     886:                request.getCookie().getCookie(getCookieName());
1.19      bmahe     887:            if (httpCookie != null)
                    888:                return httpCookie.getValue();
                    889:        }
1.18      bmahe     890:        return null;
                    891:     }
1.19      bmahe     892: 
1.31      bmahe     893:     protected String getRequestedSessionIdFromURL() {
                    894:        return getURLParameter(getCookieName());
                    895:     }
                    896: 
1.25      bmahe     897:     /**
                    898:      * Gets the session id specified with this request. This may differ 
                    899:      * from the actual session id. For example, if the request specified an
                    900:      * id for an invalid session, then this will get a new session with a 
                    901:      * new id. 
                    902:      * @return the session id specified by this request, or null if the 
                    903:      * request did not specify a session id.
                    904:      */
1.18      bmahe     905:     public String getRequestedSessionId() {
1.31      bmahe     906:        if (requestedSessionID == null) {
1.27      bmahe     907:            requestedSessionID = getRequestedSessionIdFromCookie();
1.31      bmahe     908:            if (requestedSessionID == null)
                    909:                requestedSessionID = getRequestedSessionIdFromURL();
                    910:        }
1.19      bmahe     911:        return requestedSessionID;
                    912:     }
                    913: 
                    914:     protected synchronized JigsawHttpSessionContext getSessionContext() {
                    915:        return sessionContext;
1.15      benoit    916:     }
1.14      bmahe     917: 
1.25      bmahe     918:     /**
                    919:      * Gets the current valid session associated with this request, if create
                    920:      * is false or, if necessary, creates a new session for the request, if 
                    921:      * create is true. 
                    922:      * @return the session associated with this request or null if create 
                    923:      * was false and no valid session is associated with this request. 
                    924:      */
1.18      bmahe     925:     public HttpSession getSession(boolean create) {
1.19      bmahe     926:        if (httpSession == null) {
1.27      bmahe     927:            httpSession = (JigsawHttpSession)
                    928:                getSession(getRequestedSessionId());
1.29      bmahe     929:            if (httpSession != null) // the client join the session
                    930:                httpSession.setNoMoreNew();
1.27      bmahe     931:        }
                    932:        if (httpSession == null & create) {
                    933:            httpSession = new JigsawHttpSession(getSessionContext(), 
                    934:                                                createCookie());
                    935:            response.addCookie(httpSession.getCookie());
                    936:        } else if (httpSession != null) {
                    937:            httpSession.setLastAccessedTime();
                    938:            if (! httpSession.isValid()) {
1.19      bmahe     939:                httpSession = new JigsawHttpSession(getSessionContext(), 
                    940:                                                    createCookie());
                    941:                response.addCookie(httpSession.getCookie());
                    942:            }
                    943:        }
                    944:        return httpSession;
                    945:     }
                    946: 
1.42      bmahe     947:     /**
                    948:      * Gets the current valid session associated with this request.
                    949:      * @return the session associated with this request.
                    950:      */
                    951:     public HttpSession getSession() {
                    952:        return getSession(true);
                    953:     }
                    954: 
1.33      bmahe     955:     protected String getCookieName() {
                    956:         ObservableProperties props =
                    957:             request.getClient().getServer().getProperties();
                    958:         return props.getString(ServletProps.SERVLET_COOKIE_NAME,
                    959:                                ServletProps.DEFAULT_COOKIE_NAME);
                    960:     }
                    961: 
1.19      bmahe     962:     protected Cookie createCookie() {
1.33      bmahe     963:        ObservableProperties props = 
                    964:            request.getClient().getServer().getProperties();
1.34      bmahe     965:        String name     = props.getString(ServletProps.SERVLET_COOKIE_NAME,
                    966:                                          ServletProps.DEFAULT_COOKIE_NAME);
                    967:        String path     = props.getString(ServletProps.SERVLET_COOKIE_PATH,
                    968:                                          "/");
                    969:        String domain   = props.getString(ServletProps.SERVLET_COOKIE_DOMAIN,
1.35      bmahe     970:                                          null);
1.34      bmahe     971:        String comment  = props.getString(ServletProps.SERVLET_COOKIE_COMMENT,
                    972:                                          null);
                    973:        int maxage      = props.getInteger(ServletProps.SERVLET_COOKIE_MAXAGE,
                    974:                                           86400);
                    975:        boolean secure  = props.getBoolean(ServletProps.SERVLET_COOKIE_SECURE,
                    976:                                           false);
1.33      bmahe     977: 
                    978:        Cookie cookie = new Cookie(name, null);
                    979:        cookie.setPath(path);
                    980:        cookie.setMaxAge(maxage);
                    981:        if ((comment != null) && (comment.length() > 0))
                    982:            cookie.setComment(comment);
                    983:        if ((domain != null) && (domain.length() > 0))
                    984:            cookie.setDomain(domain);
                    985:        cookie.setSecure(secure);
1.19      bmahe     986:        return cookie;
                    987:     }
                    988: 
                    989:     protected HttpSession getSession(String sessionId) {
                    990:        if (sessionId != null)
                    991:            return getSessionContext().getSession(sessionId);
1.18      bmahe     992:        return null;
                    993:     }
1.57    ! ylafon    994: 
1.25      bmahe     995:     /**
                    996:      * Checks whether this request is associated with a session that is valid 
                    997:      * in the current session context. If it is not valid, the requested
                    998:      * session will never be returned from the getSession method. 
                    999:      * @return true if this request is assocated with a session that is valid 
                   1000:      * in the current session context. 
                   1001:      */
1.18      bmahe    1002:     public boolean isRequestedSessionIdValid() {
1.27      bmahe    1003:        JigsawHttpSession session = (JigsawHttpSession) 
                   1004:            getSession(getRequestedSessionId());
1.19      bmahe    1005:        if (session == null)
                   1006:            return false;
                   1007:        return (session.isValid());
1.18      bmahe    1008:     }
                   1009: 
1.25      bmahe    1010:     /**
                   1011:      * Checks whether the session id specified by this request came in as 
                   1012:      * a cookie. (The requested session may not be one returned by the 
                   1013:      * getSession method.)
                   1014:      * @return true if the session id specified by this request came 
                   1015:      * in as a cookie; false otherwise 
                   1016:      */
1.18      bmahe    1017:     public boolean isRequestedSessionIdFromCookie() {
1.29      bmahe    1018:        return (getRequestedSessionIdFromCookie() != null);
1.18      bmahe    1019:     }
                   1020: 
1.25      bmahe    1021:     /**
                   1022:      * Checks whether the session id specified by this request came in as 
                   1023:      * part of the URL. (The requested session may not be the one returned 
                   1024:      * by the getSession method.)
                   1025:      * @return true if the session id specified by the request for this 
                   1026:      * session came in as part of the URL; false otherwise
1.42      bmahe    1027:      * @deprecated since jsdk2.1
1.25      bmahe    1028:      */
1.18      bmahe    1029:     public boolean isRequestedSessionIdFromUrl() {
1.31      bmahe    1030:        return (getRequestedSessionIdFromURL() != null);
1.18      bmahe    1031:     }
                   1032: 
1.42      bmahe    1033:     /**
                   1034:      * Checks whether the session id specified by this request came in as 
                   1035:      * part of the URL. (The requested session may not be the one returned 
                   1036:      * by the getSession method.)
                   1037:      * @return true if the session id specified by the request for this 
                   1038:      * session came in as part of the URL; false otherwise
                   1039:      */
                   1040:     public boolean isRequestedSessionIdFromURL() {
                   1041:        return (getRequestedSessionIdFromURL() != null);
                   1042:     }
                   1043: 
1.18      bmahe    1044:     protected BufferedReader reader = null;
1.25      bmahe    1045: 
                   1046:     /**
1.32      bmahe    1047:      * Returns a buffered reader for reading text in the request body. 
1.25      bmahe    1048:      * This translates character set encodings as appropriate.
1.32      bmahe    1049:      * @exception UnsupportedEncodingException if the character set encoding 
                   1050:      * is unsupported, so the text can't be correctly decoded. 
                   1051:      * @exception IllegalStateException if getInputStream has been called on 
                   1052:      * this same request. 
                   1053:      * @exception IOException on other I/O related errors. 
1.41      ylafon   1054:      * @see JigsawHttpServletRequest#getInputStream 
1.25      bmahe    1055:      */
1.18      bmahe    1056:     public BufferedReader getReader()
                   1057:        throws IOException
                   1058:     {
                   1059:        if (stream_state == INPUT_STREAM_USED)
                   1060:            throw new IllegalStateException("Input Stream used");
                   1061:        stream_state = STREAM_READER_USED;
                   1062:        if (reader == null) {
1.43      ylafon   1063:            String enc[] = request.getContentEncoding();
1.44      ylafon   1064:            InputStream is = getJigsawInputStream();
1.43      ylafon   1065:            if (enc != null) {
                   1066:                InputStreamReader isr = null;
                   1067:                for (int i=0; i < enc.length; i++) {
                   1068:                    try {
                   1069:                        isr = new InputStreamReader(is, enc[i]);
                   1070:                        break;
                   1071:                    } catch (UnsupportedEncodingException ex) {
                   1072:                        // not a valid encoding, skip it
                   1073:                        isr = null;
                   1074:                    }
                   1075:                }
                   1076:                if (isr != null)
                   1077:                    reader = new BufferedReader(isr);
                   1078:                else
                   1079:                    reader = new BufferedReader(new InputStreamReader(is));
                   1080:            } else {
                   1081:                reader = new BufferedReader(new InputStreamReader(is)); 
                   1082:            }
1.18      bmahe    1083:        }
                   1084:        return reader;
1.42      bmahe    1085:     }
                   1086: 
                   1087:     /**
1.47      bmahe    1088:      * Get the wrapped Jigsaw Request.
                   1089:      * @return the request
1.42      bmahe    1090:      */
                   1091:     protected Request getRequest() {
                   1092:        return request;
1.19      bmahe    1093:     }
                   1094: 
                   1095:     JigsawHttpServletRequest(Servlet servlet, 
                   1096:                             Request request, 
1.29      bmahe    1097:                             JigsawHttpServletResponse response,
                   1098:                             JigsawHttpSessionContext sessionContext) {
                   1099:        this.servlet        = servlet;
                   1100:        this.request        = request;
                   1101:        this.response       = response;
                   1102:        this.sessionContext = sessionContext;
1.17      bmahe    1103:     }
                   1104: 
1.1       abaird   1105: }

Webmaster