--- /dev/null
+// RedirecterFrame.java\r
+// $Id: RedirecterFrame.java,v 1.2 2010/06/15 17:52:52 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.frames;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+import org.w3c.tools.resources.AttributeRegistry;\r
+import org.w3c.tools.resources.LookupResult;\r
+import org.w3c.tools.resources.LookupState;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ReplyInterface;\r
+import org.w3c.tools.resources.RequestInterface;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.tools.resources.ResourceFrame;\r
+import org.w3c.tools.resources.StringArrayAttribute;\r
+import org.w3c.tools.resources.StringAttribute;\r
+\r
+import org.w3c.jigsaw.http.HTTPException;\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+import org.w3c.jigsaw.http.httpd;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ResourceException;\r
+\r
+/**\r
+ * Perform an internal redirect.\r
+ */\r
+public class RedirecterFrame extends HTTPFrame {\r
+ /**\r
+ * Name of the state to hold the PATH_INFO in the request.\r
+ */\r
+ public final static \r
+ String PATH_INFO = \r
+ "org.w3c.jigsaw.resources.RedirecterFrame.PathInfo";\r
+\r
+ /**\r
+ * Attributes index - The index for the target attribute.\r
+ */\r
+ protected static int ATTR_TARGET = -1 ;\r
+ /**\r
+ * Attribute index - The methods affected by this frame\r
+ */\r
+ protected static int ATTR_METHODS = -1 ;\r
+\r
+ static {\r
+ Attribute a = null ;\r
+ Class cls = null ;\r
+ // Get a pointer to our class:\r
+ try {\r
+ cls = Class.forName("org.w3c.jigsaw.frames.RedirecterFrame") ;\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace() ;\r
+ System.exit(1) ;\r
+ }\r
+ a = new StringAttribute("target"\r
+ , null\r
+ , Attribute.EDITABLE);\r
+ ATTR_TARGET = AttributeRegistry.registerAttribute(cls, a) ;\r
+ // The affected methods\r
+ a = new StringArrayAttribute("methods"\r
+ , null\r
+ , Attribute.EDITABLE) ;\r
+ ATTR_METHODS = AttributeRegistry.registerAttribute(cls, a) ;\r
+ }\r
+\r
+ /**\r
+ * Get the list of methods affected by the redirection\r
+ * @return An array of String giving the name of the redirected methods,\r
+ * or <strong>null</strong>, in wich case <em>all</em> methods are\r
+ * to be redirected.\r
+ */\r
+ public String[] getMethods() {\r
+ return (String[]) getValue(ATTR_METHODS, null) ;\r
+ }\r
+\r
+ /**\r
+ * Get the location for the internal redirection\r
+ * @return a string, containing the relative path or absolute PATH.\r
+ */\r
+ protected String getTarget() {\r
+ return (String) getValue(ATTR_TARGET, null);\r
+ }\r
+\r
+ /**\r
+ * Lookup the target resource when associated with an unknown resource.\r
+ * @param ls The current lookup state\r
+ * @param lr The result\r
+ * @return true if lookup is done.\r
+ * @exception ProtocolException If an error relative to the protocol occurs\r
+ */\r
+ protected boolean lookupResource(LookupState ls, LookupResult lr) \r
+ throws ProtocolException\r
+ {\r
+ String methods[] = getMethods();\r
+ \r
+ if (ls.hasRequest() && (methods != null)) {\r
+ Request request = (Request) ls.getRequest();\r
+ String reqmeth = request.getMethod();\r
+ boolean affected = false;\r
+ for (int i=0; i< methods.length; i++) {\r
+ if (reqmeth.equals(methods[i])) {\r
+ affected = true;\r
+ break;\r
+ }\r
+ }\r
+ if (!affected) {\r
+ return super.lookupResource(ls, lr);\r
+ }\r
+ }\r
+ // Perform our super-class lookup strategy:\r
+ if ( super.lookupOther(ls, lr) ) {\r
+ return true;\r
+ } \r
+ // Compute PATH INFO, store it as a piece of state in the request:\r
+ StringBuffer pathinfo = new StringBuffer();\r
+ while ( ls.hasMoreComponents() ) {\r
+ pathinfo.append('/');\r
+ pathinfo.append(ls.getNextComponent());\r
+ }\r
+ if (ls.hasRequest() ) {\r
+ Request request = (Request) ls.getRequest();\r
+ String reqfile = request.getURL().getFile();\r
+ if (reqfile.endsWith("/")) {\r
+ pathinfo.append('/');\r
+ }\r
+ request.setState(PATH_INFO, pathinfo.toString());\r
+ }\r
+ lr.setTarget(resource.getResourceReference());\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Perform the request.\r
+ * @param req The request to handle.\r
+ * @exception ProtocolException If request couldn't be processed.\r
+ * @exception ResourceException If the resource got a fatal error.\r
+ */\r
+ public ReplyInterface perform(RequestInterface req) \r
+ throws ProtocolException, ResourceException\r
+ {\r
+ Reply reply = (Reply) performFrames(req);\r
+ if (reply != null) \r
+ return reply;\r
+ Request request = (Request) req;\r
+ // check if we must use our parent perform call\r
+ String methods[] = getMethods();\r
+ \r
+ if (methods != null) {\r
+ String reqmeth = request.getMethod();\r
+ boolean affected = false;\r
+ for (int i=0; i< methods.length; i++) {\r
+ if (reqmeth.equals(methods[i])) {\r
+ affected = true;\r
+ break;\r
+ }\r
+ }\r
+ if (!affected) {\r
+ return super.perform(request);\r
+ }\r
+ }\r
+ httpd server = (httpd) getServer();\r
+ String host = request.getHost(); \r
+ // why this??? commenting while investigating\r
+ //request.setReferer(getURLPath());\r
+ try {\r
+ String target = null;\r
+ String pathinfo = (String) request.getState(PATH_INFO);\r
+ if (pathinfo != null)\r
+ target = getTarget()+pathinfo;\r
+ else\r
+ target = getTarget();\r
+\r
+ if (request.hasQueryString())\r
+ target += "?"+request.getQueryString();\r
+\r
+ // save the original URL\r
+ request.setState(Request.ORIG_URL_STATE, request.getURL());\r
+ // and mark content location\r
+ request.setState(STATE_CONTENT_LOCATION, "true");\r
+ if (host == null) {\r
+ request.setURL(new URL(server.getURL(), target));\r
+ } else {\r
+// URL newurl = new URL (new URL(server.getURL().getProtocol(),\r
+// host, \r
+// server.getURL().getFile()),\r
+// target);\r
+ URL newurl = new URL(request.getURL(), target);\r
+ String newhost = null;\r
+ if (newurl.getPort() != -1 && \r
+ (newurl.getProtocol().equalsIgnoreCase("http") &&\r
+ (newurl.getPort() != 80))) {\r
+ newhost = newurl.getHost() + ":" + newurl.getPort();\r
+ } else {\r
+ newhost = newurl.getHost();\r
+ }\r
+ request.setURL(newurl);\r
+ request.setHost(newhost);\r
+ }\r
+ } catch (MalformedURLException ex) {\r
+ Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);\r
+ error.setContent("<html><head><title>Server Error</title>"+\r
+ "</head><body><h1>Server misconfigured</h1>"+\r
+ "<p>The resource <b>"+getIdentifier()+"</b>"+\r
+ "has an invalid target attribute : <p><b>"+\r
+ getTarget()+"</b></body></html>"); \r
+ throw new HTTPException (error);\r
+ }\r
+ return server.perform(request);\r
+ }\r
+}\r