// ProxyFrame.java // $Id: ProxyFrame.java,v 1.7 1998/09/15 14:50:43 bmahe Exp $ // (c) COPYRIGHT MIT and INRIA, 1998. // Please first read the full copyright statement in file COPYRIGHT.html package org.w3c.jigsaw.proxy; import java.net.*; import java.io.*; import java.util.*; import org.w3c.www.http.*; import org.w3c.www.mime.*; import org.w3c.jigsaw.html.*; import org.w3c.tools.resources.*; import org.w3c.jigsaw.http.* ; import org.w3c.jigsaw.frames.HTTPFrame; /* class FtpTunnel extends HTTPFrame { public Reply get(Request request) throws HTTPException { try { MimeType mt; URLConnection c = request.getURL().openConnection(); InputStream in = c.getInputStream(); boolean markUsable = in.markSupported(); // We don't know the content length Reply reply = createDefaultReply(request, HTTP.OK); reply.addPragma("no-cache"); reply.setNoCache(); reply.setContentLength(c.getContentLength()); if (markUsable) in.mark(Integer.MAX_VALUE); try { mt = new MimeType(c.getContentType()); } catch (MimeTypeFormatException me) { mt = MimeType.TEXT_PLAIN; } reply.setContentType(mt); if (markUsable) // cope with a well known java bug in.reset(); reply.setStream(in); return reply; } catch (Exception ex) { throw new HTTPException("Unable to ftp \"" + request.getURL() + ", details \""+ex.getMessage()+"\""); } } } */ class Stats extends HTTPFrame { ProxyFrame proxy = null; Date startdate = null; boolean hasICP = true; protected String percentage(int part, int tot) { double p = ((double) part / ((double) tot)) * ((double) 100); return Integer.toString((int) p)+"%"; } public Reply get(Request request) { Reply r = createDefaultReply(request, HTTP.OK); HtmlGenerator g = new HtmlGenerator("Proxy statistics"); int c = proxy.reqcount+proxy.reqerred; if ( c == 0 ) c = 1; g.meta("Refresh", "30"); proxy.addStyleSheet(g); g.append("

Proxy statistics

"); g.append("

The proxy was last started at: " + startdate + ""); g.append("

Countercountpercentage"); // The total number of hits to the proxy: g.append("
Total number of handled requests"); g.append("", Integer.toString(c)); g.append("", percentage(c, c)); // The total number of errors: g.append("
Erred requests"); g.append("", Integer.toString(proxy.reqerred)); g.append("", percentage(proxy.reqerred, c)); // The total number of ICP redirects: g.append("
ICP redirects"); g.append("", Integer.toString(proxy.cache_icps)); g.append("", percentage(proxy.cache_icps, c)); // The total number of no-cache: g.append("
Non cacheable"); g.append("", Integer.toString(proxy.cache_nocache)); g.append("", percentage(proxy.cache_nocache, c)); // Cache accesses: int cached = (proxy.cache_hits + proxy.cache_misses + proxy.cache_revalidations + proxy.cache_retrievals); g.append("
Cache Accesses"); g.append("", Integer.toString(cached)); g.append("", percentage(cached, c)); // Hits (served by cache) g.append("
Hits (served by cache)"); g.append("", Integer.toString(proxy.cache_hits)); g.append("", percentage(proxy.cache_hits, c)); // Hits (revalidations) g.append("
Hits (revalidations)"); g.append("" , Integer.toString(proxy.cache_revalidations)); g.append("" , percentage(proxy.cache_revalidations, c)); // Misses (no cache entry) g.append("
Misses (no entry)"); g.append("", Integer.toString(proxy.cache_misses)); g.append("", percentage(proxy.cache_misses, c)); // Misses (retrievals) g.append("
Misses (retrievals)"); g.append("",Integer.toString(proxy.cache_retrievals)); g.append("", percentage(proxy.cache_retrievals, c)); g.append("
"); // Some goodies: g.append("


