Author: toad
Date: 2006-03-14 01:59:27 +0000 (Tue, 14 Mar 2006)
New Revision: 8245

Modified:
   trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
   trunk/freenet/src/freenet/clients/http/FproxyToadlet.java
   trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
   trunk/freenet/src/freenet/clients/http/Toadlet.java
   trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
   trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/pluginmanager/HTTPRequest.java
   trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java
Log:
535:
Implement HTTP post.
Attackers (and prefetchers!) can no longer do all manner of horrible things via 
long get URLs; all dangerous stuff (except plugin unloading) is done through 
POST forms now.

Modified: trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2006-03-14 
00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2006-03-14 
01:59:27 UTC (rev 8245)
@@ -2,21 +2,16 @@

 import java.io.IOException;
 import java.net.URI;
+import java.net.URISyntaxException;

-import sun.net.dns.ResolverConfiguration.Options;
-
 import freenet.client.HighLevelSimpleClient;
 import freenet.config.Config;
-import freenet.config.FilePersistentConfig;
 import freenet.config.Option;
 import freenet.config.SubConfig;
+import freenet.pluginmanager.HTTPRequest;
 import freenet.support.Bucket;
-import freenet.support.HTMLEncoder;
-import freenet.support.MultiValueTable;
-import freenet.support.SimpleFieldSet;
-import freenet.node.Node;
-import freenet.node.Version;
-import freenet.pluginmanager.HTTPRequest;
+import freenet.support.BucketTools;
+import freenet.support.Logger;


 // FIXME: add logging, comments
@@ -28,84 +23,100 @@
                config=conf;
        }

-       public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
+       public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
                StringBuffer buf = new StringBuffer();
                SubConfig[] sc = config.getConfigs();

