Author: dbkr
Date: 2006-03-05 21:35:39 +0000 (Sun, 05 Mar 2006)
New Revision: 8169
Added:
trunk/freenet/src/freenet/clients/http/PageMaker.java
trunk/freenet/src/freenet/clients/http/RedirectException.java
trunk/freenet/src/freenet/clients/http/StaticToadlet.java
trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
trunk/freenet/src/freenet/clients/http/staticfiles/
trunk/freenet/src/freenet/clients/http/staticfiles/themes/
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/background.png
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/logo.png
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/theme.css
Modified:
trunk/freenet/src/freenet/clients/http/FproxyToadlet.java
trunk/freenet/src/freenet/clients/http/Toadlet.java
trunk/freenet/src/freenet/clients/http/ToadletContext.java
trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
trunk/freenet/src/freenet/clients/http/TrivialToadlet.java
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java
Log:
500: A web interface is born.
Lots of changes here:
- Creation of WelcomeToadlet and StaticToadlet
- Addition of images and css in src/freenet/clients/http/staticfiles
- Redirect support for Toadlets via RedirectException
- PproxyToadlet changed to be valid XHTML and use Location instead of Meta
refresh
- Addition of the PageMaker XHTML Page Engine (not as fancy as I've just made
it sound)
Enjoy!
Modified: trunk/freenet/src/freenet/clients/http/FproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FproxyToadlet.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/FproxyToadlet.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -5,6 +5,7 @@
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URI;
+import java.net.URISyntaxException;
import freenet.client.FetchException;
import freenet.client.FetchResult;
@@ -19,22 +20,49 @@
import freenet.node.Node;
import freenet.node.RequestStarter;
import freenet.pluginmanager.PproxyToadlet;
+import freenet.pluginmanager.PluginHTTPRequest;
import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
+import freenet.support.MultiValueTable;
public class FproxyToadlet extends Toadlet {
public FproxyToadlet(HighLevelSimpleClient client) {
super(client);
}
+
+ public String supportedMethods() {
+ return "GET";
+ }
- public void handleGet(URI uri, ToadletContext ctx)
- throws ToadletContextClosedException, IOException {
+ public void handleGet(URI uri, ToadletContext ctx)
+ throws ToadletContextClosedException, IOException,
RedirectException {
//String ks = uri.toString();
String ks = uri.getPath();
+
+ if (ks.equals("/")) {
+ PluginHTTPRequest httprequest = new
PluginHTTPRequest(uri);
+ if (httprequest.isParameterSet("key")) {
+ MultiValueTable headers = new MultiValueTable();
+
+ headers.put("Location",
"/"+httprequest.getParam("key"));
+ ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
+ return;
+ }
+
+ RedirectException re = new RedirectException();
+ try {
+ re.newuri = new URI("/welcome/");
+ } catch (URISyntaxException e) {
+ // HUH!?!
+ }
+ throw re;
+ }
+
if(ks.startsWith("/"))
ks = ks.substring(1);
+
FreenetURI key;
try {
key = new FreenetURI(ks);
@@ -65,15 +93,6 @@
}
}
- public void handlePut(URI uri, Bucket data, ToadletContext ctx)
- throws ToadletContextClosedException, IOException {
- String notSupported = "<html><head><title>Not
supported</title></head><body>"+
- "Operation not supported</body>";
- // FIXME should be 405? Need to let toadlets indicate what is
allowed maybe in a callback?
- this.writeReply(ctx, 200, "text/html", "OK", notSupported);
- }
-
-
static class FproxyEnabledCallback implements BooleanCallback {
final Node node;
@@ -161,8 +180,16 @@
FproxyToadlet fproxy = new
FproxyToadlet(node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS));
node.setFproxy(fproxy);
server.register(fproxy, "/", false);
+
PproxyToadlet pproxy = new
PproxyToadlet(node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS),
node.pluginManager);
server.register(pproxy, "/plugins/", true);
+
+ WelcomeToadlet welcometoadlet = new
WelcomeToadlet(node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS));
+ server.register(welcometoadlet, "/welcome/", true);
+
+ StaticToadlet statictoadlet = new
StaticToadlet(node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS));
+ server.register(statictoadlet, "/static/", true);
+
fproxyConfig.finishedInitialization();
System.out.println("Starting fproxy on port "+(port));
Logger.normal(node,"Starting fproxy on "+bind_ip+":"+port);
Added: trunk/freenet/src/freenet/clients/http/PageMaker.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PageMaker.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/PageMaker.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -0,0 +1,52 @@
+package freenet.clients.http;
+
+/** Simple class to output standard heads and tail for web interface pages.
+*/
+public class PageMaker {
+ // TODO: make this...err... not a constant.
+ private final String theme = new String("default");
+
+ public void makeTopHead(StringBuffer buf) {
+ buf.append("<!DOCTYPE\n"
+ + " html PUBLIC \"-//W3C//DTD XHTML
1.1//EN\"\n"
+ + "
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ + "<html xmlns=\"http://www.w3.org/1999/xhtml\"
xml:lang=\"en\">\n"
+ + "<head>\n"
+ + "<meta http-equiv=\"Content-Type\"
content=\"text/html;\" />\n"
+ + "<link rel=\"stylesheet\"
href=\"/static/themes/"+theme+"/theme.css\" type=\"text/css\" />\n");
+ }
+
+ public void makeBottomHead(StringBuffer buf, String title) {
+ buf.append("<title>"+title+" - Freenet</title>\n"
+ + "</head>\n"
+ + "<body>\n"
+ + "<div id=\"page\">\n"
+ + "<div id=\"topbar\">\n"
+ + "<h1>"+title+"</h1>\n"
+ + "</div>\n");
+ this.makeNavBar(buf);
+ buf.append("<div id=\"content\">\n");
+ }
+
+ public void makeHead(StringBuffer buf, String title) {
+ makeTopHead(buf);
+ makeBottomHead(buf, title);
+ }
+
+ public void makeTail(StringBuffer buf) {
+ buf.append("<br style=\"clear: all;\"/>"
+ + "</div>\n"
+ +"</div>\n"
+ +"</body>\n"
+ + "</html>\n");
+ }
+
+ private void makeNavBar(StringBuffer buf) {
+ buf.append("<div id=\"navbar\">\n"
+ + "<ul id=\"navlist\">\n"
+ + "<li><a href=\"/\"
title=\"Homepage\">Home</a></li>\n"
+ + "<li><a href=\"/plugins/\" title=\"Configure
Plugins\">Plugins</a></li>\n"
+ + "</ul>\n"
+ + "</div>\n");
+ }
+}
Added: trunk/freenet/src/freenet/clients/http/RedirectException.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/RedirectException.java
2006-03-05 21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/RedirectException.java
2006-03-05 21:35:39 UTC (rev 8169)
@@ -0,0 +1,7 @@
+package freenet.clients.http;
+
+import java.net.URI;
+
+class RedirectException extends Exception {
+ URI newuri;
+}
Added: trunk/freenet/src/freenet/clients/http/StaticToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/StaticToadlet.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/StaticToadlet.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -0,0 +1,65 @@
+package freenet.clients.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.FileNameMap;
+import java.net.URLConnection;
+import freenet.client.HighLevelSimpleClient;
+import freenet.support.MultiValueTable;
+
+/**
+ * Static Toadlet.
+ * Serve up static files
+ */
+public class StaticToadlet extends Toadlet {
+ StaticToadlet(HighLevelSimpleClient client) {
+ super(client);
+ }
+
+ final String rootURL = new String("/static/");
+ final String rootPath = new String("staticfiles/");
+
+ public void handleGet(URI uri, ToadletContext ctx) throws
ToadletContextClosedException, IOException {
+ String path = uri.getPath();
+ byte[] buf = new byte[1024];
+ int len;
+
+ if (!path.startsWith(rootURL)) {
+ // we should never get any other path anyway
+ return;
+ }
+ try {
+ path = path.substring(rootURL.length());
+ } catch (IndexOutOfBoundsException ioobe) {
+ this.sendErrorPage(ctx, 404, "Path not found", "The
path you specified doesn't exist");
+ return;
+ }
+
+ // be very strict about what characters we allow in the path,
since
+ if (!path.matches("^[A-Za-z0-9\\._\\/\\-]*$") ||
path.indexOf("..") != -1) {
+ this.sendErrorPage(ctx, 404, "Path not found", "The
given URI contains disallowed characters.");
+ return;
+ }
+
+
+ InputStream strm =
getClass().getResourceAsStream(rootPath+path);
+ if (strm == null) {
+ this.sendErrorPage(ctx, 404, "Path not found", "The
specified path does not exist.");
+ return;
+ }
+
+
+ FileNameMap map = URLConnection.getFileNameMap();
+
+ ctx.sendReplyHeaders(200, "OK", null,
map.getContentTypeFor(path), strm.available());
+
+ while ( (len = strm.read(buf)) > 0) {
+ ctx.writeData(buf, 0, len);
+ }
+ }
+
+ public String supportedMethods() {
+ return "GET";
+ }
+}
Modified: trunk/freenet/src/freenet/clients/http/Toadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Toadlet.java 2006-03-05 21:34:05 UTC
(rev 8168)
+++ trunk/freenet/src/freenet/clients/http/Toadlet.java 2006-03-05 21:35:39 UTC
(rev 8169)
@@ -10,6 +10,7 @@
import freenet.client.InserterException;
import freenet.keys.FreenetURI;
import freenet.support.Bucket;
+import freenet.support.MultiValueTable;
/**
* Replacement for servlets. Just an easy to use HTTP interface, which is
@@ -38,20 +39,53 @@
/**
* Handle a GET request.
- * Must be implemented by the client.
+ * If not overridden by the client, send 'Method not supported'
* @param uri The URI (relative to this client's document root) to
* be fetched.
* @throws IOException
* @throws ToadletContextClosedException
*/
- abstract public void handleGet(URI uri, ToadletContext ctx) throws
ToadletContextClosedException, IOException;
+ public void handleGet(URI uri, ToadletContext ctx) throws
ToadletContextClosedException, IOException, RedirectException {
+ StringBuffer buf = new StringBuffer();
+
+ ctx.getPageMaker().makeHead(buf, "Not supported");
+
+ buf.append("Operation not supported");
+ ctx.getPageMaker().makeTail(buf);
+
+ MultiValueTable hdrtbl = new MultiValueTable();
+ hdrtbl.put("Allow", this.supportedMethods());
+ ctx.sendReplyHeaders(405, "Operation not Supported", hdrtbl,
"text/html", buf.length());
+ ctx.writeData(buf.toString().getBytes(), 0, buf.length());
+ }
+
/**
* Likewise for a PUT request.
*/
- abstract public void handlePut(URI uri, Bucket data, ToadletContext
ctx) throws ToadletContextClosedException, IOException;
+ public void handlePut(URI uri, Bucket data, ToadletContext ctx) throws
ToadletContextClosedException, IOException, RedirectException {
+ StringBuffer buf = new StringBuffer();
+
+ ctx.getPageMaker().makeHead(buf, "Not supported");
+
+ buf.append("Operation not supported");
+ ctx.getPageMaker().makeTail(buf);
+
+ MultiValueTable hdrtbl = new MultiValueTable();
+ hdrtbl.put("Allow", this.supportedMethods());
+ ctx.sendReplyHeaders(405, "Operation not Supported", hdrtbl,
"text/html", buf.length());
+ ctx.writeData(buf.toString().getBytes(), 0, buf.length());
+ }
/**
+ * Which methods are supported by this Toadlet.
+ * Should return a string containing the methods supported, separated
by commas
+ * For example: "GET, PUT" (in which case both 'handleGet()' and
'handlePut()'
+ * must be overridden).
+ */
+ abstract public String supportedMethods();
+
+ /**
* Client calls from the above messages to run a freenet request.
* This method may block (or suspend).
*/
@@ -88,6 +122,18 @@
}
/**
+ * Send a simple error page.
+ */
+ protected void sendErrorPage(ToadletContext ctx, int code, String desc,
String message) throws ToadletContextClosedException, IOException {
+ StringBuffer buf = new StringBuffer();
+
+ ctx.getPageMaker().makeHead(buf, desc);
+ buf.append(message);
+ ctx.getPageMaker().makeTail(buf);
+ writeReply(ctx, code, "text/html", desc, buf.toString());
+ }
+
+ /**
* Get the client impl. DO NOT call the blocking methods on it!!
* Just use it for configuration etc.
*/
Modified: trunk/freenet/src/freenet/clients/http/ToadletContext.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContext.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/ToadletContext.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -30,5 +30,10 @@
* Write data from a bucket. You must send reply headers first.
*/
void writeData(Bucket data) throws ToadletContextClosedException,
IOException;
+
+ /**
+ * Get the page maker object.
+ */
+ PageMaker getPageMaker();
+}
-}
Modified: trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2006-03-05 21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2006-03-05 21:35:39 UTC (rev 8169)
@@ -29,6 +29,7 @@
private final Socket sock;
private final MultiValueTable headers;
private final OutputStream sockOutputStream;
+ private final PageMaker pagemaker;
/** Is the context closed? If so, don't allow any more writes. This is
because there
* may be later requests.
*/
@@ -39,6 +40,7 @@
this.headers = headers;
this.closed = false;
sockOutputStream = sock.getOutputStream();
+ pagemaker = new PageMaker();
}
private void close() {
@@ -78,6 +80,10 @@
if(closed) throw new ToadletContextClosedException();
sendReplyHeaders(sockOutputStream, replyCode, replyDescription,
mvt, mimeType, contentLength);
}
+
+ public PageMaker getPageMaker() {
+ return pagemaker;
+ }
static void sendReplyHeaders(OutputStream sockOutputStream, int
replyCode, String replyDescription, MultiValueTable mvt, String mimeType, long
contentLength) throws IOException {
// Construct headers
@@ -163,38 +169,50 @@
headers.put(before, after);
}
- // Handle it.
+ boolean shouldDisconnect =
shouldDisconnectAfterHandled(split[2].equals("HTTP/1.0"), headers);
- Toadlet t = container.findToadlet(uri);
-
ToadletContextImpl ctx = new
ToadletContextImpl(sock, headers);
- boolean shouldDisconnect =
shouldDisconnectAfterHandled(split[2].equals("HTTP/1.0"), headers);
-
- if(t == null)
-
ctx.sendNoToadletError(shouldDisconnect);
-
- if(method.equals("GET")) {
+ // Handle it.
+ boolean redirect = true;
+ while (redirect) {
+ // don't go around the loop unless set
explicitly
+ redirect = false;
- t.handleGet(uri, ctx);
- ctx.close();
+ Toadlet t = container.findToadlet(uri);
- } else if(method.equals("PUT")) {
-
- t.handlePut(uri, null, ctx);
- ctx.close();
-
- } else if(method.equals("POST")) {
+ if(t == null)
+
ctx.sendNoToadletError(shouldDisconnect);
- Logger.error(ToadletContextImpl.class,
"POST not supported");
- ctx.sendMethodNotAllowed(method,
shouldDisconnect);
- ctx.close();
-
- } else {
- ctx.sendMethodNotAllowed(method,
shouldDisconnect);
- ctx.close();
+ if(method.equals("GET")) {
+ try {
+ t.handleGet(uri, ctx);
+ ctx.close();
+ } catch (RedirectException re) {
+ uri = re.newuri;
+ redirect = true;
+ }
+
+ } else if(method.equals("PUT")) {
+ try {
+ t.handlePut(uri, null,
ctx);
+ ctx.close();
+ } catch (RedirectException re) {
+ uri = re.newuri;
+ redirect = true;
+ }
+
+ } else if(method.equals("POST")) {
+
+
Logger.error(ToadletContextImpl.class, "POST not supported");
+
ctx.sendMethodNotAllowed(method, shouldDisconnect);
+ ctx.close();
+
+ } else {
+
ctx.sendMethodNotAllowed(method, shouldDisconnect);
+ ctx.close();
+ }
}
-
if(shouldDisconnect) {
sock.close();
return;
Modified: trunk/freenet/src/freenet/clients/http/TrivialToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/TrivialToadlet.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/TrivialToadlet.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -21,12 +21,8 @@
encFetched+"</a>.</body></html>";
this.writeReply(ctx, 200, "text/html", "OK", reply);
}
-
- public void handlePut(URI uri, Bucket data, ToadletContext ctx) throws
ToadletContextClosedException, IOException {
- String notSupported = "<html><head><title>Not
supported</title></head><body>"+
- "Operation not supported</body>";
- // This really should be 405, but then we'd have to put an
Allow header in.
- this.writeReply(ctx, 200, "text/html", "OK", notSupported);
+
+ public String supportedMethods() {
+ return "GET";
}
-
}
Added: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -0,0 +1,51 @@
+package freenet.clients.http;
+
+import java.io.IOException;
+import java.net.URI;
+
+import freenet.client.HighLevelSimpleClient;
+import freenet.support.Bucket;
+import freenet.support.HTMLEncoder;
+import freenet.support.MultiValueTable;
+import freenet.support.SimpleFieldSet;
+import freenet.node.Version;
+
+public class WelcomeToadlet extends Toadlet {
+ WelcomeToadlet(HighLevelSimpleClient client) {
+ super(client);
+ }
+
+ public void handleGet(URI uri, ToadletContext ctx) throws
ToadletContextClosedException, IOException {
+ StringBuffer buf = new StringBuffer();
+
+ ctx.getPageMaker().makeHead(buf, "Freenet FProxy Homepage");
+
+ // Version info
+ buf.append("<div class=\"infobox\">\n");
+ buf.append("<h2>Version</h2>");
+ buf.append("Freenet version "+Version.nodeVersion+" build
#"+Version.buildNumber());
+ if(Version.buildNumber() < Version.highestSeenBuild) {
+ buf.append("<br />");
+ buf.append("<b>A newer version is available! (Build
#"+Version.highestSeenBuild+")</b>");
+ }
+ buf.append("</div>\n");
+
+ // Fetch-a-key box
+ buf.append("<br style=\"clear: all; \" />\n");
+ buf.append("<form action=\"/\" method=\"get\">\n");
+ buf.append("<div class=\"infobox\">\n");
+ buf.append("<h2>Fetch a Key</h2>\n");
+ buf.append("Key: <input type=\"text\" size=\"100\"
name=\"key\"/>\n");
+ buf.append("<input type=\"submit\" value=\"Fetch\" />\n");
+ buf.append("</div>\n");
+ buf.append("</form>\n");
+
+ ctx.getPageMaker().makeTail(buf);
+
+ this.writeReply(ctx, 200, "text/html", "OK", buf.toString());
+ }
+
+ public String supportedMethods() {
+ return "GET";
+ }
+}
\ No newline at end of file
Added:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/background.png
===================================================================
(Binary files differ)
Property changes on:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/background.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/logo.png
===================================================================
(Binary files differ)
Property changes on:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/logo.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/theme.css
2006-03-05 21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/default/theme.css
2006-03-05 21:35:39 UTC (rev 8169)
@@ -0,0 +1,66 @@
+body {
+ margin: 10px;
+ border: 3px double #356ace;
+ background-image: url(/static/themes/default/background.png);
+ background-repeat: repeat;
+ padding: 10px;
+ padding-top: 0px;
+ min-height: 400px;
+}
+
+#topbar {
+ margin: 0px;
+ margin-bottom: 10px;
+ background-image: url(/static/themes/default/logo.png);
+ background-repeat: no-repeat;
+ background-position: top left;
+ min-height: 51px;
+ padding-left: 100px;
+}
+
+#navbar {
+ float: left;
+ border: 2px solid #5e88d8;
+ margin-right: 10px;
+ text-align: center;
+ padding: 5px;
+}
+
+#navlist {
+ display: inline;
+ margin: 0;
+ padding: 0;
+ text-align: center;
+}
+
+#navlist li {
+ display: inline;
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+ list-style-position: outside;
+ font-weight: bold;
+}
+
+#navlist a {
+ display: block;
+ color: black;
+}
+
+#navlist a:visited {
+ display: block;
+ color: black;
+}
+
+#navlist a:active {
+ display: block;
+ color: black;
+}
+
+.infobox {
+ border: 1px solid #5e88d8;
+ padding: 5px;
+ float: left;
+ margin-bottom: 10px;
+}
+
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-03-05 21:34:05 UTC (rev
8168)
+++ trunk/freenet/src/freenet/node/Version.java 2006-03-05 21:35:39 UTC (rev
8169)
@@ -20,7 +20,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 499;
+ private static final int buildNumber = 500;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 475;
Modified: trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java 2006-03-05
21:34:05 UTC (rev 8168)
+++ trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java 2006-03-05
21:35:39 UTC (rev 8169)
@@ -18,11 +18,13 @@
import freenet.clients.http.Toadlet;
import freenet.clients.http.ToadletContext;
import freenet.clients.http.ToadletContextClosedException;
+import freenet.clients.http.PageMaker;
import freenet.keys.FreenetURI;
import freenet.support.Bucket;
import freenet.support.Logger;
import freenet.support.URLDecoder;
import freenet.support.URLEncodedFormatException;
+import freenet.support.MultiValueTable;
public class PproxyToadlet extends Toadlet {
private PluginManager pm = null;
@@ -31,20 +33,11 @@
super(client);
this.pm = pm;
}
+
+ public String supportedMethods() {
+ return "GET";
+ }
- /**
- * TODO: Remove me eventually!!!!
- *
- * @param title
- * @param content
- * @return
- */
- private String mkPage(String title, String content) {
- if (content == null) content = "null";
- return "<html><head><title>" + title +
"</title></head><body><h1>"+
- title +"</h1>" + content + "</body>";
- }
-
private String mkForwardPage(String title, String content, String
nextpage, int interval) {
if (content == null) content = "null";
return "<html><head><title>" + title + "</title>"+
@@ -61,7 +54,7 @@
ks = URLDecoder.decode(uri.toString());
} catch (URLEncodedFormatException e) {
// TODO Auto-generated catch block
- writeReply(ctx, 500, "text/html", "OK",
mkPage("Internal Server Error", "Could not parse URI"));
+ this.sendErrorPage(ctx, 500, "Internal Server Error",
"Could not parse URI");
return;
}
@@ -72,12 +65,13 @@
try {
if (ks.equals("")) {
StringBuffer out = new StringBuffer();
+ ctx.getPageMaker().makeHead(out, "Plugin List");
out.append("<table style=\"border: 1pt solid
#c0c0c0;\">");
out.append(" <tr>\n");
- out.append(" <td
align=\"center\">Name</td>\n");
- out.append(" <td
align=\"center\">ID</td>\n");
- out.append(" <td
align=\"center\">Started</td>\n");
- out.append(" <td align=\"center\"></td>\n");
+ out.append(" <th>Name</th>\n");
+ out.append(" <th>ID</th>\n");
+ out.append(" <th>Started</th>\n");
+ out.append(" <th></th>\n");
out.append(" </tr>\n");
Iterator it = pm.getPlugins().iterator();
while (it.hasNext()) {
@@ -88,26 +82,48 @@
out.append(" <td style=\"border: 1pt
solid #c0c0c0;\">" + (new Date(pi.getStarted())) + "</td>\n");
out.append(" <td style=\"border: 1pt
solid #c0c0c0;\">");
if (pi.isPproxyPlugin())
- out.append(" <A
HREF=\""+pi.getPluginClassName()+"/\">[VISIT]</A> ");
- out.append(" <A
HREF=\"?remove="+pi.getThreadName()+"\">[UNLOAD]</A> ");
+ out.append(" <a
href=\""+pi.getPluginClassName()+"/\">[VISIT]</a> ");
+ out.append(" <a
href=\"?remove="+pi.getThreadName()+"\">[UNLOAD]</a> ");
out.append("</td>\n");
out.append(" </tr>\n");
}
+
+ if (pm.getPlugins().isEmpty()) {
+ out.append("<tr>\n");
+ out.append("<td colspan=\"4\"\n");
+ out.append("<i>No plugins
loaded</i>\n");
+ out.append("</td>\n");
+ out.append("</tr>\n");
+ }
+
out.append("</table>");
- String ret = "<hr/>" + out.toString();
+ //String ret = "<hr/>" + out.toString();
//ret = pm.dumpPlugins().replaceAll(",",
"\n ").replaceAll("\"", " \" ");
- if (ret.length() < 6)
+ /*if (ret.length() < 6)
ret += "<i>No plugins loaded</i>\n";
- ret += "<hr/>";
- ret += "<form method=\"GET\">Remove plugin:
(enter ID) <input type=text name=\"remove\" size=40/><input type=submit
value=\"Remove\"/></form>\n";
- ret += "<form method=\"GET\">Load plugin:
<input type=text name=\"load\" size=40/><input type=submit value=\"Load\"
/></form>\n";
- writeReply(ctx, 200, "text/html", "OK",
mkPage("Plugin list", ret));
+ ret += "<hr/>";*/
+
+
+ // Obsolete
+ //out.append("<form method=\"get\"><div>Remove
plugin: (enter ID) <input type=\"text\" name=\"remove\" size=40/><input
type=\"submit\" value=\"Remove\"/></div></form>\n");
+ out.append("<form method=\"get\"
action=\".\"><div>Load plugin: <input type=\"text\" name=\"load\"
size=\"40\"/><input type=\"submit\" value=\"Load\" /></div></form>\n");
+ ctx.getPageMaker().makeTail(out);
+ writeReply(ctx, 200, "text/html", "OK",
out.toString());
} else if (ks.startsWith("?remove=")) {
pm.killPlugin(ks.substring("?remove=".length()));
- writeReply(ctx, 200, "text/html", "OK",
mkForwardPage("Removing plugin", "Removing plugin...", ".", 5));
+
+ MultiValueTable headers = new MultiValueTable();
+
+ headers.put("Location", ".");
+ ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
+ //writeReply(ctx, 200, "text/html", "OK",
mkForwardPage("Removing plugin", "Removing plugin...", ".", 5));
} else if (ks.startsWith("?load=")) {
pm.startPlugin(ks.substring("?load=".length()));
- writeReply(ctx, 200, "text/html", "OK",
mkForwardPage("Loading plugin", "Loading plugin...", ".", 5));
+ //writeReply(ctx, 200, "text/html", "OK",
mkForwardPage("Loading plugin", "Loading plugin...", ".", 5));
+ MultiValueTable headers = new MultiValueTable();
+
+ headers.put("Location", ".");
+ ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
} else {
int to = ks.indexOf("/");
String plugin, data;
@@ -145,13 +161,4 @@
this.writeReply(ctx, 500, "text/html", "Internal
Error", msg);
}
}
-
- public void handlePut(URI uri, Bucket data, ToadletContext ctx)
- throws ToadletContextClosedException, IOException {
- String notSupported = "<html><head><title>Not
supported</title></head><body>"+
- "Operation not supported</body>";
- // FIXME should be 405? Need to let toadlets indicate what is
allowed maybe in a callback?
- super.writeReply(ctx, 200, "text/html", "OK", notSupported);
- }
-
}