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