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