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

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

Webmaster