--- /dev/null
+// MirrorFrame.java\r
+// $Id: MirrorFrame.java,v 1.2 2010/06/15 17:53:06 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1998\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.proxy ;\r
+\r
+import java.net.URL;\r
+\r
+import java.io.IOException;\r
+\r
+import org.w3c.www.http.HTTP;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+import org.w3c.tools.resources.AttributeHolder;\r
+import org.w3c.tools.resources.AttributeRegistry;\r
+import org.w3c.tools.resources.BooleanAttribute;\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.Resource;\r
+import org.w3c.tools.resources.ResourceFrame;\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
+\r
+import org.w3c.jigsaw.frames.HTTPFrame;\r
+\r
+public class MirrorFrame extends ForwardFrame {\r
+ /**\r
+ * Attribute index - The site we are mirroring.\r
+ */\r
+ protected static int ATTR_MIRRORS = -1;\r
+ /**\r
+ * Attribute index - Do we mirror from root or relative\r
+ */\r
+ protected static int ATTR_PARTIAL = -1;\r
+\r
+ static {\r
+ Class c = null;\r
+ Attribute a = null;\r
+ try {\r
+ c = Class.forName("org.w3c.jigsaw.proxy.MirrorFrame");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ System.exit(1);\r
+ }\r
+ // Register the mirrored site attribute:\r
+ a = new StringAttribute("mirrors"\r
+ , null\r
+ , Attribute.EDITABLE);\r
+ ATTR_MIRRORS = AttributeRegistry.registerAttribute(c, a);\r
+ // Do we allow sub mirroring (aka parts of the site)\r
+ // and not from root\r
+ a = new BooleanAttribute("partial"\r
+ , Boolean.FALSE\r
+ , Attribute.EDITABLE);\r
+ ATTR_PARTIAL = AttributeRegistry.registerAttribute(c, a);\r
+ }\r
+ \r
+ protected URL mirrors = null;\r
+ public static final String MIRROR_PATH = "MIRROR_PATH";\r
+ \r
+ /**\r
+ * Get the mirrors site attribute value.\r
+ * @return The String encoded URL of the site we are mirroring here.\r
+ */\r
+\r
+ public String getMirrors() {\r
+ return getString(ATTR_MIRRORS, null);\r
+ }\r
+\r
+ /**\r
+ * Get the mirrors site attribute value.\r
+ * @return The String encoded URL of the site we are mirroring here.\r
+ */\r
+\r
+ public boolean isPartialMirroring() {\r
+ return getBoolean(ATTR_PARTIAL, false);\r
+ }\r
+\r
+ /**\r
+ * Catch assignment to the mirror attribute, to update our cached URL.\r
+ * @param idx The slot to set.\r
+ * @param value It's new value.\r
+ */\r
+\r
+ public void setValue(int idx, Object value) {\r
+ super.setValue(idx, value);\r
+ if ( idx == ATTR_MIRRORS ) {\r
+ try {\r
+ mirrors = new URL(getMirrors());\r
+ } catch (Exception ex) {\r
+ mirrors = null;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param request the incomming request\r
+ * @param rep the client reply\r
+ * @return A Reply instance\r
+ * @exception HTTPException if processing the request failed.\r
+ * @exception IOException if an IO error occurs.\r
+ */\r
+ protected Reply dupReply(Request request\r
+ , org.w3c.www.protocol.http.Reply rep) \r
+ throws HTTPException, IOException\r
+ {\r
+ Reply reply = super.dupReply(request, rep);\r
+ // Tweak redirections ! Wow this is getting real nifty :-)\r
+ switch(reply.getStatus()) {\r
+ case HTTP.MOVED_PERMANENTLY:\r
+ case HTTP.TEMPORARY_REDIRECT:\r
+ case HTTP.FOUND:\r
+ case HTTP.SEE_OTHER:\r
+ // Have fun !\r
+ String location = rep.getLocation();\r
+ if ((mirrors != null) && (location != null)) {\r
+ try {\r
+ URL uloc = new URL(request.getURL(), location);\r
+ URL loc = getURL(request);\r
+ URL fake = null;\r
+ if (isPartialMirroring()) {\r
+ fake = new URL(request.getURL().getProtocol()\r
+ , loc.getHost()\r
+ , loc.getPort()\r
+ , getURLPath()+uloc.getFile());\r
+ } else if (location.startsWith(mirrors.toString())) {\r
+ fake = new URL(request.getURL().getProtocol()\r
+ , loc.getHost()\r
+ , loc.getPort()\r
+ , uloc.getFile());\r
+ } else {\r
+ fake = uloc;\r
+ }\r
+ if (fake != null) {\r
+ reply.setLocation(fake);\r
+ }\r
+ } catch (Exception ex) {\r
+ }\r
+ }\r
+ }\r
+ return reply;\r
+ }\r
+\r
+ /**\r
+ * @param request the incomming request\r
+ * @return A client Request instance.\r
+ * @exception HTTPException if processing the request failed.\r
+ * @exception IOException if an IO error occurs.\r
+ */\r
+ protected org.w3c.www.protocol.http.Request dupRequest(Request request) \r
+ throws HTTPException, IOException\r
+ {\r
+ org.w3c.www.protocol.http.Request req = super.dupRequest(request);\r
+ // Tweak the URL :-)\r
+ if (isPartialMirroring()) {\r
+ String requrl = request.getURL().getFile();\r
+ String respath = getURLPath();\r
+ if (requrl.startsWith(respath)) {\r
+ String nurl = requrl.substring(respath.length());\r
+ req.setURL(new URL(mirrors, nurl));\r
+ } else {\r
+ req.setURL(new URL(mirrors, requrl));\r
+ }\r
+ } else {\r
+ req.setURL(new URL(mirrors, request.getURL().getFile()));\r
+ }\r
+ return req;\r
+ }\r
+ \r
+ /**\r
+ * Lookup for a mirrored resource.\r
+ * @param ls The current lookup state\r
+ * @param lr The result\r
+ * @return true if lookup is done.\r
+ * @exception org.w3c.tools.resources.ProtocolException If an error \r
+ * relative to the protocol occurs\r
+ */\r
+ public boolean lookupOther(LookupState ls, LookupResult lr)\r
+ throws org.w3c.tools.resources.ProtocolException \r
+ {\r
+ // Get the full URL from the request:\r
+ Request request = (Request) ls.getRequest();\r
+ URL url = request.getURL();\r
+\r
+ if ( ls.isInternal() )\r
+ return super.lookupOther(ls, lr);\r
+ if ( mirrors != null ) {\r
+ request.setProxy(true);\r
+ lr.setTarget(this.getResource().getResourceReference());\r
+ return true;\r
+ } \r
+ // Emit a not found:\r
+ Reply error = request.makeReply(HTTP.NOT_FOUND);\r
+ if (request.getMethod().equals("GET"))\r
+ error.setContent("Target resource not found.");\r
+ lr.setTarget(null);\r
+ lr.setReply(error);\r
+ return true;\r
+ }\r
+\r
+ public void initialize(Object values[]) {\r
+ super.initialize(values);\r
+ String strmirrors = getMirrors();\r
+ try {\r
+ mirrors = new URL(strmirrors);\r
+ } catch (Exception ex) {\r
+ mirrors = null;\r
+ }\r
+ }\r
+}\r