001: // RedirecterFrame.java
002: // $Id: RedirecterFrame.java,v 1.12 2002/09/13 16:40:55 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.frames;
007:
008: import java.net.MalformedURLException;
009: import java.net.URL;
010:
011: import org.w3c.tools.resources.Attribute;
012: import org.w3c.tools.resources.AttributeRegistry;
013: import org.w3c.tools.resources.LookupResult;
014: import org.w3c.tools.resources.LookupState;
015: import org.w3c.tools.resources.ProtocolException;
016: import org.w3c.tools.resources.ReplyInterface;
017: import org.w3c.tools.resources.RequestInterface;
018: import org.w3c.tools.resources.Resource;
019: import org.w3c.tools.resources.ResourceException;
020: import org.w3c.tools.resources.ResourceFrame;
021: import org.w3c.tools.resources.StringArrayAttribute;
022: import org.w3c.tools.resources.StringAttribute;
023:
024: import org.w3c.jigsaw.http.HTTPException;
025: import org.w3c.jigsaw.http.Reply;
026: import org.w3c.jigsaw.http.Request;
027: import org.w3c.jigsaw.http.httpd;
028:
029: import org.w3c.www.http.HTTP;
030: import org.w3c.www.http.HttpMessage;
031: import org.w3c.www.http.HttpRequestMessage;
032:
033: import org.w3c.tools.resources.ProtocolException;
034: import org.w3c.tools.resources.ResourceException;
035:
036: /**
037: * Perform an internal redirect.
038: */
039: public class RedirecterFrame extends HTTPFrame {
040: /**
041: * Name of the state to hold the PATH_INFO in the request.
042: */
043: public final static String PATH_INFO = "org.w3c.jigsaw.resources.RedirecterFrame.PathInfo";
044:
045: /**
046: * Attributes index - The index for the target attribute.
047: */
048: protected static int ATTR_TARGET = -1;
049: /**
050: * Attribute index - The methods affected by this frame
051: */
052: protected static int ATTR_METHODS = -1;
053:
054: static {
055: Attribute a = null;
056: Class cls = null;
057: // Get a pointer to our class:
058: try {
059: cls = Class
060: .forName("org.w3c.jigsaw.frames.RedirecterFrame");
061: } catch (Exception ex) {
062: ex.printStackTrace();
063: System.exit(1);
064: }
065: a = new StringAttribute("target", null, Attribute.EDITABLE);
066: ATTR_TARGET = AttributeRegistry.registerAttribute(cls, a);
067: // The affected methods
068: a = new StringArrayAttribute("methods", null,
069: Attribute.EDITABLE);
070: ATTR_METHODS = AttributeRegistry.registerAttribute(cls, a);
071: }
072:
073: /**
074: * Get the list of methods affected by the redirection
075: * @return An array of String giving the name of the redirected methods,
076: * or <strong>null</strong>, in wich case <em>all</em> methods are
077: * to be redirected.
078: */
079: public String[] getMethods() {
080: return (String[]) getValue(ATTR_METHODS, null);
081: }
082:
083: /**
084: * Get the location for the internal redirection
085: * @return a string, containing the relative path or absolute PATH.
086: */
087: protected String getTarget() {
088: return (String) getValue(ATTR_TARGET, null);
089: }
090:
091: /**
092: * Lookup the target resource when associated with an unknown resource.
093: * @param ls The current lookup state
094: * @param lr The result
095: * @return true if lookup is done.
096: * @exception ProtocolException If an error relative to the protocol occurs
097: */
098: protected boolean lookupResource(LookupState ls, LookupResult lr)
099: throws ProtocolException {
100: String methods[] = getMethods();
101:
102: if (ls.hasRequest() && (methods != null)) {
103: Request request = (Request) ls.getRequest();
104: String reqmeth = request.getMethod();
105: boolean affected = false;
106: for (int i = 0; i < methods.length; i++) {
107: if (reqmeth.equals(methods[i])) {
108: affected = true;
109: break;
110: }
111: }
112: if (!affected) {
113: return super .lookupResource(ls, lr);
114: }
115: }
116: // Perform our super-class lookup strategy:
117: if (super .lookupOther(ls, lr)) {
118: return true;
119: }
120: // Compute PATH INFO, store it as a piece of state in the request:
121: StringBuffer pathinfo = new StringBuffer();
122: while (ls.hasMoreComponents()) {
123: pathinfo.append('/');
124: pathinfo.append(ls.getNextComponent());
125: }
126: if (ls.hasRequest()) {
127: Request request = (Request) ls.getRequest();
128: String reqfile = request.getURL().getFile();
129: if (reqfile.endsWith("/")) {
130: pathinfo.append('/');
131: }
132: request.setState(PATH_INFO, pathinfo.toString());
133: }
134: lr.setTarget(resource.getResourceReference());
135: return true;
136: }
137:
138: /**
139: * Perform the request.
140: * @param req The request to handle.
141: * @exception ProtocolException If request couldn't be processed.
142: * @exception ResourceException If the resource got a fatal error.
143: */
144: public ReplyInterface perform(RequestInterface req)
145: throws ProtocolException, ResourceException {
146: Reply reply = (Reply) performFrames(req);
147: if (reply != null)
148: return reply;
149: Request request = (Request) req;
150: // check if we must use our parent perform call
151: String methods[] = getMethods();
152:
153: if (methods != null) {
154: String reqmeth = request.getMethod();
155: boolean affected = false;
156: for (int i = 0; i < methods.length; i++) {
157: if (reqmeth.equals(methods[i])) {
158: affected = true;
159: break;
160: }
161: }
162: if (!affected) {
163: return super .perform(request);
164: }
165: }
166: httpd server = (httpd) getServer();
167: String host = request.getHost();
168: // why this??? commenting while investigating
169: //request.setReferer(getURLPath());
170: try {
171: String target = null;
172: String pathinfo = (String) request.getState(PATH_INFO);
173: if (pathinfo != null)
174: target = getTarget() + pathinfo;
175: else
176: target = getTarget();
177:
178: if (request.hasQueryString())
179: target += "?" + request.getQueryString();
180:
181: // save the original URL
182: request.setState(Request.ORIG_URL_STATE, request.getURL());
183: // and mark content location
184: request.setState(STATE_CONTENT_LOCATION, "true");
185: if (host == null) {
186: request.setURL(new URL(server.getURL(), target));
187: } else {
188: // URL newurl = new URL (new URL(server.getURL().getProtocol(),
189: // host,
190: // server.getURL().getFile()),
191: // target);
192: URL newurl = new URL(request.getURL(), target);
193: String newhost = null;
194: if (newurl.getPort() != -1
195: && (newurl.getProtocol().equalsIgnoreCase(
196: "http") && (newurl.getPort() != 80))) {
197: newhost = newurl.getHost() + ":" + newurl.getPort();
198: } else {
199: newhost = newurl.getHost();
200: }
201: request.setURL(newurl);
202: request.setHost(newhost);
203: }
204: } catch (MalformedURLException ex) {
205: Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
206: error.setContent("<html><head><title>Server Error</title>"
207: + "</head><body><h1>Server misconfigured</h1>"
208: + "<p>The resource <b>" + getIdentifier() + "</b>"
209: + "has an invalid target attribute : <p><b>"
210: + getTarget() + "</b></body></html>");
211: throw new HTTPException(error);
212: }
213: return server.perform(request);
214: }
215: }
|