Annotation of java/classes/org/w3c/jigsaw/servlet/JigsawHttpServletRequest.java, revision 1.31
1.1 abaird 1: // JigsawHttpServletRequest.java
1.31 ! bmahe 2: // $Id: JigsawHttpServletRequest.java,v 1.30 1998/06/04 16:48:17 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.*;
10:
1.8 bmahe 11: import javax.servlet.*;
12: import javax.servlet.http.*;
1.1 abaird 13:
1.16 bmahe 14: import org.w3c.util.*;
15: import org.w3c.jigsaw.http.*;
16: import org.w3c.jigsaw.forms.URLDecoder;
17: import org.w3c.jigsaw.forms.URLDecoderException;
18: import org.w3c.www.http.*;
19: import org.w3c.www.mime.*;
20: import org.w3c.jigsaw.auth.AuthFilter; // for auth infos access
1.2 abaird 21:
1.16 bmahe 22: import org.w3c.tools.resources.*;
1.14 bmahe 23:
1.6 abaird 24: class HeaderNames implements Enumeration {
1.18 bmahe 25: // The HeaderDescription enumeration
26: Enumeration e = null;
1.6 abaird 27:
1.18 bmahe 28: public boolean hasMoreElements() {
29: return e.hasMoreElements();
30: }
31:
32: public Object nextElement() {
33: HeaderDescription d = (HeaderDescription) e.nextElement();
34: return d.getName();
35: }
36:
37: HeaderNames(Enumeration e) {
38: this.e = e ;
39: }
1.6 abaird 40:
41: }
42:
1.2 abaird 43: /**
44: * @author Alexandre Rafalovitch <alex@access.com.au>
45: * @author Anselm Baird-Smith <abaird@w3.org>
1.12 bmahe 46: * @author Benoit Mahe <bmahe@sophia.inria.fr>
1.2 abaird 47: */
1.1 abaird 48:
49: public class JigsawHttpServletRequest implements HttpServletRequest {
1.9 bmahe 50:
1.25 bmahe 51: /**
52: * The InputStream state codes.
53: */
54:
55: /**
56: * The initial state of the request InputStream
57: */
1.18 bmahe 58: private final static int STREAM_STATE_INITIAL = 0;
1.25 bmahe 59:
60: /**
61: * One reader has been created and is probably used.
62: */
1.18 bmahe 63: private final static int STREAM_READER_USED = 1;
1.25 bmahe 64:
65: /**
66: * The input stream is used
67: */
1.18 bmahe 68: private final static int INPUT_STREAM_USED = 2;
69:
1.25 bmahe 70: /**
71: * The inputstream state
72: */
1.18 bmahe 73: private int stream_state = STREAM_STATE_INITIAL;
74:
75: public final static
76: String STATE_PARAMETERS = "org.w3c.jigsaw.servlet.stateParam";
77:
78: private static MimeType type = MimeType.APPLICATION_X_WWW_FORM_URLENCODED ;
79: /**
80: * The initial request.
81: */
82: private Request request = null;
83: /**
84: * The attached servlet.
85: */
86: private Servlet servlet = null;
87: /**
88: * The lazyly computed queryParameters hashtable.
89: */
90: private Hashtable queryParameters = null;
91:
1.25 bmahe 92: protected JigsawHttpServletResponse response = null;
93:
94: protected JigsawHttpSession httpSession = null;
95:
1.29 bmahe 96: protected JigsawHttpSessionContext sessionContext = null;
1.25 bmahe 97:
98: protected String requestedSessionID = null;
99:
1.18 bmahe 100: private synchronized void prepareQueryParameters()
101: {
102: if( queryParameters != null )
103: return;
104: // What kinf of parameters are we expecting ?
105: if ( request.getMethod().equals("POST") ) {
106: // POSTed parameters, check content type:
107: if ((! request.hasContentType())
108: || (type.match(request.getContentType()) < 0) )
109: return;
110: // Get and decode the request entity:
111: URLDecoder dec = null;
112: try {
113: InputStream in = request.getInputStream() ;
114: // Notify the client that we are willing to continue
115: Client client = request.getClient();
116: if ( client != null )
117: client.sendContinue();
118: dec = new URLDecoder (in, false);
119: queryParameters = dec.parse () ;
120: } catch (URLDecoderException e) {
121: queryParameters = null;
122: } catch (IOException ex) {
123: queryParameters = null;
124: }
125: } else {
126: // URL encoded parameters:
127: String query = request.getQueryString();
128: if (query != null) {
129: InputStream qis = new StringBufferInputStream(query);
130: try {
131: queryParameters = new URLDecoder(qis, false).parse();
132: } catch (Exception ex) {
133: throw new RuntimeException("Java implementation bug.");
134: }
135: }
136: }
137: // state parameters
138: Hashtable param = (Hashtable)request.getState(STATE_PARAMETERS);
139: if (param != null) {
140: if (queryParameters == null)
141: queryParameters = param;
142: else {
143: Enumeration e= param.keys();
144: while (e.hasMoreElements()) {
145: String name = (String)e.nextElement();
146: Object value = queryParameters.get(name);
147: if (value == null)
148: queryParameters.put(name,param.get(name));
149: else if (value instanceof String[]) {
150: String oldValues [] = (String[])value;
151: String newValues [] = new String[oldValues.length+1];
152: System.arraycopy(oldValues,0,newValues,0,
153: oldValues.length);
154: newValues[oldValues.length] = (String)param.get(name);
155: queryParameters.put(name,newValues);
156: } else {
157: String newValues [] = new String[2];
158: newValues[0] = (String)param.get(name);
159: newValues[1] = (String)value;
160: queryParameters.put(name,newValues);
161: }
162: }
163: }
164: }
165: }
166:
1.31 ! bmahe 167: protected String getURLParameter(String name) {
! 168: Hashtable urlParameters = null;
! 169: String query = request.getQueryString();
! 170: if (query != null) {
! 171: InputStream qis = new StringBufferInputStream(query);
! 172: try {
! 173: urlParameters = new URLDecoder(qis, false).parse();
! 174: return (String) urlParameters.get(name);
! 175: } catch (Exception ex) {
! 176: throw new RuntimeException("Java implementation bug.");
! 177: }
! 178: }
! 179: return null;
! 180: }
1.18 bmahe 181:
182: /**
183: * Return the Charset parameter of content type
184: * @return A String instance
185: */
186: public String getCharacterEncoding() {
187: org.w3c.www.mime.MimeType type = request.getContentType();
188: if ((type != null) && (type.hasParameter("charset"))) {
189: return type.getParameterValue("charset");
190: }
1.19 bmahe 191: return "ISO-8859-1";
1.18 bmahe 192: }
193:
194: /**
195: * ServletRequest implementation - Get the length of request data.
196: * @return An int, or <strong>-1</strong>.
197: */
198:
199: public int getContentLength()
200: {
201: return request.getContentLength();
202: }
203:
204: /**
205: * ServletRequest implementation - Get the type of the request's body.
206: * @return A String encoded mime type, or <strong>null</strong>.
207: */
208:
209: public String getContentType()
210: {
211: org.w3c.www.mime.MimeType t = request.getContentType();
212: return (t == null) ? null : t.toString();
213: }
214:
215: /**
216: * ServletRequest implementation - Get the protocol of that request.
217: * @return A String encoded version of the protocol.
218: */
219:
220: public String getProtocol()
221: {
222: return request.getVersion();
223: }
224:
225: /**
226: * ServletRequest implementation - Get the name of queried server.
227: * @return Name of server, as a String.
228: */
229:
230: public String getServerName()
231: {
232: return request.getClient().getServer().getHost();
233: }
234:
235: /**
236: * ServletRequest implementation - Get the port of queried server.
237: * @return A port number (int).
238: */
239:
240: public int getServerPort()
241: {
242: return request.getClient().getServer().getLocalPort();
243: }
244:
245: /**
246: * ServletRequest implementation - Get the IP address of requests's sender.
247: * @return Numeric IP address, as a String.
248: */
249:
250: public String getRemoteAddr()
251: {
252: return request.getClient().getInetAddress().getHostAddress();
253: }
254:
255: /**
256: * ServletRequest implementation - FQDN of request's sender.
257: * @return Name of client's machine (FQDN).
258: */
259:
260: public String getRemoteHost()
261: {
262: return request.getClient().getInetAddress().getHostName();
263: }
264:
265: /**
266: * ServletRequest implementation - Get real path.
267: * Jigsaw realy has no notion of <em>translation</em> stricto
268: * sensu (it has much better in fact ;-). This is a pain here.
269: * @return Always <strong>null</strong>.
270: */
271:
272: public String getRealPath(String name) {
273: return null;
274: }
275:
276: /**
277: * ServletRequest interface - Get the input stream to read data.
278: * @return An input stream instance (may be <strong>null</strong>).
279: */
280:
281: protected ServletInputStream is = null;
282: public ServletInputStream getInputStream()
283: throws IOException
284: {
285: if (stream_state == STREAM_READER_USED)
286: throw new IllegalStateException("Reader used");
287: stream_state = INPUT_STREAM_USED;
288: return getJigsawInputStream();
289: }
290:
291: protected ServletInputStream getJigsawInputStream()
292: throws IOException
293: {
294: // If alredy computed return:
295: if ( is != null )
296: return is;
297: // Built it:
298: InputStream stream = null;
299: if ((stream = request.getInputStream()) == null)
300: stream = new ContentLengthInputStream(null, 0);
301: return is = new JigsawServletInputStream(stream);
302: }
303:
304: /**
305: * ServletRequest implementation - Get a parameter value.
306: * @return The String encoded value for the parameter.
307: */
308:
309: public String getParameter(String name)
310: {
311: prepareQueryParameters();
312: if ( queryParameters != null ) {
313: Object value = queryParameters.get(name);
314: if (value instanceof String[])
315: return ((String[])value)[0];
316: else return (String)value;
317: }
318: else
319: return null;
320: }
321:
322: /**
323: * ServletRequest implementation - Get the parameters value.
324: * @return The String array encoded value for the parameter.
325: */
326:
327: public String[] getParameterValues(String parameter) {
328: Vector V = new Vector(23);
329: prepareQueryParameters();
330: if (queryParameters == null)
331: return null;
332: Object value = queryParameters.get(parameter);
333: if (value == null) return null;
334: if (value instanceof String[])
335: return (String[])value;
336: else {
337: String [] parameterValues = new String[1];
338: parameterValues[0] = (String)value;
339: return parameterValues;
340: }
341: }
342:
343: /**
344: * ServletRequest implementation - List available parameters.
345: * @return An enumeration of parameter names.
346: */
347:
348: public Enumeration getParameterNames()
349: {
350: prepareQueryParameters();
351: return ((queryParameters == null)
352: ? new EmptyEnumeration()
353: : queryParameters.keys());
354: }
355:
356: /**
357: * ServletRequest implementation - Get an attribute of the request.
358: * This closely match Jigsaw's notion of request state.
359: * @param name The name of the attribute.
360: * @return An object that gives the value of the attribute.
361: */
362:
363: public Object getAttribute(String name) {
364: return request.getState(name);
365: }
366:
367: /**
368: * HttpServletRequest implementation - Get the request's method.
369: * @return A String instance.
370: */
371:
372: public String getMethod()
373: {
374: return request.getMethod();
375: }
376:
377: /**
378: * HttpServletRequest implementation - Get the request's path info.
379: * @return A String instance or <strong>null</strong>.
380: */
381:
382: public String getPathInfo()
383: {
384: return (String) request.getState(ServletWrapperFrame.STATE_EXTRA_PATH);
385: }
386:
387: /**
388: * HttpServletRequest implementation - Get the request's path translated.
389: * @return A String instance or <strong>null</strong>.
390: */
391:
392: public String getPathTranslated()
393: {
394: String pathinfo = getPathInfo();
395: if ( pathinfo != null ) {
396: httpd server = request.getClient().getServer();
397: ResourceReference rr_root = server.getRootReference();
398: try {
399: LookupState ls = new LookupState(pathinfo);
400: LookupResult lr = new LookupResult(rr_root);
401: ResourceReference path = null;
402:
403: try {
404: FramedResource root = (FramedResource) rr_root.lock();
405: if (root.lookup(ls,lr))
406: path = lr.getTarget();
407: } catch (InvalidResourceException ex) {
408: path = null;
409: } finally {
410: rr_root.unlock();
411: }
412:
413: if (path != null) {
414: try {
415: Resource r = path.lock();
416: if (r instanceof FileResource)
417: return ((FileResource)
418: r).getFile().getAbsolutePath();
419: else if (r instanceof DirectoryResource)
420: return ((DirectoryResource)
421: r).getDirectory().getAbsolutePath();
422: else return null;
423: } catch (InvalidResourceException ex) {
424: return null;
425: } finally {
426: path.unlock();
427: }
428: }
429: } catch (org.w3c.tools.resources.ProtocolException ex) {
430: return null;
431: }
432: }
433: return null;
434: }
435:
436: /**
437: * HttpServletRequest implementation - Get the request's query string.
438: * @return A String instance or <strong>null</strong>.
439: */
440:
441: public String getQueryString()
442: {
443: return request.getQueryString();
444: }
445:
446: /**
447: * HttpServletRequest implementation - Get the request's user (if any).
448: * @return A String instance or <strong>null</strong>.
449: */
450:
451: public String getRemoteUser()
452: {
453: return (String) request.getState(AuthFilter.STATE_AUTHUSER);
454: }
455:
456: /**
457: * HttpServletRequest implementation - Get the request's auth method.
458: * @return A String instance or <strong>null</strong>.
459: */
460:
461: public String getAuthType() {
462: return (String) request.getState(AuthFilter.STATE_AUTHTYPE);
463: }
464:
465: /**
466: * HttpServletRequest implementation - Get a request header as a String.
467: * @return A String instance or <strong>null</strong>.
468: */
469:
470: public String getHeader(String name) {
471: return request.getValue(name);
472: }
473:
474: /**
475: * HttpServletRequest implementation - Get a request header as an int.
476: * @return An int, or <strong>-1</strong>.
477: */
478:
479: public int getIntHeader(String name) {
480: HeaderValue v = request.getHeaderValue(name);
481: if ( v != null ) {
482: Object o = v.getValue();
483: if ((o != null) && (o instanceof Integer))
484: return ((Integer) o).intValue();
1.1 abaird 485: }
1.18 bmahe 486: return -1;
1.1 abaird 487: }
1.18 bmahe 488:
489: /**
490: * HttpServletRequest implementation - Get a request header as an date.
491: * @return An long (as a number of milliseconds), or <strong>-1</strong>.
492: */
493:
494: public long getDateHeader(String name) {
495: HeaderValue v = request.getHeaderValue(name, null);
496: if ( v != null ) {
497: Object o = v.getValue();
498: if ((o != null) && (o instanceof Long))
499: return ((Long) o).longValue();
1.10 bmahe 500: }
1.18 bmahe 501: return (long) -1;
1.1 abaird 502: }
1.8 bmahe 503:
1.18 bmahe 504: /**
505: * HttpServletRequest implementation - Get a all header names.
506: * @return An enumeration.
507: */
508:
509: public Enumeration getHeaderNames() {
510: return new HeaderNames(request.enumerateHeaderDescriptions());
511: }
1.16 bmahe 512:
1.25 bmahe 513: /**
514: * Gets, from the first line of the HTTP request,
515: * the part of this request's URI that is to the left of any query string.
516: */
1.18 bmahe 517: public String getRequestURI()
518: {
519: return request.getURL().toExternalForm();
520: }
521:
522: public String getRequestPath()
523: {
524: return request.getURLPath();
525: }
526:
1.25 bmahe 527: /**
528: * Gets the part of this request's URI that refers to the servlet
529: * being invoked. Analogous to the CGI variable SCRIPT_NAME.
530: */
1.18 bmahe 531: public String getServletPath()
532: {
533: ResourceReference rr = request.getTargetResource();
1.16 bmahe 534: try {
1.18 bmahe 535: return rr.lock().getURLPath();
1.16 bmahe 536: } catch (InvalidResourceException ex) {
1.18 bmahe 537: return null;
1.16 bmahe 538: } finally {
1.18 bmahe 539: rr.unlock();
1.16 bmahe 540: }
1.18 bmahe 541: }
542:
1.25 bmahe 543: /**
544: * @return the scheme of the URL used in this request, for example "http",
545: * "https", or "ftp". Different schemes have different rules
546: * for constructing URLs, as noted in RFC 1738. The URL used to create
547: * a request may be reconstructed using this scheme, the server name
548: * and port, and additional information such as URIs.
549: */
1.18 bmahe 550: public String getScheme() {
551: return request.getURL().getProtocol();
552: }
1.16 bmahe 553:
1.25 bmahe 554: /**
555: * Gets the array of cookies found in this request.
556: * @return the array of cookies found in this request
557: */
1.18 bmahe 558: public Cookie[] getCookies() {
1.19 bmahe 559: HttpCookieList cookielist = request.getCookie();
560: HttpCookie[] cookies = cookielist.getCookies();
561: Cookie[] Scookies = new Cookie[cookies.length];
562: for (int i = 0 ; i < cookies.length ; i++ ) {
563: Scookies[i] = convertCookie(cookies[i]);
564: }
565: return Scookies;
566: }
567:
568: protected Cookie convertCookie(HttpCookie httpCookie) {
569: Cookie cookie = new Cookie(httpCookie.getName(),
570: httpCookie.getValue());
571: cookie.setDomain(httpCookie.getDomain());
572: cookie.setPath(httpCookie.getPath());
573: cookie.setVersion(httpCookie.getVersion());
574: return cookie;
575: }
576:
1.28 bmahe 577: protected String getCookieName() {
1.29 bmahe 578: return "JIGSAW-SESSION-ID";
1.28 bmahe 579: }
580:
1.19 bmahe 581: protected String getRequestedSessionIdFromCookie() {
582: HttpCookieList cookielist = request.getCookie();
583: if (cookielist != null) {
584: HttpCookie httpCookie =
1.28 bmahe 585: request.getCookie().getCookie(getCookieName());
1.19 bmahe 586: if (httpCookie != null)
587: return httpCookie.getValue();
588: }
1.18 bmahe 589: return null;
590: }
1.19 bmahe 591:
1.31 ! bmahe 592: protected String getRequestedSessionIdFromURL() {
! 593: return getURLParameter(getCookieName());
! 594: }
! 595:
1.25 bmahe 596: /**
597: * Gets the session id specified with this request. This may differ
598: * from the actual session id. For example, if the request specified an
599: * id for an invalid session, then this will get a new session with a
600: * new id.
601: * @return the session id specified by this request, or null if the
602: * request did not specify a session id.
603: */
1.18 bmahe 604: public String getRequestedSessionId() {
1.31 ! bmahe 605: if (requestedSessionID == null) {
1.27 bmahe 606: requestedSessionID = getRequestedSessionIdFromCookie();
1.31 ! bmahe 607: if (requestedSessionID == null)
! 608: requestedSessionID = getRequestedSessionIdFromURL();
! 609: }
1.19 bmahe 610: return requestedSessionID;
611: }
612:
613: protected synchronized JigsawHttpSessionContext getSessionContext() {
614: return sessionContext;
1.15 benoit 615: }
1.14 bmahe 616:
1.25 bmahe 617: /**
618: * Gets the current valid session associated with this request, if create
619: * is false or, if necessary, creates a new session for the request, if
620: * create is true.
621: * @return the session associated with this request or null if create
622: * was false and no valid session is associated with this request.
623: */
1.18 bmahe 624: public HttpSession getSession(boolean create) {
1.19 bmahe 625: if (httpSession == null) {
1.27 bmahe 626: httpSession = (JigsawHttpSession)
627: getSession(getRequestedSessionId());
1.29 bmahe 628: if (httpSession != null) // the client join the session
629: httpSession.setNoMoreNew();
1.27 bmahe 630: }
631: if (httpSession == null & create) {
632: httpSession = new JigsawHttpSession(getSessionContext(),
633: createCookie());
634: response.addCookie(httpSession.getCookie());
635: } else if (httpSession != null) {
636: httpSession.setLastAccessedTime();
637: if (! httpSession.isValid()) {
1.19 bmahe 638: httpSession = new JigsawHttpSession(getSessionContext(),
639: createCookie());
640: response.addCookie(httpSession.getCookie());
641: }
642: }
643: return httpSession;
644: }
645:
646: protected Cookie createCookie() {
1.28 bmahe 647: Cookie cookie = new Cookie(getCookieName(), null);
648: cookie.setPath("/");
1.30 bmahe 649: cookie.setMaxAge(86400); // one day
1.19 bmahe 650: return cookie;
651: }
652:
653: protected HttpSession getSession(String sessionId) {
654: if (sessionId != null)
655: return getSessionContext().getSession(sessionId);
1.18 bmahe 656: return null;
657: }
1.17 bmahe 658:
1.25 bmahe 659: /**
660: * Checks whether this request is associated with a session that is valid
661: * in the current session context. If it is not valid, the requested
662: * session will never be returned from the getSession method.
663: * @return true if this request is assocated with a session that is valid
664: * in the current session context.
665: */
1.18 bmahe 666: public boolean isRequestedSessionIdValid() {
1.27 bmahe 667: JigsawHttpSession session = (JigsawHttpSession)
668: getSession(getRequestedSessionId());
1.19 bmahe 669: if (session == null)
670: return false;
671: return (session.isValid());
1.18 bmahe 672: }
673:
1.25 bmahe 674: /**
675: * Checks whether the session id specified by this request came in as
676: * a cookie. (The requested session may not be one returned by the
677: * getSession method.)
678: * @return true if the session id specified by this request came
679: * in as a cookie; false otherwise
680: */
1.18 bmahe 681: public boolean isRequestedSessionIdFromCookie() {
1.29 bmahe 682: return (getRequestedSessionIdFromCookie() != null);
1.18 bmahe 683: }
684:
1.25 bmahe 685: /**
686: * Checks whether the session id specified by this request came in as
687: * part of the URL. (The requested session may not be the one returned
688: * by the getSession method.)
689: * @return true if the session id specified by the request for this
690: * session came in as part of the URL; false otherwise
691: */
1.18 bmahe 692: public boolean isRequestedSessionIdFromUrl() {
1.31 ! bmahe 693: return (getRequestedSessionIdFromURL() != null);
1.18 bmahe 694: }
695:
696: protected BufferedReader reader = null;
1.25 bmahe 697:
698: /**
699: * @return a buffered reader for reading text in the request body.
700: * This translates character set encodings as appropriate.
701: */
1.18 bmahe 702: public BufferedReader getReader()
703: throws IOException
704: {
705: if (stream_state == INPUT_STREAM_USED)
706: throw new IllegalStateException("Input Stream used");
707: stream_state = STREAM_READER_USED;
708: if (reader == null) {
709: reader = new BufferedReader(
710: new InputStreamReader( getJigsawInputStream()));
711: }
712: return reader;
1.19 bmahe 713: }
714:
715: JigsawHttpServletRequest(Servlet servlet,
716: Request request,
1.29 bmahe 717: JigsawHttpServletResponse response,
718: JigsawHttpSessionContext sessionContext) {
719: this.servlet = servlet;
720: this.request = request;
721: this.response = response;
722: this.sessionContext = sessionContext;
1.17 bmahe 723: }
724:
1.1 abaird 725: }
Webmaster