-               HTTPRequest request = new HTTPRequest(uri);
-               if (request.hasParameters() == false) {
-                       ctx.getPageMaker().makeHead(buf, "Freenet Node 
Configuration", CSSName);
-                       buf.append("<h1 class=\"title\">Node 
Configuration</h1>\n");
-                       buf.append("<div class=\"config\">\n");
-                       buf.append("    <ul class=\"config\">\n");
-                       // FIXME: Use POST insteed !
-                       buf.append("<form method=\"get\">");
-                       String last = null;
+               if(data.size() > 1024*1024) {
+                       this.writeReply(ctx, 400, "text/plain", "Too big", "Too 
much data, config servlet limited to 1MB");
+                       return;
+               }
+               byte[] d = BucketTools.toByteArray(data);
+               String s = new String(d, "us-ascii");
+               HTTPRequest request;
+               try {
+                       request = new HTTPRequest("/", s);
+               } catch (URISyntaxException e) {
+                       Logger.error(this, "Impossible: "+e, e);
+                       return;
+               }
+               for(int i=0; i<sc.length ; i++){
+                       Option[] o = sc[i].getOptions();
+                       String prefix = new String(sc[i].getPrefix());
+                       String configName;

-                       for(int i=0; i<sc.length;i++){
-                               Option[] o = sc[i].getOptions();
-                               String prefix = new String(sc[i].getPrefix());
+                       for(int j=0; j<o.length; j++){
+                               configName=o[j].getName();
+                               Logger.minor(this, "Setting 
"+prefix+"."+configName);

-                               if(last == null || ! 
last.equalsIgnoreCase(prefix)){
-                                       buf.append("</p>\n");
-                                       buf.append("</span>\n");
-                                       buf.append("<span 
id=\""+prefix+"\">\n");
-                                       buf.append("<p>\n");
-                               }
-                               
-                               for(int j=0; j<o.length; j++){
-                                       String configName = new 
String(o[j].getName());
-                                       /*
-                                       if(prefix.equals("node") && 
configName.equals("name")){
-                                               buf.append("<form 
method=\"post\"><input alt=\"node name\" class=\"config\"" +
-                                                               " type=\"text\" 
name=\"__node_name\" value=\""+o[j].getValueString()+"\"/></form>\n");
+                               // we ignore unreconized parameters 
+                               if(request.getParam(prefix+"."+configName) != 
""){
+                                       
if(!(o[j].getValueString().equals(request.getParam(prefix+"."+configName)))){
+                                               Logger.minor(this, "Setting 
"+prefix+"."+configName+" to "+request.getParam(prefix+"."+configName));
+                                               try{
+                                                       
o[j].setValue(request.getParam(prefix+"."+configName));
+                                               }catch(Exception e){
+                                                       
buf.append(o[j].getName()+" "+e+"\n");
+                                               }
                                        }
-                                       */
-                                               
-                                       buf.append(o[j].getShortDesc()+":\n");
-                                       buf.append("            
<li>"+prefix+"."+configName+"=><input alt=\""+o[j].getShortDesc()+"\" 
class=\"config\"" +
-                                                       " type=\"text\" 
name=\""+prefix+"."+configName+"\" 
value=\""+o[j].getValueString()+"\"></li>\n");
                                }
-                               
-                               buf.append("<br><hr>");
                        }
+               }
+               config.store();
+               writeReply(ctx, 200, "text/html", "OK", mkForwardPage(ctx, 
"Applying configuration", buf.toString(), "/config/", 10));
+               
+       }
+       
+       public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
+               StringBuffer buf = new StringBuffer();
+               SubConfig[] sc = config.getConfigs();
+               
+               HTTPRequest request = new HTTPRequest(uri);
+               ctx.getPageMaker().makeHead(buf, "Freenet Node Configuration", 
CSSName);
+               buf.append("<h1 class=\"title\">Node Configuration</h1>\n");
+               buf.append("<div class=\"config\">\n");
+               buf.append("    <ul class=\"config\">\n");
+               buf.append("<form method=\"post\">");
+               String last = null;
+               
+               for(int i=0; i<sc.length;i++){
+                       Option[] o = sc[i].getOptions();
+                       String prefix = new String(sc[i].getPrefix());

-                       buf.append("<br>");
-                       buf.append("<input type=\"submit\" value=\"Apply\">");
-                       buf.append("<input type=\"reset\" value=\"Cancel\">");
-                       buf.append("</form>");
-                       buf.append("    </ul>\n");
-                       buf.append("</div>\n");
+                       if(last == null || ! last.equalsIgnoreCase(prefix)){
+                               buf.append("</p>\n");
+                               buf.append("</span>\n");
+                               buf.append("<span id=\""+prefix+"\">\n");
+                               buf.append("<p>\n");
+                       }

-                       ctx.getPageMaker().makeTail(buf);
+                       for(int j=0; j<o.length; j++){
+                               String configName = new String(o[j].getName());
+                               /*
+                               if(prefix.equals("node") && 
configName.equals("name")){
+                                       buf.append("<form 
method=\"post\"><input alt=\"node name\" class=\"config\"" +
+                                                       " type=\"text\" 
name=\"__node_name\" value=\""+o[j].getValueString()+"\"/></form>\n");
+                               }
+                               */
+                                       
+                               buf.append(o[j].getShortDesc()+":\n");
+                               buf.append("            
<li>"+prefix+"."+configName+"=><input alt=\""+o[j].getShortDesc()+"\" 
class=\"config\"" +
+                                               " type=\"text\" 
name=\""+prefix+"."+configName+"\" 
value=\""+o[j].getValueString()+"\"></li>\n");
+                       }

-                       this.writeReply(ctx, 200, "text/html", "OK", 
buf.toString());
+                       buf.append("<br><hr>");
+               }

-               } else {
-                       return;
-//                     for(int i=0; i<sc.length ; i++){
-//                             Option[] o = sc[i].getOptions();
-//                             String prefix = new String(sc[i].getPrefix());
-//                             String configName;
-//                             
-//                             for(int j=0; j<o.length; j++){
-//                                     configName=o[j].getName();
-//                                     
-//                                     // we ignore unreconized parameters 
-//                                     
if(request.getParam(prefix+"."+configName) != ""){
-//                                             if(o[j].getValueString() != 
request.getParam(prefix+"."+configName)){
-//                                                     try{
-//                                                             
o[j].setValue(request.getParam(prefix+"."+configName));
-//                                                     }catch(Exception e){
-//                                                             
buf.append(o[j].getName()+" "+e+"\n");
-//                                                     }
-//                                             }
-//                                     }
-//                             }
-//                     }
-//                     config.store();
-//                     writeReply(ctx, 200, "text/html", "OK", 
mkForwardPage(ctx, "Applying configuration", buf.toString(), "/config/", 10));
-               }
+               buf.append("<br>");
+               buf.append("<input type=\"submit\" value=\"Apply\">");
+               buf.append("<input type=\"reset\" value=\"Cancel\">");
+               buf.append("</form>");
+               buf.append("    </ul>\n");
+               buf.append("</div>\n");
+               
+               ctx.getPageMaker().makeTail(buf);
+               
+               this.writeReply(ctx, 200, "text/html", "OK", buf.toString());
        }

        public void handlePut(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {

Modified: trunk/freenet/src/freenet/clients/http/FproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FproxyToadlet.java   2006-03-14 
00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/clients/http/FproxyToadlet.java   2006-03-14 
01:59:27 UTC (rev 8245)
@@ -21,6 +21,8 @@
 import freenet.node.RequestStarter;
 import freenet.pluginmanager.HTTPRequest;
 import freenet.pluginmanager.PproxyToadlet;
+import freenet.support.Bucket;
+import freenet.support.BucketTools;
 import freenet.support.HTMLEncoder;
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
@@ -35,12 +37,21 @@
                return "GET";
        }

-       public void handleGet(URI uri, ToadletContext ctx) 
-                       throws ToadletContextClosedException, IOException, 
RedirectException {
-               //String ks = uri.toString();
-               String ks = uri.getPath();
+       public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {

-               HTTPRequest request = new HTTPRequest(uri);
+               if(data.size() > 1024*1024) {
+                       this.writeReply(ctx, 400, "text/plain", "Too big", "Too 
much data, config servlet limited to 1MB");
+                       return;
+               }
+               byte[] d = BucketTools.toByteArray(data);
+               String s = new String(d, "us-ascii");
+               HTTPRequest request;
+               try {
+                       request = new HTTPRequest("/", s);
+               } catch (URISyntaxException e) {
+                       Logger.error(this, "Impossible: "+e, e);
+                       return;
+               }

                if(request.hasParameters() && 
request.getParam("exit").equalsIgnoreCase("true")){       
                        System.out.println("Goodbye.");
@@ -48,6 +59,15 @@
                        System.exit(0);
                }

+       }
+       
+       public void handleGet(URI uri, ToadletContext ctx) 
+                       throws ToadletContextClosedException, IOException, 
RedirectException {
+               //String ks = uri.toString();
+               String ks = uri.getPath();
+               
+               HTTPRequest request = new HTTPRequest(uri);
+               
                if (ks.equals("/")) {
                        HTTPRequest httprequest = new HTTPRequest(uri);
                        if (httprequest.isParameterSet("key")) {
@@ -208,7 +228,7 @@
                Logger.normal(node,"Starting fproxy on "+bind_ip+":"+port);

                try {
-                       SimpleToadletServer server = new 
SimpleToadletServer(port, bind_ip);
+                       SimpleToadletServer server = new 
SimpleToadletServer(port, bind_ip, node.tempBucketFactory);
                        node.setToadletContainer(server);
                        FproxyToadlet fproxy = new 
FproxyToadlet(node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS), 
CSSName);
                        node.setFproxy(fproxy);

Modified: trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2006-03-14 00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2006-03-14 01:59:27 UTC (rev 8245)
@@ -13,11 +13,15 @@
 import freenet.config.Config;
 import freenet.config.InvalidConfigValueException;
 import freenet.config.SubConfig;
+import freenet.crypt.DummyRandomSource;
 import freenet.node.Node;
 import freenet.node.RequestStarter;
+import freenet.support.BucketFactory;
 import freenet.support.FileLoggerHook;
 import freenet.support.Logger;
 import freenet.support.FileLoggerHook.IntervalParseException;
+import freenet.support.io.FilenameGenerator;
+import freenet.support.io.TempBucketFactory;

 public class SimpleToadletServer implements ToadletContainer, Runnable {

@@ -32,12 +36,14 @@

        final int port;
        final String bindto;
+       final BucketFactory bf;
        private final ServerSocket sock;
        private final LinkedList toadlets;

-       public SimpleToadletServer(int i, String newbindto) throws IOException {
+       public SimpleToadletServer(int i, String newbindto, BucketFactory bf) 
throws IOException {
                this.port = i;
                this.bindto = newbindto;
+               this.bf = bf;
                this.sock = new ServerSocket(port, 0, 
InetAddress.getByName(this.bindto));
                toadlets = new LinkedList();
                Thread t = new Thread(this, "SimpleToadletServer");
@@ -74,7 +80,7 @@
         Logger.globalSetThreshold(Logger.MINOR);
         Logger.globalAddHook(logger);
         logger.start();
-               SimpleToadletServer server = new SimpleToadletServer(1111, 
"127.0.0.1");
+               SimpleToadletServer server = new SimpleToadletServer(1111, 
"127.0.0.1", new TempBucketFactory(new FilenameGenerator(new 
DummyRandomSource(), true, new File("temp-test"), "test-temp-")));
                server.register(new TrivialToadlet(null,null), "", true);
                System.out.println("Bound to port 1111.");
                while(true) {
@@ -113,7 +119,7 @@

                public void run() {
                        Logger.minor(this, "Handling connection");
-                       ToadletContextImpl.handle(sock, 
SimpleToadletServer.this);
+                       ToadletContextImpl.handle(sock, 
SimpleToadletServer.this, bf);
                        Logger.minor(this, "Handled connection");
                }


Modified: trunk/freenet/src/freenet/clients/http/Toadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Toadlet.java 2006-03-14 00:45:50 UTC 
(rev 8244)
+++ trunk/freenet/src/freenet/clients/http/Toadlet.java 2006-03-14 01:59:27 UTC 
(rev 8245)
@@ -12,6 +12,8 @@
 import freenet.client.InserterException;
 import freenet.keys.FreenetURI;
 import freenet.support.Bucket;
+import freenet.support.BucketTools;
+import freenet.support.Logger;
 import freenet.support.MultiValueTable;

 /**
@@ -80,6 +82,21 @@
                ctx.writeData(buf.toString().getBytes(), 0, buf.length());
        }

+       public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException, RedirectException {
+               StringBuffer buf = new StringBuffer();
+               
+               ctx.getPageMaker().makeHead(buf, "Not supported", CSSName);
+               
+               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());
+               Logger.minor(this, "POSTed data to 
"+uri+":\n"+BucketTools.toByteArray(data));
+       }
+       
        /**
         * Which methods are supported by this Toadlet.
         * Should return a string containing the methods supported, separated 
by commas
@@ -162,4 +179,5 @@
        public String getCSSName(){
                return CSSName;
        }
+
 }

Modified: trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java      
2006-03-14 00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java      
2006-03-14 01:59:27 UTC (rev 8245)
@@ -10,6 +10,7 @@

 import freenet.config.Config;
 import freenet.support.Bucket;
+import freenet.support.BucketFactory;
 import freenet.support.BucketTools;
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
@@ -121,7 +122,7 @@
        /**
         * Handle an incoming connection. Blocking, obviously.
         */
-       public static void handle(Socket sock, ToadletContainer container) {
+       public static void handle(Socket sock, ToadletContainer container, 
BucketFactory bf) {
                try {
                        InputStream is = sock.getInputStream();

@@ -177,7 +178,7 @@
                                        if (index < 0) {
                                                throw new 
ParseException("Missing ':' in request header field");
                                        }
-                                       String before = line.substring(0, 
index);
+                                       String before = line.substring(0, 
index).toLowerCase();
                                        String after = line.substring(index+1);
                                        after = after.trim();
                                        headers.put(before, after);
@@ -217,11 +218,29 @@
                                                }

                                        } else if(method.equals("POST")) {
+                                               String slen = (String) 
headers.get("content-length");
+                                               if(slen == null) {
+                                                       
sendError(sock.getOutputStream(), 400, "No content-length in POST", true, null);
+                                                       return;
+                                               }
+                                               long len;
+                                               try {
+                                                       len = 
Integer.parseInt(slen);
+                                                       if(len < 0) throw new 
NumberFormatException("content-length less than 0");
+                                               } catch (NumberFormatException 
e) {
+                                                       
sendError(sock.getOutputStream(), 400, "content-length parse error: "+e, true, 
null);
+                                                       return;
+                                               }
+                                               Bucket data = 
bf.makeBucket(len);
+                                               BucketTools.copyFrom(data, is, 
len);
+
+                                               try {
+                                                       t.handlePost(uri, data, 
ctx);
+                                               } catch (RedirectException re) {
+                                                       uri = re.newuri;
+                                                       redirect = true;
+                                               }

-                                               
Logger.error(ToadletContextImpl.class, "POST not supported");
-                                               
ctx.sendMethodNotAllowed(method, shouldDisconnect);
-                                               ctx.close();
-                                               
                                        } else {
                                                
ctx.sendMethodNotAllowed(method, shouldDisconnect);
                                                ctx.close();

Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-03-14 
00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-03-14 
01:59:27 UTC (rev 8245)
@@ -2,11 +2,14 @@

 import java.io.IOException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.text.Format.Field;

 import freenet.client.HighLevelSimpleClient;
 import freenet.support.Bucket;
+import freenet.support.BucketTools;
 import freenet.support.HTMLEncoder;
+import freenet.support.Logger;
 import freenet.support.MultiValueTable;
 import freenet.support.SimpleFieldSet;
 import freenet.node.Version;
@@ -21,59 +24,74 @@
                this.node = n;
        }

+       public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
+               
+               if(data.size() > 1024*1024) {
+                       this.writeReply(ctx, 400, "text/plain", "Too big", "Too 
much data, config servlet limited to 1MB");
+                       return;
+               }
+               byte[] d = BucketTools.toByteArray(data);
+               String s = new String(d, "us-ascii");
+               HTTPRequest request;
+               try {
+                       request = new HTTPRequest("/", s);
+               } catch (URISyntaxException e) {
+                       Logger.error(this, "Impossible: "+e, e);
+                       return;
+               }
+               
+               if(request.hasParameters() && 
request.getParam("exit").equalsIgnoreCase("true")){       
+                       System.out.println("Goodbye.");
+                       writeReply(ctx, 200, "text/html", "OK", 
mkForwardPage(ctx, "Shutting down the node", "" , "/", 5));
+                       System.exit(0);
+               }
+               
+       }
+       
        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
                StringBuffer buf = new StringBuffer();
                HTTPRequest request = new HTTPRequest(uri);

-               if(request.hasParameters()){
-                       if(request.getParam("exit").equalsIgnoreCase("true")){
-                   System.out.println("Goodbye.");
-                   writeReply(ctx, 200, "text/html", "OK", mkForwardPage(ctx, 
"Shutting down the node", buf.toString(), "/", 60));
-                   System.exit(0);
-                       }
-                       System.out.println(request.toString());
-               }else{
-                       
-                       ctx.getPageMaker().makeHead(buf, "Freenet FProxy 
Homepage", CSSName);
-                       
-                       // 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=\"80\" 
name=\"key\"/>\n");
-                       buf.append("<input type=\"submit\" value=\"Fetch\" 
/>\n");
-                       buf.append("</div>\n");
-                       buf.append("</form>\n");
-                       
-                       // Quit Form
-                       buf.append("<div class=\"exit\" target=\".\">\n");
-                       buf.append("<form>\n");
-                       buf.append("<input type=\"hidden\" name=\"exit\" 
value=\"true\"><input type=\"submit\" value=\"Shutdown the node\">\n");
-                       buf.append("</form>\n");
-                       buf.append("</div>\n");
-                       
-                       // Activity
-                       buf.append("<ul id=\"activity\">\n"
-                                       + "<li>Inserts: 
"+this.node.getNumInserts()+"</li>\n"
-                                       + "<li>Requests: 
"+this.node.getNumRequests()+"</li>\n"
-                                       + "<li>Transferring Requests: 
"+this.node.getNumTransferringRequests()+"</li>\n"
-                                       + "</ul>\n");
-                       
-                       ctx.getPageMaker().makeTail(buf);
-                       
-                       this.writeReply(ctx, 200, "text/html", "OK", 
buf.toString());
+               
+               ctx.getPageMaker().makeHead(buf, "Freenet FProxy Homepage", 
CSSName);
+               
+               // 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=\"80\" 
name=\"key\"/>\n");
+               buf.append("<input type=\"submit\" value=\"Fetch\" />\n");
+               buf.append("</div>\n");
+               buf.append("</form>\n");
+               
+               // Quit Form
+               buf.append("<div class=\"exit\" target=\".\">\n");
+               buf.append("<form method=\"post\">\n");
+               buf.append("<input type=\"hidden\" name=\"exit\" 
value=\"true\"><input type=\"submit\" value=\"Shutdown the node\">\n");
+               buf.append("</form>\n");
+               buf.append("</div>\n");
+               
+               // Activity
+               buf.append("<ul id=\"activity\">\n"
+                               + "<li>Inserts: 
"+this.node.getNumInserts()+"</li>\n"
+                               + "<li>Requests: 
"+this.node.getNumRequests()+"</li>\n"
+                               + "<li>Transferring Requests: 
"+this.node.getNumTransferringRequests()+"</li>\n"
+                               + "</ul>\n");
+               
+               ctx.getPageMaker().makeTail(buf);
+               
+               this.writeReply(ctx, 200, "text/html", "OK", buf.toString());
        }

        public String supportedMethods() {

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-03-14 00:45:50 UTC (rev 
8244)
+++ trunk/freenet/src/freenet/node/Version.java 2006-03-14 01:59:27 UTC (rev 
8245)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 534;
+       private static final int buildNumber = 535;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 507;

Modified: trunk/freenet/src/freenet/pluginmanager/HTTPRequest.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/HTTPRequest.java    2006-03-14 
00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/pluginmanager/HTTPRequest.java    2006-03-14 
01:59:27 UTC (rev 8245)
@@ -9,6 +9,7 @@
 import java.util.Map;
 import java.util.StringTokenizer;

+import freenet.support.Logger;
 import freenet.support.URLDecoder;
 import freenet.support.URLEncodedFormatException;

@@ -93,6 +94,8 @@
         */
        private void parseRequestParameters(String queryString, boolean 
doUrlDecoding) {

+               Logger.minor(this, "queryString is "+queryString+", 
doUrlDecoding="+doUrlDecoding);
+               
                // nothing to do if there was no query string in the URI
                if (queryString == null || queryString.length() == 0) {
                        return;
@@ -102,6 +105,8 @@
                StringTokenizer tokenizer = new StringTokenizer(queryString, 
"&");
                while (tokenizer.hasMoreTokens()) {
                        String nameValueToken = tokenizer.nextToken();
+                       
+                       Logger.minor(this, "Token: "+nameValueToken);

                        // a token can be either a name, or a name value pair...
                        String name = null;
@@ -110,14 +115,17 @@
                        if (indexOfEqualsChar < 0) {
                                // ...it's only a name, so the value stays 
emptys
                                name = nameValueToken;
+                               Logger.minor(this, "Name: "+name);
                        } else if (indexOfEqualsChar == nameValueToken.length() 
- 1) {
                                // ...it's a name with an empty value, so 
remove the '='
                                // character
                                name = nameValueToken.substring(0, 
indexOfEqualsChar);
+                               Logger.minor(this, "Name: "+name);
                        } else {
                                // ...it's a name value pair, split into name 
and value
                                name = nameValueToken.substring(0, 
indexOfEqualsChar);
                                value = 
nameValueToken.substring(indexOfEqualsChar + 1);
+                               Logger.minor(this, "Name: "+name+" Value: 
"+value);
                        }

                        // url-decode the name and value
@@ -125,6 +133,8 @@
                                if (doUrlDecoding) {
                                        name = URLDecoder.decode(name);
                                        value = URLDecoder.decode(value);
+                                       Logger.minor(this, "Decoded name: 
"+name);
+                                       Logger.minor(this, "Decoded value: 
"+value);
                                }

                                // get the list of values for this parameter 
that were parsed so

Modified: trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java  2006-03-14 
00:45:50 UTC (rev 8244)
+++ trunk/freenet/src/freenet/pluginmanager/PproxyToadlet.java  2006-03-14 
01:59:27 UTC (rev 8245)
@@ -4,6 +4,7 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Date;
 import java.util.Iterator;

@@ -11,6 +12,8 @@
 import freenet.clients.http.Toadlet;
 import freenet.clients.http.ToadletContext;
 import freenet.clients.http.ToadletContextClosedException;
+import freenet.support.Bucket;
+import freenet.support.BucketTools;
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;

@@ -23,8 +26,41 @@
        }

        public String supportedMethods() {
-               return "GET";
+               return "GET, POST";
        }
+
+       public void handlePost(URI uri, Bucket data, ToadletContext ctx)
+               throws ToadletContextClosedException, IOException {
+               
+               if(data.size() > 1024*1024) {
+                       this.writeReply(ctx, 400, "text/plain", "Too big", "Too 
much data, config servlet limited to 1MB");
+                       return;
+               }
+               byte[] d = BucketTools.toByteArray(data);
+               String s = new String(d, "us-ascii");
+               HTTPRequest request;
+               try {
+                       request = new HTTPRequest("/", s);
+               } catch (URISyntaxException e) {
+                       Logger.error(this, "Impossible: "+e, e);
+                       return;
+               }
+               
+               if (request.isParameterSet("load")) {
+                       pm.startPlugin(request.getParam("load"));
+                       //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 {
+                       // Ignore
+                       MultiValueTable headers = new MultiValueTable();
+                       headers.put("Location", ".");
+                       ctx.sendReplyHeaders(302, "Found", headers, null, 0);
+               }
+
+       }

        public void handleGet(URI uri, ToadletContext ctx)
                        throws ToadletContextClosedException, IOException {
@@ -125,7 +161,7 @@

                        // 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");
+                       out.append("<form method=\"post\" 
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 (request.isParameterSet("remove")) {
@@ -136,13 +172,6 @@
                        headers.put("Location", ".");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        //writeReply(ctx, 200, "text/html", "OK", 
mkForwardPage("Removing plugin", "Removing plugin...", ".", 5));
-               } else if (request.isParameterSet("load")) {
-                       pm.startPlugin(request.getParam("load"));
-                       //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 if (request.isParameterSet("reload")) {
                        String fn = null;
                        Iterator it = pm.getPlugins().iterator();


Reply via email to