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

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

Webmaster