Generated by " , proxy.getServer().getURL().toExternalForm()); r.setStream(g); r.addPragma("no-cache"); r.setNoCache(); return r; } Stats(ProxyFrame proxy) { this.proxy = proxy; this.startdate = new Date(System.currentTimeMillis()); } } /** * A proxy module for Jigsaw. */ public class ProxyFrame extends ForwardFrame { /** * Attribute index - Should we tunnel ftp accesses ? */ protected static int ATTR_HANDLEFTP = -1; static { Attribute a = null; Class c = null; try { c = Class.forName("org.w3c.jigsaw.proxy.ProxyFrame"); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } // Register the handle-ftp attribute: a = new BooleanAttribute("handle-ftp" , Boolean.FALSE , Attribute.EDITABLE); ATTR_HANDLEFTP = AttributeRegistry.registerAttribute(c, a); } URL url = null; // FtpTunnel ftphandler = null; Stats statistics = null; DummyResourceReference drr = null; FramedResource statsres = null; /** * Trap changes to the handleftp attribute. * @param idx The attribute being set. * @param value The new value for that attribute. */ public void setValue(int idx, Object value) { super.setValue(idx, value); if ( idx == ATTR_HANDLEFTP ) { boolean b = ((Boolean) value).booleanValue(); // if ( b ) { // ftphandler = new FtpTunnel(); // } else { // ftphandler = null; // } } } /** * Do we handle ftp ? * @return A boolean. */ public boolean checkHandleFTP() { return getBoolean(ATTR_HANDLEFTP, false); } /** * Lookup for an proxied resource. * @param request The request whose URI is to be looked up. * @param ls The current lookup state * @param lr The result * @exception org.w3c.tools.resources.ProtocolException If something fails. */ public boolean lookupOther(LookupState ls, LookupResult lr) throws org.w3c.tools.resources.ProtocolException { // Get the full URL from the request: Request request = (Request) ls.getRequest(); URL requrl = ((request != null) ? request.getURL() : null); if (((url != null) && (requrl != null) && (requrl.getPort() == url.getPort()) && (requrl.getHost().equalsIgnoreCase(url.getHost()))) || (ls.isInternal())) { // Call super.lookup: super.lookupOther(ls, lr); if ( ls.hasMoreComponents() ) { ResourceReference root = getLocalRootResource(); if ( root == null ) { lr.setTarget(this.getResource().getResourceReference()); return true; } try { // because the root eats the lookup state components // we have to return true. // Should not be continued by the caller. FramedResource res = (FramedResource)root.lock(); boolean done = res.lookup(ls, lr); if (! done) lr.setTarget(null); return true; } catch (InvalidResourceException ex) { // should never happen with the root resource ex.printStackTrace(); } finally { root.unlock(); } return true; // should never be reached } else { lr.setTarget(drr); return true; } } else { // Always invoke super lookup, after notification that its a proxy request.setProxy(true); super.lookupOther(ls, lr); if ( requrl.getProtocol().equals("ftp") ) { // if (ftphandler != null) // lr.setTarget(ftphandler); // else lr.setTarget(null); return true; } else { lr.setTarget(this.getResource().getResourceReference()); return true; } } } /** * do the normal lookup, and set the proxy boolean flag if needed * @param ls The current lookup state * @param lr The result * @return true if lookup is done. * @exception org.w3c.tools.resources.ProtocolException If an error * relative to the protocol occurs */ public boolean lookup(LookupState ls, LookupResult lr) throws org.w3c.tools.resources.ProtocolException { // Internal lookup: if ( ls.isInternal() ) return super.lookup(ls, lr); Request request = (Request) ls.getRequest(); URL requrl = request.getURL() ; if ((url != null) && (requrl.getPort() == url.getPort()) && (requrl.getHost().equalsIgnoreCase(url.getHost()))) { return super.lookup(ls, lr); } else { // not internal, so set it as a proxied call for lookup request.setProxy(true); } return super.lookup(ls, lr); } /** * companion to initialize, called after the register */ public void registerResource(FramedResource resource) { super.registerResource(resource); // Our home url: url = getServer().getURL(); // If we do handle ftp, initialize: // if ( checkHandleFTP() ) // ftphandler = new FtpTunnel(); // Initialize the stats: ResourceFrame frame = null; try { frame = getFrame(Class.forName("org.w3c.jigsaw.proxy.Stats")); } catch (Exception ex) { // don't give a damn } if (frame != null) return; statistics = new Stats(this); statsres = new FramedResource(); // create an empty resource statsres.registerFrame(statistics, new Hashtable(1)); drr = new DummyResourceReference(statsres); } /** * Update the URL in which we are installed. * @param values The default attribute values. */ public void initialize(Object values[]) { super.initialize(values); } }