📄 relocateframe.java
字号:
// RelocateFrame.java// $Id: RelocateFrame.java,v 1.19 2002/04/11 11:58:36 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.frames;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import org.w3c.tools.resources.Attribute;import org.w3c.tools.resources.AttributeHolder;import org.w3c.tools.resources.AttributeRegistry;import org.w3c.tools.resources.BooleanAttribute;import org.w3c.tools.resources.LookupResult;import org.w3c.tools.resources.LookupState;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.Resource;import org.w3c.tools.resources.ResourceException;import org.w3c.tools.resources.ResourceFrame;import org.w3c.tools.resources.ServerInterface;import org.w3c.tools.resources.StringArrayAttribute;import org.w3c.tools.resources.StringAttribute;import org.w3c.jigsaw.http.HTTPException;import org.w3c.jigsaw.http.Reply;import org.w3c.jigsaw.http.Request;import org.w3c.jigsaw.http.httpd;import org.w3c.jigsaw.html.HtmlGenerator;import org.w3c.www.http.HTTP;import org.w3c.www.http.HttpMessage;import org.w3c.www.http.HttpReplyMessage;import org.w3c.www.http.HttpRequestMessage;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.ResourceException;/** * Emit a HTTP redirect. */public class RelocateFrame extends HTTPFrame { /** * Name of the state to hold the PATH_INFO in the request. */ public final static String PATH_INFO = "org.w3c.jigsaw.resources.RelocateResource.PathInfo"; /** * Attribute index - The relocation location. */ protected static int ATTR_LOCATION = -1 ; /** * Attribute index - Should we also handle extra path infos ? */ protected static int ATTR_HANDLE_PATHINFO = -1; /** * Attribute index - Is the relocation permanent? */ protected static int ATTR_PERMANENT_REDIRECT = -1; /** * Attribute index - SHould we use the ambiguous 302? */ protected static int ATTR_USE_302 = -1; /** * Attribute index - The methods affected by this frame */ protected static int ATTR_METHODS = -1 ; static { Attribute a = null ; Class c = null ; try { c = Class.forName("org.w3c.jigsaw.frames.RelocateFrame"); } catch (Exception ex) { ex.printStackTrace() ; System.exit(1) ; } // The location attribute a = new StringAttribute("location" , null , Attribute.EDITABLE|Attribute.MANDATORY) ; ATTR_LOCATION = AttributeRegistry.registerAttribute(c, a) ; // The handle path info attribute a = new BooleanAttribute("handle-pathinfo" , Boolean.TRUE , Attribute.EDITABLE); ATTR_HANDLE_PATHINFO = AttributeRegistry.registerAttribute(c, a); // the permanent redirection attribute a = new BooleanAttribute("permanent-redirect" , Boolean.FALSE , Attribute.EDITABLE); ATTR_PERMANENT_REDIRECT = AttributeRegistry.registerAttribute(c, a); // should we use the ambiguous 302 response code? a = new BooleanAttribute("use-usual-response" , Boolean.TRUE , Attribute.EDITABLE); ATTR_USE_302 = AttributeRegistry.registerAttribute(c, a); // The affected methods a = new StringArrayAttribute("methods" , null , Attribute.EDITABLE) ; ATTR_METHODS = AttributeRegistry.registerAttribute(c, a) ; } /** * Get the location for the relocation * @return a string, containing the relative path or absolute */ public String getLocation() { return (String) getValue(ATTR_LOCATION, null) ; } /** * Get the list of methods affected by the redirect * @return An array of String giving the name of the redirected methods, * or <strong>null</strong>, in wich case <em>all</em> methods are * to be redirected. */ public String[] getMethods() { return (String[]) getValue(ATTR_METHODS, null) ; } /** * Get the path info value * @return a boolean */ public boolean checkHandlePathInfo() { return getBoolean(ATTR_HANDLE_PATHINFO, true); } /** * Get the permanent redirect flag * @return a boolean */ public boolean checkPermanentRedirect() { return getBoolean(ATTR_PERMANENT_REDIRECT, false); } /** * Get the "use ambigous 302 response code" flag * @return a boolean */ public boolean checkUse302() { return getBoolean(ATTR_USE_302, true); } /** * Lookup the target resource (dispath to more specific lookup methods). * @param ls The current lookup state * @param lr The result * @return true if lookup is done. * @exception ProtocolException If an error relative to the protocol occurs * @see #lookupDirectory * @see #lookupFile * @see #lookupOther */ protected boolean lookupResource(LookupState ls, LookupResult lr) throws ProtocolException { String methods[] = getMethods(); if (ls.hasRequest() && (methods != null)) { Request request = (Request) ls.getRequest(); String reqmeth = request.getMethod(); boolean affected = false; for (int i=0; i< methods.length; i++) { if (reqmeth.equals(methods[i])) { affected = true; break; } } if (!affected) { return super.lookupResource(ls, lr); } } // Perform our super-class lookup strategy: if ( super.lookupOther(ls, lr) ) { return true; } else if ( ! checkHandlePathInfo() ) { return false; } // Compute PATH INFO, store it as a piece of state in // the request: StringBuffer pathinfo = new StringBuffer(); while ( ls.hasMoreComponents() ) { pathinfo.append('/'); pathinfo.append(ls.getNextComponent()); } if (ls.hasRequest() ) { Request request = (Request) ls.getRequest(); String reqfile = request.getURL().getFile(); if (reqfile.endsWith("/")) { pathinfo.append('/'); } request.setState(PATH_INFO, pathinfo.toString()); } lr.setTarget(resource.getResourceReference()); return true; } /** * build the redirect reply based on the request and the current * configuration * @param request The request to handle. * @exception ProtocolException If processsing the request failed. * @return a Reply */ private Reply getRedirectReply(Request request) throws ProtocolException { String location = getLocation() ; if ( location == null ) { Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ; error.setContent("The target RelocateResource doesn't define the" + " relocation location. The server is " + " misconfigured.") ; throw new HTTPException(error) ; } else { Reply reply = null; URL loc = null; if (checkUse302()) { reply = request.makeReply(HTTP.FOUND) ; } else { if (checkPermanentRedirect()) { reply = request.makeReply(HTTP.MOVED_PERMANENTLY) ; } else { reply = request.makeReply(HTTP.TEMPORARY_REDIRECT) ; } } try { httpd server = (httpd) getServer(); String host = request.getHost(); if (host == null) loc = new URL(server.getURL(), location); else { int ic = host.indexOf(':'); if (ic < 0 ) { loc = new URL(new URL(server.getURL().getProtocol(), host,server.getURL().getFile()), location); } else { loc = new URL(new URL(server.getURL().getProtocol(), host.substring(0, ic), Integer.parseInt( host.substring(ic+1)) ,server.getURL().getFile()), location); } } if (checkHandlePathInfo()) { String pathinfo = (String) request.getState(PATH_INFO); // Given the way pathinfo is computed, it starts with a / try { if (pathinfo != null) { loc = new URL(loc.toExternalForm()+pathinfo); } } catch (MalformedURLException ex) { resource.getServer().errlog(resource, "This resource handle Pathinfo "+ "but the request has an invalid "+ "PATH_INFO state."); } if (request.hasQueryString()) { try { loc = new URL(loc.toExternalForm() + "?" + request.getQueryString()); } catch (MalformedURLException ex) { resource.getServer().errlog(resource, "This resource handle " +"Pathinfo but the " +"request has an " +"invalid "+ "PATH_INFO state."); } } } } catch (Exception ex) { ex.printStackTrace(); } reply.setLocation(loc); HtmlGenerator g = new HtmlGenerator("Moved"); g.append("<P>This resources has moved, click on the link if your" + " browser doesn't support automatic redirection<BR>"+ "<A HREF=\""+loc.toExternalForm()+"\">"+ loc.toExternalForm()+"</A>"); reply.setStream(g); return reply ; } } /** * The GET method, may emit a redirect * @param request The request to handle. * @exception ProtocolException If processsing the request failed. * @exception ResourceException If the resource got a fatal error. */ public Reply get(Request request) throws ProtocolException, ResourceException { String methods[] = getMethods(); if (methods != null) { String reqmeth = request.getMethod(); boolean affected = false; for (int i=0; i< methods.length; i++) { if (reqmeth.equals(methods[i])) { affected = true; break; } } if (!affected) { return super.get(request); } } // now we can modify it :) return getRedirectReply(request); } /** * The HEAD method, may emit a redirect * @param request The request to handle. * @exception ProtocolException If processsing the request failed. * @exception ResourceException If the resource got a fatal error. */ public Reply head(Request request) throws ProtocolException, ResourceException { String methods[] = getMethods(); if (methods != null) { String reqmeth = request.getMethod(); boolean affected = false; for (int i=0; i< methods.length; i++) { if (reqmeth.equals(methods[i])) { affected = true; break; } } if (!affected) { return super.head(request); } } // now we can modify it :) Reply reply = getRedirectReply(request); reply.setStream((InputStream) null); return reply ; } /** * The PUT method, may emit a redirect, otherwise uses its parent put * @param request The request to handle. * @exception ProtocolException If processsing the request failed. * @exception ResourceException If the resource got a fatal error. */ public Reply put(Request request) throws ProtocolException, ResourceException { String methods[] = getMethods(); if (methods != null) { String reqmeth = request.getMethod(); boolean affected = false; for (int i=0; i< methods.length; i++) { if (reqmeth.equals(methods[i])) { affected = true; break; } } if (!affected) { return super.put(request); } } // now we can modify it :) return getRedirectReply(request); } /** * The POST method, may emit a redirect, otherwise uses its parent put * @param request The request to handle. * @exception ProtocolException If processsing the request failed. * @exception ResourceException If the resource got a fatal error. */ public Reply post(Request request) throws ProtocolException, ResourceException { String methods[] = getMethods(); if (methods != null) { String reqmeth = request.getMethod(); boolean affected = false; for (int i=0; i< methods.length; i++) { if (reqmeth.equals(methods[i])) { affected = true; break; } } if (!affected) { return super.post(request); } } // now we can modify it :) return getRedirectReply(request); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -