Author: toad
Date: 2006-12-15 21:55:54 +0000 (Fri, 15 Dec 2006)
New Revision: 11425

Added:
   trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java
   trunk/freenet/src/freenet/plugin/api/NeedsWebInterfaceHTMLString.java
   trunk/freenet/src/freenet/support/api/HTTPRequest.java
   trunk/freenet/src/freenet/support/api/HTTPUploadedFile.java
Removed:
   trunk/freenet/src/freenet/clients/http/HTTPRequest.java
Modified:
   trunk/freenet/src/freenet/clients/http/BrowserTestToadlet.java
   trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
   trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
   trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
   trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java
   trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
   trunk/freenet/src/freenet/clients/http/NinjaSpider.java
   trunk/freenet/src/freenet/clients/http/PluginToadlet.java
   trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
   trunk/freenet/src/freenet/clients/http/QueueToadlet.java
   trunk/freenet/src/freenet/clients/http/Spider.java
   trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
   trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
   trunk/freenet/src/freenet/oldplugins/plugin/HttpPlugin.java
   trunk/freenet/src/freenet/oldplugins/plugin/TestHttpPlugin.java
   trunk/freenet/src/freenet/pluginmanager/FredPluginHTTP.java
   trunk/freenet/src/freenet/pluginmanager/PluginManager.java
   trunk/plugins/Librarian/Librarian.java
   trunk/plugins/TestGallery/TestGallery.java
Log:
Extract base interface for HTTPRequest and HTTPRequest.File.
Use it to define freenet.plugin.api.NeedsWebInterfaceHTMLString.

Modified: trunk/freenet/src/freenet/clients/http/BrowserTestToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/BrowserTestToadlet.java      
2006-12-15 21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/BrowserTestToadlet.java      
2006-12-15 21:55:54 UTC (rev 11425)
@@ -6,6 +6,7 @@
 import freenet.client.HighLevelSimpleClient;
 import freenet.node.NodeClientCore;
 import freenet.support.HTMLNode;
+import freenet.support.api.HTTPRequest;

 /**
  * Browser Test Toadlet.
@@ -175,7 +176,7 @@

        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
                final boolean advancedEnabled = core.isAdvancedDarknetEnabled();
-               HTTPRequest request = new HTTPRequest(uri);
+               HTTPRequest request = new HTTPRequestImpl(uri);

                // Yes, we need that in order to test the browser (number of 
connections per server)
                if (request.isParameterSet("wontload")) return;

Modified: trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2006-12-15 
21:55:54 UTC (rev 11425)
@@ -17,6 +17,7 @@
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;


 // FIXME: add logging, comments
@@ -38,7 +39,7 @@
                StringBuffer errbuf = new StringBuffer();
                SubConfig[] sc = config.getConfigs();

-               HTTPRequest request = new HTTPRequest(uri, data, ctx);
+               HTTPRequest request = new HTTPRequestImpl(uri, data, ctx);

                String pass = request.getPartAsString("formPassword", 32);
                if((pass == null) || !pass.equals(core.formPassword)) {

Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-12-15 21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-12-15 21:55:54 UTC (rev 11425)
@@ -36,6 +36,7 @@
 import freenet.support.SizeUtil;
 import freenet.support.TimeUtil;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 public class DarknetConnectionsToadlet extends Toadlet {

@@ -54,7 +55,7 @@
        }

        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException, RedirectException {
-               final HTTPRequest request = new HTTPRequest(uri);
+               final HTTPRequest request = new HTTPRequestImpl(uri);

                String path = uri.getPath();
                if(path.endsWith("myref.fref")) {
@@ -616,7 +617,7 @@
                        return;
                }

-               HTTPRequest request = new HTTPRequest(uri, data, ctx);
+               HTTPRequest request = new HTTPRequestImpl(uri, data, ctx);

                boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);


Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2006-12-15 
21:55:54 UTC (rev 11425)
@@ -37,6 +37,7 @@
 import freenet.support.URLEncoder;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
+import freenet.support.api.HTTPRequest;

 public class FProxyToadlet extends Toadlet {

@@ -253,7 +254,7 @@
                //String ks = uri.toString();
                String ks = uri.getPath();

-               HTTPRequest httprequest = new HTTPRequest(uri);
+               HTTPRequest httprequest = new HTTPRequestImpl(uri);

                if (ks.equals("/")) {
                        if (httprequest.isParameterSet("key")) {
@@ -462,7 +463,7 @@
                                String path = refererURI.getPath();
                                while(path.startsWith("/")) path = 
path.substring(1);
                                FreenetURI furi = new FreenetURI(path);
-                               HTTPRequest req = new HTTPRequest(refererURI);
+                               HTTPRequest req = new 
HTTPRequestImpl(refererURI);
                                String type = req.getParam("type");
                                referer = "/" + furi.toString();
                                if(type != null && type.length() > 0)

Deleted: trunk/freenet/src/freenet/clients/http/HTTPRequest.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/HTTPRequest.java     2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/HTTPRequest.java     2006-12-15 
21:55:54 UTC (rev 11425)
@@ -1,678 +0,0 @@
-/* This code is part of Freenet. It is distributed under the GNU General
- * Public License, version 2 (or at your option any later version). See
- * http://www.gnu.org/ for further details of the GPL. */
-package freenet.clients.http;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import freenet.support.Logger;
-import freenet.support.MultiValueTable;
-import freenet.support.SimpleReadOnlyArrayBucket;
-import freenet.support.URLEncodedFormatException;
-import freenet.support.api.Bucket;
-import freenet.support.api.BucketFactory;
-import freenet.support.io.BucketTools;
-import freenet.support.io.LineReadingInputStream;
-
-/**
- * Used for passing all HTTP request information to the FredPlugin that handles
- * the request. It parses the query string and has several methods for acessing
- * the request parameter values.
- * 
- * @author nacktschneck
- */
-public class HTTPRequest {
-
-       /**
-        * This map is used to store all parameter values. The name (as String) 
of
-        * the parameter is used as key, the returned value is a list (of 
Strings)
-        * with all values for that parameter sent in the request. You shouldn't
-        * access this map directly, use {@link #getParameterValueList(String)} 
and
-        * {@link #isParameterSet(String)} insted
-        */
-       private final Map parameterNameValuesMap = new HashMap();
-
-       /**
-        * the original URI as given to the constructor
-        */
-       private URI uri;
-       
-       /**
-        * The headers sent by the client
-        */
-       private MultiValueTable headers;
-       
-       /**
-        * The data sent in the connection
-        */
-       private Bucket data;
-       
-       /**
-        * A hasmap of buckets that we use to store all the parts for a 
multipart/form-data request
-        */
-       private HashMap parts;
-       
-       /** A map for uploaded files. */
-       private Map uploadedFiles = new HashMap();
-       
-       private final BucketFactory bucketfactory;
-
-       /**
-        * Create a new HTTPRequest for the given URI and parse its request
-        * parameters.
-        * 
-        * @param uri
-        *            the URI being requested
-        */
-       public HTTPRequest(URI uri) {
-               this.uri = uri;
-               this.parseRequestParameters(uri.getRawQuery(), true, false);
-               this.data = null;
-               this.parts = null;
-               this.bucketfactory = null;
-       }
-
-       /**
-        * Creates a new HTTPRequest for the given path and url-encoded query 
string
-        * 
-        * @param path i.e. /test/test.html
-        * @param encodedQueryString a=some+text&b=abc%40def.de
-        * @throws URISyntaxException if the URI is invalid
-        */
-       public HTTPRequest(String path, String encodedQueryString) throws 
URISyntaxException {
-               this.data = null;
-               this.parts = null;
-               this.bucketfactory = null;
-               if ((encodedQueryString!=null) && 
(encodedQueryString.length()>0)) {
-                       this.uri = new URI(path+ '?' +encodedQueryString);
-               } else {
-                       this.uri = new URI(path);
-               }
-               this.parseRequestParameters(uri.getRawQuery(), true, false);
-       }
-       
-       /**
-        * Creates a new HTTPRequest for the given URI and data.
-        * 
-        * @param uri The URI being requested
-        * @param h Client headers
-        * @param d The data
-        * @param ctx The toadlet context (for headers and bucket factory)
-        * @throws URISyntaxException if the URI is invalid
-        */
-       public HTTPRequest(URI uri, Bucket d, ToadletContext ctx) {
-               this.uri = uri;
-               this.headers = ctx.getHeaders();
-               this.parseRequestParameters(uri.getRawQuery(), true, false);
-               this.data = d;
-               this.parts = new HashMap();
-               this.bucketfactory = ctx.getBucketFactory();
-               try {
-                       this.parseMultiPartData();
-               } catch (IOException ioe) {
-                       
-               }
-       }
-       
-
-       /**
-        * The path of this request, where the part of the path the specified 
the
-        * plugin has already been removed..
-        */
-       public String getPath() {
-               return this.uri.getPath();
-       }
-
-
-       /**
-        * 
-        * @return true if the query string was totally empty
-        */
-       public boolean hasParameters() {
-               return ! this.parameterNameValuesMap.isEmpty();
-       }
-
-       /**
-        * Parse the query string and populate {@link #parameterNameValuesMap} 
with
-        * the lists of values for each parameter. If this method is not called 
at
-        * all, all other methods would be useless. Because they rely on the
-        * parameter map to be filled.
-        * 
-        * @param queryString
-        *            the query string in its raw form (not yet url-decoded)
-        * @param doUrlDecoding TODO
-        */
-       private void parseRequestParameters(String queryString, boolean 
doUrlDecoding, boolean asParts) {
-
-               boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
-               if(logMINOR) 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;
-               }
-
-               // iterate over all tokens in the query string (seperated by &)
-               StringTokenizer tokenizer = new StringTokenizer(queryString, 
"&");
-               while (tokenizer.hasMoreTokens()) {
-                       String nameValueToken = tokenizer.nextToken();
-                       
-                       if(logMINOR) Logger.minor(this, "Token: 
"+nameValueToken);
-
-                       // a token can be either a name, or a name value pair...
-                       String name = null;
-                       String value = "";
-                       int indexOfEqualsChar = nameValueToken.indexOf('=');
-                       if (indexOfEqualsChar < 0) {
-                               // ...it's only a name, so the value stays 
emptys
-                               name = nameValueToken;
-                               if(logMINOR) 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);
-                               if(logMINOR) 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);
-                               if(logMINOR) Logger.minor(this, "Name: "+name+" 
Value: "+value);
-                       }
-
-                       // url-decode the name and value
-                       if (doUrlDecoding) {
-                                       try {
-                                               name = URLDecoder.decode(name, 
"UTF-8");
-                                               value = 
URLDecoder.decode(value, "UTF-8");
-                                       } catch (UnsupportedEncodingException 
e) {
-                                               throw new Error(e);
-                                       }
-                               if(logMINOR) {
-                                       Logger.minor(this, "Decoded name: 
"+name);
-                                       Logger.minor(this, "Decoded value: 
"+value);
-                               }
-                       }
-                       
-                       if(asParts) {
-                               // Store as a part
-                               byte[] buf;
-                               try {
-                                       buf = value.getBytes("UTF-8");
-                               } catch (UnsupportedEncodingException e) {
-                                       throw new Error(e);
-                               } // FIXME some other encoding?
-                               Bucket b = new SimpleReadOnlyArrayBucket(buf);
-                               parts.put(name, b);
-                               if(logMINOR)
-                                       Logger.minor(this, "Added as part: 
name="+name+" value="+value);
-                       } else {
-                               // get the list of values for this parameter 
that were parsed so far
-                               List valueList = 
this.getParameterValueList(name);
-                               // add this value to the list
-                               valueList.add(value);
-                       }
-               }
-       }
-
-       /**
-        * Get the first value of the parameter with the given name.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @return the first value or <code>null</code> if the parameter was not
-        *         set
-        */
-       private String getParameterValue(String name) {
-               if (!this.isParameterSet(name)) {
-                       return null;
-               }
-               List allValues = this.getParameterValueList(name);
-               return (String) allValues.get(0);
-       }
-
-       /**
-        * Get the list of all values for the parameter with the given name. 
When
-        * this method is called for a given parameter for the first time, a new
-        * empty list of values is created and stored in
-        * {@link #parameterNameValuesMap}. This list is returned and should be
-        * used to add parameter values. If you only want to check if a 
parameter is
-        * set at all, you must use {@link #isParameterSet(String)}.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @return the list of all values for this parameter that were parsed so
-        *         far.
-        */
-       private List getParameterValueList(String name) {
-               List values = (List) this.parameterNameValuesMap.get(name);
-               if (values == null) {
-                       values = new LinkedList();
-                       this.parameterNameValuesMap.put(name, values);
-               }
-               return values;
-       }
-
-       /**
-        * Check if a parameter was set in the request at all, either with or
-        * without a value.
-        * 
-        * @param name
-        *            the name of the parameter to check
-        * @return true if the parameter was set in the request, not regarding 
if
-        *         the value is empty
-        */
-       public boolean isParameterSet(String name) {
-               return this.parameterNameValuesMap.containsKey(name);
-       }
-
-       /**
-        * Get the value of a request parameter, using an empty string as 
default
-        * value if the parameter was not set. This method will never return 
null,
-        * so its safe to do things like
-        * 
-        * <p>
-        * <code>
-        *   if (request.getParam(&quot;abc&quot;).equals(&quot;def&quot;))
-        * </code>
-        * </p>
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @return the parameter value as String, or an empty String if the 
value
-        *         was missing or empty
-        */
-       public String getParam(String name) {
-               return this.getParam(name, "");
-       }
-
-       /**
-        * Get the value of a request parameter, using the specified default 
value
-        * if the parameter was not set or has an empty value.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @param defaultValue
-        *            the default value to be returned if the parameter is 
missing
-        *            or empty
-        * @return either the parameter value as String, or the default value
-        */
-       public String getParam(String name, String defaultValue) {
-               String value = this.getParameterValue(name);
-               if (value == null) {
-                       return defaultValue;
-               }
-               return value;
-       }
-
-       /**
-        * Get the value of a request parameter converted to an int, using 0 as
-        * default value. If there are multiple values for this parameter, the 
first
-        * value is used.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @return either the parameter value as int, or 0 if the parameter is
-        *         missing, empty or invalid
-        */
-       public int getIntParam(String name) {
-               return this.getIntParam(name, 0);
-       }
-
-       /**
-        * Get the value of a request parameter converted to an 
<code>int</code>,
-        * using the specified default value. If there are multiple values for 
this
-        * parameter, the first value is used.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @param defaultValue
-        *            the default value to be returned if the parameter is 
missing,
-        *            empty or invalid
-        * @return either the parameter value as int, or the default value
-        */
-       public int getIntParam(String name, int defaultValue) {
-               if (!this.isParameterSet(name)) {
-                       return defaultValue;
-               }
-               String value = this.getParameterValue(name);
-               try {
-                       return Integer.parseInt(value);
-               } catch (NumberFormatException e) {
-                       return defaultValue;
-               }
-       }
-
-       public int getIntPart(String name, int defaultValue) {
-               if (!this.isPartSet(name)) {
-                       return defaultValue;
-               }
-               String value = this.getPartAsString(name, 32);
-               try {
-                       return Integer.parseInt(value);
-               } catch (NumberFormatException e) {
-                       return defaultValue;
-               }
-       }
-
-       // TODO: add similar methods for long, boolean etc.
-
-       /**
-        * Get all values of a request parameter as a string array. If the 
parameter
-        * was not set at all, an empty array is returned, so this method will 
never
-        * return <code>null</code>.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @return an array of all paramter values that might include empty 
values
-        */
-       public String[] getMultipleParam(String name) {
-               List valueList = this.getParameterValueList(name);
-               String[] values = new String[valueList.size()];
-               valueList.toArray(values);
-               return values;
-       }
-
-       /**
-        * Get all values of a request parameter as int array, ignoring all 
values
-        * that can not be parsed. If the parameter was not set at all, an empty
-        * array is returned, so this method will never return 
<code>null</code>.
-        * 
-        * @param name
-        *            the name of the parameter to get
-        * @return an int array of all parameter values that could be parsed as 
int
-        */
-       public int[] getMultipleIntParam(String name) {
-               List valueList = this.getParameterValueList(name);
-
-               // try parsing all values and put the valid Integers in a new 
list
-               List intValueList = new ArrayList();
-               for (int i = 0; i < valueList.size(); i++) {
-                       try {
-                               intValueList.add(new Integer((String) 
valueList.get(i)));
-                       } catch (Exception e) {
-                               // ignore invalid parameter values
-                       }
-               }
-
-               // convert the valid Integers to an array of ints
-               int[] values = new int[intValueList.size()];
-               for (int i = 0; i < intValueList.size(); i++) {
-                       values[i] = ((Integer) intValueList.get(i)).intValue();
-               }
-               return values;
-       }
-
-
-       // TODO: add similar methods for multiple long, boolean etc.
-       
-       
-       /**
-        * Parse submitted data from a bucket.
-        * Note that if this is application/x-www-form-urlencoded, it will come 
out as
-        * params, whereas if it is multipart/form-data it will be separated 
into buckets.
-        */
-       private void parseMultiPartData() throws IOException {
-               if(data == null) return;
-               String ctype = (String) this.headers.get("content-type");
-               if (ctype == null) return;
-               if(Logger.shouldLog(Logger.MINOR, this))
-                       Logger.minor(this, "Uploaded content-type: "+ctype);
-               String[] ctypeparts = ctype.split(";");
-               
if(ctypeparts[0].equalsIgnoreCase("application/x-www-form-urlencoded")) {
-                       // Completely different encoding, but easy to handle
-                       if(data.size() > 1024*1024)
-                               throw new IOException("Too big");
-                       byte[] buf = BucketTools.toByteArray(data);
-                       String s = new String(buf, "us-ascii");
-                       parseRequestParameters(s, true, true);
-               }
-               if 
(!ctypeparts[0].trim().equalsIgnoreCase("multipart/form-data") || 
(ctypeparts.length < 2)) {
-                       return;
-               }
-               
-               String boundary = null;
-               for (int i = 0; i < ctypeparts.length; i++) {
-                       String[] subparts = ctypeparts[i].split("=");
-                       if ((subparts.length == 2) && 
subparts[0].trim().equalsIgnoreCase("boundary")) {
-                               boundary = subparts[1];
-                       }
-               }
-               
-               if ((boundary == null) || (boundary.length() == 0)) return;
-               if (boundary.charAt(0) == '"') boundary = boundary.substring(1);
-               if (boundary.charAt(boundary.length() - 1) == '"')
-                       boundary = boundary.substring(0, boundary.length() - 1);
-               
-               boundary = "--"+boundary;
-               
-               InputStream is = this.data.getInputStream();
-               BufferedInputStream bis = new BufferedInputStream(is, 32768);
-               LineReadingInputStream lis = new LineReadingInputStream(bis);
-               
-               String line;
-               line = lis.readLine(100, 100, false); // really it's US-ASCII, 
but ISO-8859-1 is close enough.
-               while ((bis.available() > 0) && !line.equals(boundary)) {
-                       line = lis.readLine(100, 100, false);
-               }
-               
-               boundary  = "\r\n"+boundary;
-               
-               Bucket filedata = null;
-               String name = null;
-               String filename = null;
-               String contentType = null;
-               
-               while(bis.available() > 0) {
-                       name = null;
-                       filename = null;
-                       contentType = null;
-                       // chomp headers
-                       while( (line = lis.readLine(200, 200, true)) /* should 
be UTF-8 as we told the browser to send UTF-8 */ != null) {
-                               if (line.length() == 0) break;
-                               
-                               String[] lineparts = line.split(":");
-                               if (lineparts == null || lineparts.length == 0) 
continue;
-                               String hdrname = lineparts[0].trim();
-                               
-                               if 
(hdrname.equalsIgnoreCase("Content-Disposition")) {
-                                       if (lineparts.length < 2) continue;
-                                       String[] valueparts = 
lineparts[1].split(";");
-                                       
-                                       for (int i = 0; i < valueparts.length; 
i++) {
-                                               String[] subparts = 
valueparts[i].split("=");
-                                               if (subparts.length != 2) {
-                                                       continue;
-                                               }
-                                               String fieldname = 
subparts[0].trim();
-                                               String value = 
subparts[1].trim();
-                                               if (value.startsWith("\"") && 
value.endsWith("\"")) {
-                                                       value = 
value.substring(1, value.length() - 1);
-                                               }
-                                               if 
(fieldname.equalsIgnoreCase("name")) {
-                                                       name = value;
-                                               } else if 
(fieldname.equalsIgnoreCase("filename")) {
-                                                       filename = value;
-                                               }
-                                       }
-                               } else if 
(hdrname.equalsIgnoreCase("Content-Type")) {
-                                       contentType = lineparts[1].trim();
-                                       if(Logger.shouldLog(Logger.MINOR, 
this)) Logger.minor(this, "Parsed type: "+contentType);
-                               } else {
-                                       
-                               }
-                       }
-                       
-                       if (name == null) continue;
-                       
-                       // we should be at the data now. Start reading it in, 
checking for the
-                       // boundary string
-                       
-                       // we can only give an upper bound for the size of the 
bucket
-                       filedata = 
this.bucketfactory.makeBucket(bis.available());
-                       OutputStream bucketos = filedata.getOutputStream();
-                       OutputStream bbos = new BufferedOutputStream(bucketos, 
32768);
-                       // buffer characters that match the boundary so far
-                       // FIXME use whatever charset was used
-                       byte[] bbound = boundary.getBytes("UTF-8"); // 
ISO-8859-1? boundary should be in US-ASCII
-                       int offset = 0;
-                       while ((bis.available() > 0) && (offset < 
bbound.length)) {
-                               byte b = (byte)bis.read();
-                               
-                               if (b == bbound[offset]) {
-                                       offset++;
-                               } else if ((b != bbound[offset]) && (offset > 
0)) {
-                                       // offset bytes matched, but no more
-                                       // write the bytes that matched, then 
the non-matching byte
-                                       bbos.write(bbound, 0, offset);
-                                       bbos.write((int) b & 0xff);
-                                       offset = 0;
-                               } else {
-                                       bbos.write((int) b & 0xff);
-                               }
-                       }
-                       
-                       bbos.close();
-                       
-                       parts.put(name, filedata);
-                       if(Logger.shouldLog(Logger.MINOR, this))
-                               Logger.minor(this, "Name = "+name+" length = 
"+filedata.size()+" filename = "+filename);
-                       if (filename != null) {
-                               uploadedFiles.put(name, new File(filename, 
contentType, filedata));
-                       }
-               }
-       }
-       
-       public File getUploadedFile(String name) {
-               return (File) uploadedFiles.get(name);
-       }
-       
-       public Bucket getPart(String name) {
-               return (Bucket)this.parts.get(name);
-       }
-       
-       public boolean isPartSet(String name) {
-               return this.parts.containsKey(name);
-       }
-       
-       public String getPartAsString(String name, int maxlength) {
-               Bucket part = (Bucket)this.parts.get(name);
-               if(part == null) return "";
-               
-               if (part.size() > maxlength) return "";
-               
-               try {
-                       InputStream is = part.getInputStream();
-                       DataInputStream dis = new DataInputStream(is);
-                       byte[] buf = new byte[is.available()];
-                       dis.readFully(buf);
-                       is.close();
-                       return new String(buf);
-               } catch (IOException ioe) {
-                       
-               }
-               return "";
-       }
-       
-       public void freeParts() {
-               if (this.parts == null) return;
-               Iterator i = this.parts.keySet().iterator();
-               
-               while (i.hasNext()) {
-                       String key = (String) i.next();
-                       Bucket b = (Bucket)this.parts.get(key);
-                       b.free();
-               }
-       }
-
-       public long getLongParam(String name, long defaultValue) {
-               if (!this.isParameterSet(name)) {
-                       return defaultValue;
-               }
-               String value = this.getParameterValue(name);
-               try {
-                       return Long.parseLong(value);
-               } catch (NumberFormatException e) {
-                       return defaultValue;
-               }
-       }
-
-       /**
-        * Container for uploaded files in HTTP POST requests.
-        * 
-        * @author David 'Bombe' Roden &lt;bombe at freenetproject.org&gt;
-        * @version $Id$
-        */
-       public static class File {
-
-               /** The filename. */
-               private final String filename;
-
-               /** The content type. */
-               private final String contentType;
-
-               /** The data. */
-               private final Bucket data;
-
-               /**
-                * Creates a new file with the specified filename, content 
type, and
-                * data.
-                * 
-                * @param filename
-                *            The name of the file
-                * @param contentType
-                *            The content type of the file
-                * @param data
-                *            The data of the file
-                */
-               public File(String filename, String contentType, Bucket data) {
-                       this.filename = filename;
-                       this.contentType = contentType;
-                       this.data = data;
-               }
-
-               /**
-                * Returns the content type of the file.
-                * 
-                * @return The content type of the file
-                */
-               public String getContentType() {
-                       return contentType;
-               }
-
-               /**
-                * Returns the data of the file.
-                * 
-                * @return The data of the file
-                */
-               public Bucket getData() {
-                       return data;
-               }
-
-               /**
-                * Returns the name of the file.
-                * 
-                * @return The name of the file
-                */
-               public String getFilename() {
-                       return filename;
-               }
-
-       }
-
-}

Copied: trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java (from rev 
11407, trunk/freenet/src/freenet/clients/http/HTTPRequest.java)
===================================================================
--- trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java                 
        (rev 0)
+++ trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java 2006-12-15 
21:55:54 UTC (rev 11425)
@@ -0,0 +1,637 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.clients.http;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import freenet.support.Logger;
+import freenet.support.MultiValueTable;
+import freenet.support.SimpleReadOnlyArrayBucket;
+import freenet.support.api.Bucket;
+import freenet.support.api.BucketFactory;
+import freenet.support.api.HTTPRequest;
+import freenet.support.api.HTTPUploadedFile;
+import freenet.support.io.BucketTools;
+import freenet.support.io.LineReadingInputStream;
+
+/**
+ * Used for passing all HTTP request information to the FredPlugin that handles
+ * the request. It parses the query string and has several methods for acessing
+ * the request parameter values.
+ * 
+ * @author nacktschneck
+ */
+public class HTTPRequestImpl implements HTTPRequest {
+
+       /**
+        * This map is used to store all parameter values. The name (as String) 
of
+        * the parameter is used as key, the returned value is a list (of 
Strings)
+        * with all values for that parameter sent in the request. You shouldn't
+        * access this map directly, use {@link #getParameterValueList(String)} 
and
+        * {@link #isParameterSet(String)} insted
+        */
+       private final Map parameterNameValuesMap = new HashMap();
+
+       /**
+        * the original URI as given to the constructor
+        */
+       private URI uri;
+       
+       /**
+        * The headers sent by the client
+        */
+       private MultiValueTable headers;
+       
+       /**
+        * The data sent in the connection
+        */
+       private Bucket data;
+       
+       /**
+        * A hasmap of buckets that we use to store all the parts for a 
multipart/form-data request
+        */
+       private HashMap parts;
+       
+       /** A map for uploaded files. */
+       private Map uploadedFiles = new HashMap();
+       
+       private final BucketFactory bucketfactory;
+
+       /**
+        * Create a new HTTPRequest for the given URI and parse its request
+        * parameters.
+        * 
+        * @param uri
+        *            the URI being requested
+        */
+       public HTTPRequestImpl(URI uri) {
+               this.uri = uri;
+               this.parseRequestParameters(uri.getRawQuery(), true, false);
+               this.data = null;
+               this.parts = null;
+               this.bucketfactory = null;
+       }
+
+       /**
+        * Creates a new HTTPRequest for the given path and url-encoded query 
string
+        * 
+        * @param path i.e. /test/test.html
+        * @param encodedQueryString a=some+text&b=abc%40def.de
+        * @throws URISyntaxException if the URI is invalid
+        */
+       public HTTPRequestImpl(String path, String encodedQueryString) throws 
URISyntaxException {
+               this.data = null;
+               this.parts = null;
+               this.bucketfactory = null;
+               if ((encodedQueryString!=null) && 
(encodedQueryString.length()>0)) {
+                       this.uri = new URI(path+ '?' +encodedQueryString);
+               } else {
+                       this.uri = new URI(path);
+               }
+               this.parseRequestParameters(uri.getRawQuery(), true, false);
+       }
+       
+       /**
+        * Creates a new HTTPRequest for the given URI and data.
+        * 
+        * @param uri The URI being requested
+        * @param h Client headers
+        * @param d The data
+        * @param ctx The toadlet context (for headers and bucket factory)
+        * @throws URISyntaxException if the URI is invalid
+        */
+       public HTTPRequestImpl(URI uri, Bucket d, ToadletContext ctx) {
+               this.uri = uri;
+               this.headers = ctx.getHeaders();
+               this.parseRequestParameters(uri.getRawQuery(), true, false);
+               this.data = d;
+               this.parts = new HashMap();
+               this.bucketfactory = ctx.getBucketFactory();
+               try {
+                       this.parseMultiPartData();
+               } catch (IOException ioe) {
+                       
+               }
+       }
+       
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getPath()
+        */
+       public String getPath() {
+               return this.uri.getPath();
+       }
+
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#hasParameters()
+        */
+       public boolean hasParameters() {
+               return ! this.parameterNameValuesMap.isEmpty();
+       }
+
+       /**
+        * Parse the query string and populate {@link #parameterNameValuesMap} 
with
+        * the lists of values for each parameter. If this method is not called 
at
+        * all, all other methods would be useless. Because they rely on the
+        * parameter map to be filled.
+        * 
+        * @param queryString
+        *            the query string in its raw form (not yet url-decoded)
+        * @param doUrlDecoding TODO
+        */
+       private void parseRequestParameters(String queryString, boolean 
doUrlDecoding, boolean asParts) {
+
+               boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
+               if(logMINOR) 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;
+               }
+
+               // iterate over all tokens in the query string (seperated by &)
+               StringTokenizer tokenizer = new StringTokenizer(queryString, 
"&");
+               while (tokenizer.hasMoreTokens()) {
+                       String nameValueToken = tokenizer.nextToken();
+                       
+                       if(logMINOR) Logger.minor(this, "Token: 
"+nameValueToken);
+
+                       // a token can be either a name, or a name value pair...
+                       String name = null;
+                       String value = "";
+                       int indexOfEqualsChar = nameValueToken.indexOf('=');
+                       if (indexOfEqualsChar < 0) {
+                               // ...it's only a name, so the value stays 
emptys
+                               name = nameValueToken;
+                               if(logMINOR) 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);
+                               if(logMINOR) 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);
+                               if(logMINOR) Logger.minor(this, "Name: "+name+" 
Value: "+value);
+                       }
+
+                       // url-decode the name and value
+                       if (doUrlDecoding) {
+                                       try {
+                                               name = URLDecoder.decode(name, 
"UTF-8");
+                                               value = 
URLDecoder.decode(value, "UTF-8");
+                                       } catch (UnsupportedEncodingException 
e) {
+                                               throw new Error(e);
+                                       }
+                               if(logMINOR) {
+                                       Logger.minor(this, "Decoded name: 
"+name);
+                                       Logger.minor(this, "Decoded value: 
"+value);
+                               }
+                       }
+                       
+                       if(asParts) {
+                               // Store as a part
+                               byte[] buf;
+                               try {
+                                       buf = value.getBytes("UTF-8");
+                               } catch (UnsupportedEncodingException e) {
+                                       throw new Error(e);
+                               } // FIXME some other encoding?
+                               Bucket b = new SimpleReadOnlyArrayBucket(buf);
+                               parts.put(name, b);
+                               if(logMINOR)
+                                       Logger.minor(this, "Added as part: 
name="+name+" value="+value);
+                       } else {
+                               // get the list of values for this parameter 
that were parsed so far
+                               List valueList = 
this.getParameterValueList(name);
+                               // add this value to the list
+                               valueList.add(value);
+                       }
+               }
+       }
+
+       /**
+        * Get the first value of the parameter with the given name.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @return the first value or <code>null</code> if the parameter was not
+        *         set
+        */
+       private String getParameterValue(String name) {
+               if (!this.isParameterSet(name)) {
+                       return null;
+               }
+               List allValues = this.getParameterValueList(name);
+               return (String) allValues.get(0);
+       }
+
+       /**
+        * Get the list of all values for the parameter with the given name. 
When
+        * this method is called for a given parameter for the first time, a new
+        * empty list of values is created and stored in
+        * {@link #parameterNameValuesMap}. This list is returned and should be
+        * used to add parameter values. If you only want to check if a 
parameter is
+        * set at all, you must use {@link #isParameterSet(String)}.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @return the list of all values for this parameter that were parsed so
+        *         far.
+        */
+       private List getParameterValueList(String name) {
+               List values = (List) this.parameterNameValuesMap.get(name);
+               if (values == null) {
+                       values = new LinkedList();
+                       this.parameterNameValuesMap.put(name, values);
+               }
+               return values;
+       }
+
+       /* (non-Javadoc)
+        * @see 
freenet.clients.http.HTTPRequest#isParameterSet(java.lang.String)
+        */
+       public boolean isParameterSet(String name) {
+               return this.parameterNameValuesMap.containsKey(name);
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getParam(java.lang.String)
+        */
+       public String getParam(String name) {
+               return this.getParam(name, "");
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getParam(java.lang.String, 
java.lang.String)
+        */
+       public String getParam(String name, String defaultValue) {
+               String value = this.getParameterValue(name);
+               if (value == null) {
+                       return defaultValue;
+               }
+               return value;
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getIntParam(java.lang.String)
+        */
+       public int getIntParam(String name) {
+               return this.getIntParam(name, 0);
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getIntParam(java.lang.String, 
int)
+        */
+       public int getIntParam(String name, int defaultValue) {
+               if (!this.isParameterSet(name)) {
+                       return defaultValue;
+               }
+               String value = this.getParameterValue(name);
+               try {
+                       return Integer.parseInt(value);
+               } catch (NumberFormatException e) {
+                       return defaultValue;
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getIntPart(java.lang.String, 
int)
+        */
+       public int getIntPart(String name, int defaultValue) {
+               if (!this.isPartSet(name)) {
+                       return defaultValue;
+               }
+               String value = this.getPartAsString(name, 32);
+               try {
+                       return Integer.parseInt(value);
+               } catch (NumberFormatException e) {
+                       return defaultValue;
+               }
+       }
+
+       // TODO: add similar methods for long, boolean etc.
+
+       /* (non-Javadoc)
+        * @see 
freenet.clients.http.HTTPRequest#getMultipleParam(java.lang.String)
+        */
+       public String[] getMultipleParam(String name) {
+               List valueList = this.getParameterValueList(name);
+               String[] values = new String[valueList.size()];
+               valueList.toArray(values);
+               return values;
+       }
+
+       /* (non-Javadoc)
+        * @see 
freenet.clients.http.HTTPRequest#getMultipleIntParam(java.lang.String)
+        */
+       public int[] getMultipleIntParam(String name) {
+               List valueList = this.getParameterValueList(name);
+
+               // try parsing all values and put the valid Integers in a new 
list
+               List intValueList = new ArrayList();
+               for (int i = 0; i < valueList.size(); i++) {
+                       try {
+                               intValueList.add(new Integer((String) 
valueList.get(i)));
+                       } catch (Exception e) {
+                               // ignore invalid parameter values
+                       }
+               }
+
+               // convert the valid Integers to an array of ints
+               int[] values = new int[intValueList.size()];
+               for (int i = 0; i < intValueList.size(); i++) {
+                       values[i] = ((Integer) intValueList.get(i)).intValue();
+               }
+               return values;
+       }
+
+
+       // TODO: add similar methods for multiple long, boolean etc.
+       
+       
+       /**
+        * Parse submitted data from a bucket.
+        * Note that if this is application/x-www-form-urlencoded, it will come 
out as
+        * params, whereas if it is multipart/form-data it will be separated 
into buckets.
+        */
+       private void parseMultiPartData() throws IOException {
+               if(data == null) return;
+               String ctype = (String) this.headers.get("content-type");
+               if (ctype == null) return;
+               if(Logger.shouldLog(Logger.MINOR, this))
+                       Logger.minor(this, "Uploaded content-type: "+ctype);
+               String[] ctypeparts = ctype.split(";");
+               
if(ctypeparts[0].equalsIgnoreCase("application/x-www-form-urlencoded")) {
+                       // Completely different encoding, but easy to handle
+                       if(data.size() > 1024*1024)
+                               throw new IOException("Too big");
+                       byte[] buf = BucketTools.toByteArray(data);
+                       String s = new String(buf, "us-ascii");
+                       parseRequestParameters(s, true, true);
+               }
+               if 
(!ctypeparts[0].trim().equalsIgnoreCase("multipart/form-data") || 
(ctypeparts.length < 2)) {
+                       return;
+               }
+               
+               String boundary = null;
+               for (int i = 0; i < ctypeparts.length; i++) {
+                       String[] subparts = ctypeparts[i].split("=");
+                       if ((subparts.length == 2) && 
subparts[0].trim().equalsIgnoreCase("boundary")) {
+                               boundary = subparts[1];
+                       }
+               }
+               
+               if ((boundary == null) || (boundary.length() == 0)) return;
+               if (boundary.charAt(0) == '"') boundary = boundary.substring(1);
+               if (boundary.charAt(boundary.length() - 1) == '"')
+                       boundary = boundary.substring(0, boundary.length() - 1);
+               
+               boundary = "--"+boundary;
+               
+               InputStream is = this.data.getInputStream();
+               BufferedInputStream bis = new BufferedInputStream(is, 32768);
+               LineReadingInputStream lis = new LineReadingInputStream(bis);
+               
+               String line;
+               line = lis.readLine(100, 100, false); // really it's US-ASCII, 
but ISO-8859-1 is close enough.
+               while ((bis.available() > 0) && !line.equals(boundary)) {
+                       line = lis.readLine(100, 100, false);
+               }
+               
+               boundary  = "\r\n"+boundary;
+               
+               Bucket filedata = null;
+               String name = null;
+               String filename = null;
+               String contentType = null;
+               
+               while(bis.available() > 0) {
+                       name = null;
+                       filename = null;
+                       contentType = null;
+                       // chomp headers
+                       while( (line = lis.readLine(200, 200, true)) /* should 
be UTF-8 as we told the browser to send UTF-8 */ != null) {
+                               if (line.length() == 0) break;
+                               
+                               String[] lineparts = line.split(":");
+                               if (lineparts == null || lineparts.length == 0) 
continue;
+                               String hdrname = lineparts[0].trim();
+                               
+                               if 
(hdrname.equalsIgnoreCase("Content-Disposition")) {
+                                       if (lineparts.length < 2) continue;
+                                       String[] valueparts = 
lineparts[1].split(";");
+                                       
+                                       for (int i = 0; i < valueparts.length; 
i++) {
+                                               String[] subparts = 
valueparts[i].split("=");
+                                               if (subparts.length != 2) {
+                                                       continue;
+                                               }
+                                               String fieldname = 
subparts[0].trim();
+                                               String value = 
subparts[1].trim();
+                                               if (value.startsWith("\"") && 
value.endsWith("\"")) {
+                                                       value = 
value.substring(1, value.length() - 1);
+                                               }
+                                               if 
(fieldname.equalsIgnoreCase("name")) {
+                                                       name = value;
+                                               } else if 
(fieldname.equalsIgnoreCase("filename")) {
+                                                       filename = value;
+                                               }
+                                       }
+                               } else if 
(hdrname.equalsIgnoreCase("Content-Type")) {
+                                       contentType = lineparts[1].trim();
+                                       if(Logger.shouldLog(Logger.MINOR, 
this)) Logger.minor(this, "Parsed type: "+contentType);
+                               } else {
+                                       
+                               }
+                       }
+                       
+                       if (name == null) continue;
+                       
+                       // we should be at the data now. Start reading it in, 
checking for the
+                       // boundary string
+                       
+                       // we can only give an upper bound for the size of the 
bucket
+                       filedata = 
this.bucketfactory.makeBucket(bis.available());
+                       OutputStream bucketos = filedata.getOutputStream();
+                       OutputStream bbos = new BufferedOutputStream(bucketos, 
32768);
+                       // buffer characters that match the boundary so far
+                       // FIXME use whatever charset was used
+                       byte[] bbound = boundary.getBytes("UTF-8"); // 
ISO-8859-1? boundary should be in US-ASCII
+                       int offset = 0;
+                       while ((bis.available() > 0) && (offset < 
bbound.length)) {
+                               byte b = (byte)bis.read();
+                               
+                               if (b == bbound[offset]) {
+                                       offset++;
+                               } else if ((b != bbound[offset]) && (offset > 
0)) {
+                                       // offset bytes matched, but no more
+                                       // write the bytes that matched, then 
the non-matching byte
+                                       bbos.write(bbound, 0, offset);
+                                       bbos.write((int) b & 0xff);
+                                       offset = 0;
+                               } else {
+                                       bbos.write((int) b & 0xff);
+                               }
+                       }
+                       
+                       bbos.close();
+                       
+                       parts.put(name, filedata);
+                       if(Logger.shouldLog(Logger.MINOR, this))
+                               Logger.minor(this, "Name = "+name+" length = 
"+filedata.size()+" filename = "+filename);
+                       if (filename != null) {
+                               uploadedFiles.put(name, new 
HTTPUploadedFileImpl(filename, contentType, filedata));
+                       }
+               }
+       }
+       
+       /* (non-Javadoc)
+        * @see 
freenet.clients.http.HTTPRequest#getUploadedFile(java.lang.String)
+        */
+       public HTTPUploadedFile getUploadedFile(String name) {
+               return (HTTPUploadedFile) uploadedFiles.get(name);
+       }
+       
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getPart(java.lang.String)
+        */
+       public Bucket getPart(String name) {
+               return (Bucket)this.parts.get(name);
+       }
+       
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#isPartSet(java.lang.String)
+        */
+       public boolean isPartSet(String name) {
+               return this.parts.containsKey(name);
+       }
+       
+       /* (non-Javadoc)
+        * @see 
freenet.clients.http.HTTPRequest#getPartAsString(java.lang.String, int)
+        */
+       public String getPartAsString(String name, int maxlength) {
+               Bucket part = (Bucket)this.parts.get(name);
+               if(part == null) return "";
+               
+               if (part.size() > maxlength) return "";
+               
+               try {
+                       InputStream is = part.getInputStream();
+                       DataInputStream dis = new DataInputStream(is);
+                       byte[] buf = new byte[is.available()];
+                       dis.readFully(buf);
+                       is.close();
+                       return new String(buf);
+               } catch (IOException ioe) {
+                       
+               }
+               return "";
+       }
+       
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#freeParts()
+        */
+       public void freeParts() {
+               if (this.parts == null) return;
+               Iterator i = this.parts.keySet().iterator();
+               
+               while (i.hasNext()) {
+                       String key = (String) i.next();
+                       Bucket b = (Bucket)this.parts.get(key);
+                       b.free();
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.clients.http.HTTPRequest#getLongParam(java.lang.String, 
long)
+        */
+       public long getLongParam(String name, long defaultValue) {
+               if (!this.isParameterSet(name)) {
+                       return defaultValue;
+               }
+               String value = this.getParameterValue(name);
+               try {
+                       return Long.parseLong(value);
+               } catch (NumberFormatException e) {
+                       return defaultValue;
+               }
+       }
+
+       /**
+        * Container for uploaded files in HTTP POST requests.
+        * 
+        * @author David 'Bombe' Roden &lt;bombe at freenetproject.org&gt;
+        * @version $Id$
+        */
+       public static class HTTPUploadedFileImpl implements HTTPUploadedFile {
+
+               /** The filename. */
+               private final String filename;
+
+               /** The content type. */
+               private final String contentType;
+
+               /** The data. */
+               private final Bucket data;
+
+               /**
+                * Creates a new file with the specified filename, content 
type, and
+                * data.
+                * 
+                * @param filename
+                *            The name of the file
+                * @param contentType
+                *            The content type of the file
+                * @param data
+                *            The data of the file
+                */
+               public HTTPUploadedFileImpl(String filename, String 
contentType, Bucket data) {
+                       this.filename = filename;
+                       this.contentType = contentType;
+                       this.data = data;
+               }
+
+               /* (non-Javadoc)
+                * @see freenet.clients.http.HTTPUploadedFile#getContentType()
+                */
+               public String getContentType() {
+                       return contentType;
+               }
+
+               /* (non-Javadoc)
+                * @see freenet.clients.http.HTTPUploadedFile#getData()
+                */
+               public Bucket getData() {
+                       return data;
+               }
+
+               /* (non-Javadoc)
+                * @see freenet.clients.http.HTTPUploadedFile#getFilename()
+                */
+               public String getFilename() {
+                       return filename;
+               }
+
+       }
+
+}

Modified: trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java  
2006-12-15 21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java  
2006-12-15 21:55:54 UTC (rev 11425)
@@ -13,6 +13,7 @@
 import freenet.node.NodeClientCore;
 import freenet.support.HTMLNode;
 import freenet.support.URLEncoder;
+import freenet.support.api.HTTPRequest;

 /**
  * @author David 'Bombe' Roden &lt;bombe at freenetproject.org&gt;
@@ -37,7 +38,7 @@
         *      freenet.clients.http.ToadletContext)
         */
        public void handleGet(URI uri, ToadletContext toadletContext) throws 
ToadletContextClosedException, IOException, RedirectException {
-               HTTPRequest request = new HTTPRequest(uri, null, 
toadletContext);
+               HTTPRequest request = new HTTPRequestImpl(uri, null, 
toadletContext);

                String path = request.getParam("path");
                if (path.length() == 0) {

Modified: trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java    2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java    2006-12-15 
21:55:54 UTC (rev 11425)
@@ -23,6 +23,7 @@
 import freenet.support.MultiValueTable;
 import freenet.support.SimpleFieldSet;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 public class N2NTMToadlet extends Toadlet {

@@ -42,7 +43,7 @@
   }

   public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException, RedirectException {
-         HTTPRequest request = new HTTPRequest(uri, null, ctx);
+         HTTPRequest request = new HTTPRequestImpl(uri, null, ctx);
          if (request.isParameterSet("peernode_hashcode")) {
                  HTMLNode pageNode = ctx.getPageMaker().getPageNode("Send Node 
to Node Text Message");
                  HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
@@ -106,7 +107,7 @@
                  return;
          }

-         HTTPRequest request = new HTTPRequest(uri, data, ctx);
+         HTTPRequest request = new HTTPRequestImpl(uri, data, ctx);

          String pass = request.getPartAsString("formPassword", 32);
          if((pass == null) || !pass.equals(core.formPassword)) {

Modified: trunk/freenet/src/freenet/clients/http/NinjaSpider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/NinjaSpider.java     2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/NinjaSpider.java     2006-12-15 
21:55:54 UTC (rev 11425)
@@ -52,6 +52,7 @@
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 /**
  * NinjaSpider. Produces a ninj^W err ... an XML index.
@@ -531,7 +532,7 @@
        }

        /**
-        * @see 
freenet.oldplugins.plugin.HttpPlugin#handleGet(freenet.clients.http.HTTPRequest,
 freenet.clients.http.ToadletContext)
+        * @see 
freenet.oldplugins.plugin.HttpPlugin#handleGet(freenet.clients.http.HTTPRequestImpl,
 freenet.clients.http.ToadletContext)
         */
        public void handleGet(HTTPRequest request, ToadletContext context) 
throws IOException, ToadletContextClosedException {
                String action = request.getParam("action");
@@ -603,7 +604,7 @@
        }

        /**
-        * @see 
freenet.oldplugins.plugin.HttpPlugin#handlePost(freenet.clients.http.HTTPRequest,
 freenet.clients.http.ToadletContext)
+        * @see 
freenet.oldplugins.plugin.HttpPlugin#handlePost(freenet.clients.http.HTTPRequestImpl,
 freenet.clients.http.ToadletContext)
         */
        public void handlePost(HTTPRequest request, ToadletContext context) 
throws IOException {
        }

Modified: trunk/freenet/src/freenet/clients/http/PluginToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PluginToadlet.java   2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/PluginToadlet.java   2006-12-15 
21:55:54 UTC (rev 11425)
@@ -14,6 +14,7 @@
 import freenet.support.HTMLNode;
 import freenet.support.MultiValueTable;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 /**
  * Toadlet for the plugin manager.
@@ -63,7 +64,7 @@
         *            The context of this toadlet
         */
        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException, RedirectException {
-               HTTPRequest httpRequest = new HTTPRequest(uri, null, ctx);
+               HTTPRequest httpRequest = new HTTPRequestImpl(uri, null, ctx);

                String uriPath = uri.getPath();
                String pluginName = uriPath.substring(uriPath.lastIndexOf('/') 
+ 1);
@@ -102,7 +103,7 @@
         * @see freenet.clients.http.Toadlet#handlePost(java.net.URI, 
freenet.support.api.Bucket, freenet.clients.http.ToadletContext)
         */
        public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException, RedirectException {
-               HTTPRequest httpRequest = new HTTPRequest(uri, data, ctx);
+               HTTPRequest httpRequest = new HTTPRequestImpl(uri, data, ctx);

                String uriPath = uri.getPath();
                String pluginName = uriPath.substring(uriPath.lastIndexOf('/') 
+ 1);

Modified: trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PproxyToadlet.java   2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/PproxyToadlet.java   2006-12-15 
21:55:54 UTC (rev 11425)
@@ -16,6 +16,7 @@
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 public class PproxyToadlet extends Toadlet {
        private static final int MAX_PLUGIN_NAME_LENGTH = 1024;
@@ -35,7 +36,7 @@
        public void handlePost(URI uri, Bucket data, ToadletContext ctx)
                throws ToadletContextClosedException, IOException {

-               HTTPRequest request = new HTTPRequest(uri, data, ctx);
+               HTTPRequest request = new HTTPRequestImpl(uri, data, ctx);

                MultiValueTable headers = new MultiValueTable();

@@ -118,7 +119,7 @@
        public void handleGet(URI uri, ToadletContext ctx)
                        throws ToadletContextClosedException, IOException {
                //String basepath = "/plugins/";
-               HTTPRequest request = new HTTPRequest(uri);
+               HTTPRequest request = new HTTPRequestImpl(uri);
                String path = request.getPath();

                // remove leading / and 'plugins/' from path

Modified: trunk/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2006-12-15 
21:55:54 UTC (rev 11425)
@@ -32,6 +32,8 @@
 import freenet.support.MultiValueTable;
 import freenet.support.SizeUtil;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;
+import freenet.support.api.HTTPUploadedFile;
 import freenet.support.io.BucketTools;
 import freenet.support.io.FileBucket;

@@ -70,7 +72,7 @@
        }

        public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException, RedirectException {
-               HTTPRequest request = new HTTPRequest(uri, data, ctx);
+               HTTPRequest request = new HTTPRequestImpl(uri, data, ctx);
                try {
                        // Browse... button
                        if (request.getPartAsString("insert-local", 
128).length() > 0) {
@@ -182,7 +184,7 @@
                                        writeError("Invalid URI to insert", 
"You fooled around with the POST request. Shame on you.", ctx);
                                        return;
                                }
-                               HTTPRequest.File file = 
request.getUploadedFile("filename");
+                               HTTPUploadedFile file = 
request.getUploadedFile("filename");
                                if (file == null || 
file.getFilename().trim().length() == 0) {
                                        writeError("No file selected", "You did 
not select a file to upload.", ctx);
                                        return;
@@ -294,7 +296,7 @@
                        return;
                }

-               final HTTPRequest request = new HTTPRequest(uri, null, ctx);
+               final HTTPRequest request = new HTTPRequestImpl(uri, null, ctx);
                final String requestPath = 
request.getPath().substring("/queue/".length());

                if (requestPath.length() > 0) {

Modified: trunk/freenet/src/freenet/clients/http/Spider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Spider.java  2006-12-15 21:39:13 UTC 
(rev 11424)
+++ trunk/freenet/src/freenet/clients/http/Spider.java  2006-12-15 21:55:54 UTC 
(rev 11425)
@@ -42,6 +42,7 @@
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 /**
  * Spider. Produces an index.
@@ -274,7 +275,7 @@
        }

        /**
-        * @see 
freenet.oldplugins.plugin.HttpPlugin#handleGet(freenet.clients.http.HTTPRequest,
 freenet.clients.http.ToadletContext)
+        * @see 
freenet.oldplugins.plugin.HttpPlugin#handleGet(freenet.clients.http.HTTPRequestImpl,
 freenet.clients.http.ToadletContext)
         */
        public void handleGet(HTTPRequest request, ToadletContext context) 
throws IOException, ToadletContextClosedException {
                String action = request.getParam("action");
@@ -342,7 +343,7 @@
        }

        /**
-        * @see 
freenet.oldplugins.plugin.HttpPlugin#handlePost(freenet.clients.http.HTTPRequest,
 freenet.clients.http.ToadletContext)
+        * @see 
freenet.oldplugins.plugin.HttpPlugin#handlePost(freenet.clients.http.HTTPRequestImpl,
 freenet.clients.http.ToadletContext)
         */
        public void handlePost(HTTPRequest request, ToadletContext context) 
throws IOException {
        }

Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-12-15 
21:55:54 UTC (rev 11425)
@@ -27,6 +27,7 @@
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
 import freenet.support.api.Bucket;
+import freenet.support.api.HTTPRequest;

 import freenet.frost.message.*;

@@ -63,7 +64,7 @@
                        return;
                }

-               HTTPRequest request = new HTTPRequest(uri,data,ctx);
+               HTTPRequest request = new HTTPRequestImpl(uri,data,ctx);

                String passwd = request.getPartAsString("formPassword", 32);
                boolean noPassword = (passwd == null) || 
!passwd.equals(core.formPassword);
@@ -422,7 +423,7 @@
        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
                boolean advancedDarknetOutputEnabled = 
core.getToadletContainer().isAdvancedDarknetEnabled();

-               HTTPRequest request = new HTTPRequest(uri);
+               HTTPRequest request = new HTTPRequestImpl(uri);
                if (request.getParam("newbookmark").length() > 0) {
                        HTMLNode pageNode = ctx.getPageMaker().getPageNode("Add 
a Bookmark");
                        HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);

Modified: 
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
===================================================================
--- 
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java    
    2006-12-15 21:39:13 UTC (rev 11424)
+++ 
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java    
    2006-12-15 21:55:54 UTC (rev 11425)
@@ -10,11 +10,12 @@
 import java.net.URLEncoder;
 import java.util.HashSet;

-import freenet.clients.http.HTTPRequest;
+import freenet.clients.http.HTTPRequestImpl;
 import freenet.keys.FreenetURI;
 import freenet.support.HTMLEncoder;
 import freenet.support.Logger;
 import freenet.support.URIPreEncoder;
+import freenet.support.api.HTTPRequest;

 public class GenericReadFilterCallback implements FilterCallback {
        public static final String magicHTTPEscapeString = "_CHECKED_HTTP_";
@@ -82,7 +83,7 @@
                }
                String path = uri.getPath();

-               HTTPRequest req = new HTTPRequest(uri);
+               HTTPRequest req = new HTTPRequestImpl(uri);
                if (path != null){
                        if(path.equals("/") && 
req.isParameterSet("newbookmark")){
                                // allow links to the root to add bookmarks
@@ -194,7 +195,7 @@
        private String processURI(FreenetURI furi, URI uri, String 
overrideType, boolean noRelative) {
                // Valid freenet URI, allow it
                // Now what about the queries?
-               HTTPRequest req = new HTTPRequest(uri);
+               HTTPRequest req = new HTTPRequestImpl(uri);
                if(cb != null) cb.foundURI(furi);
                return finishProcess(req, overrideType, '/' + 
furi.toString(false, false), uri, noRelative);
        }

Modified: trunk/freenet/src/freenet/oldplugins/plugin/HttpPlugin.java
===================================================================
--- trunk/freenet/src/freenet/oldplugins/plugin/HttpPlugin.java 2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/oldplugins/plugin/HttpPlugin.java 2006-12-15 
21:55:54 UTC (rev 11425)
@@ -5,9 +5,9 @@

 import java.io.IOException;

-import freenet.clients.http.HTTPRequest;
 import freenet.clients.http.ToadletContext;
 import freenet.clients.http.ToadletContextClosedException;
+import freenet.support.api.HTTPRequest;

 /**
  * Interface for plugins that support HTTP interaction.

Modified: trunk/freenet/src/freenet/oldplugins/plugin/TestHttpPlugin.java
===================================================================
--- trunk/freenet/src/freenet/oldplugins/plugin/TestHttpPlugin.java     
2006-12-15 21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/oldplugins/plugin/TestHttpPlugin.java     
2006-12-15 21:55:54 UTC (rev 11425)
@@ -5,10 +5,10 @@

 import java.io.IOException;

-import freenet.clients.http.HTTPRequest;
 import freenet.clients.http.ToadletContext;
 import freenet.clients.http.ToadletContextClosedException;
 import freenet.support.MultiValueTable;
+import freenet.support.api.HTTPRequest;

 /**
  * Test HTTP plugin. Outputs "Plugin works" to the browser.
@@ -20,7 +20,7 @@

        /**
         * @throws ToadletContextClosedException
-        * @see 
freenet.oldplugins.plugin.HttpPlugin#handleGet(freenet.clients.http.HTTPRequest)
+        * @see 
freenet.oldplugins.plugin.HttpPlugin#handleGet(freenet.clients.http.HTTPRequestImpl)
         */
        public void handleGet(HTTPRequest request, ToadletContext context) 
throws IOException, ToadletContextClosedException {
                byte[] messageBytes = "Plugin works.".getBytes("UTF-8");
@@ -29,7 +29,7 @@
        }

        /**
-        * @see 
freenet.oldplugins.plugin.HttpPlugin#handlePost(freenet.clients.http.HTTPRequest)
+        * @see 
freenet.oldplugins.plugin.HttpPlugin#handlePost(freenet.clients.http.HTTPRequestImpl)
         */
        public void handlePost(HTTPRequest request, ToadletContext context) 
throws IOException, ToadletContextClosedException {
        }

Added: trunk/freenet/src/freenet/plugin/api/NeedsWebInterfaceHTMLString.java
===================================================================
--- trunk/freenet/src/freenet/plugin/api/NeedsWebInterfaceHTMLString.java       
                        (rev 0)
+++ trunk/freenet/src/freenet/plugin/api/NeedsWebInterfaceHTMLString.java       
2006-12-15 21:55:54 UTC (rev 11425)
@@ -0,0 +1,11 @@
+package freenet.plugin.api;
+
+import freenet.support.api.HTTPRequest;
+
+public interface NeedsWebInterfaceHTMLString {
+
+       public String handleGet(HTTPRequest req);
+       
+       public String handlePost(HTTPRequest req);
+       
+}

Modified: trunk/freenet/src/freenet/pluginmanager/FredPluginHTTP.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/FredPluginHTTP.java 2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/pluginmanager/FredPluginHTTP.java 2006-12-15 
21:55:54 UTC (rev 11425)
@@ -3,7 +3,7 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.pluginmanager;

-import freenet.clients.http.HTTPRequest;
+import freenet.support.api.HTTPRequest;

 public interface FredPluginHTTP {


Modified: trunk/freenet/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginManager.java  2006-12-15 
21:39:13 UTC (rev 11424)
+++ trunk/freenet/src/freenet/pluginmanager/PluginManager.java  2006-12-15 
21:55:54 UTC (rev 11425)
@@ -18,7 +18,6 @@
 import java.util.Set;
 import java.util.jar.JarFile;

-import freenet.clients.http.HTTPRequest;
 import freenet.config.InvalidConfigValueException;
 import freenet.config.StringArrCallback;
 import freenet.config.StringArrOption;
@@ -29,6 +28,7 @@
 import freenet.node.useralerts.UserAlert;
 import freenet.support.Logger;
 import freenet.support.URIPreEncoder;
+import freenet.support.api.HTTPRequest;

 public class PluginManager {


Copied: trunk/freenet/src/freenet/support/api/HTTPRequest.java (from rev 11407, 
trunk/freenet/src/freenet/clients/http/HTTPRequest.java)
===================================================================
--- trunk/freenet/src/freenet/support/api/HTTPRequest.java                      
        (rev 0)
+++ trunk/freenet/src/freenet/support/api/HTTPRequest.java      2006-12-15 
21:55:54 UTC (rev 11425)
@@ -0,0 +1,122 @@
+package freenet.support.api;
+
+
+public interface HTTPRequest {
+
+       /**
+        * The path of this request, where the part of the path the specified 
the
+        * plugin has already been removed..
+        */
+       public String getPath();
+
+       /**
+        * 
+        * @return true if the query string was totally empty
+        */
+       public boolean hasParameters();
+
+       /**
+        * Check if a parameter was set in the request at all, either with or
+        * without a value.
+        * 
+        * @param name
+        *            the name of the parameter to check
+        * @return true if the parameter was set in the request, not regarding 
if
+        *         the value is empty
+        */
+       public boolean isParameterSet(String name);
+
+       /**
+        * Get the value of a request parameter, using an empty string as 
default
+        * value if the parameter was not set. This method will never return 
null,
+        * so its safe to do things like
+        * 
+        * <p>
+        * <code>
+        *   if (request.getParam(&quot;abc&quot;).equals(&quot;def&quot;))
+        * </code>
+        * </p>
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @return the parameter value as String, or an empty String if the 
value
+        *         was missing or empty
+        */
+       public String getParam(String name);
+
+       /**
+        * Get the value of a request parameter, using the specified default 
value
+        * if the parameter was not set or has an empty value.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @param defaultValue
+        *            the default value to be returned if the parameter is 
missing
+        *            or empty
+        * @return either the parameter value as String, or the default value
+        */
+       public String getParam(String name, String defaultValue);
+
+       /**
+        * Get the value of a request parameter converted to an int, using 0 as
+        * default value. If there are multiple values for this parameter, the 
first
+        * value is used.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @return either the parameter value as int, or 0 if the parameter is
+        *         missing, empty or invalid
+        */
+       public int getIntParam(String name);
+
+       /**
+        * Get the value of a request parameter converted to an 
<code>int</code>,
+        * using the specified default value. If there are multiple values for 
this
+        * parameter, the first value is used.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @param defaultValue
+        *            the default value to be returned if the parameter is 
missing,
+        *            empty or invalid
+        * @return either the parameter value as int, or the default value
+        */
+       public int getIntParam(String name, int defaultValue);
+
+       public int getIntPart(String name, int defaultValue);
+
+       /**
+        * Get all values of a request parameter as a string array. If the 
parameter
+        * was not set at all, an empty array is returned, so this method will 
never
+        * return <code>null</code>.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @return an array of all paramter values that might include empty 
values
+        */
+       public String[] getMultipleParam(String name);
+
+       /**
+        * Get all values of a request parameter as int array, ignoring all 
values
+        * that can not be parsed. If the parameter was not set at all, an empty
+        * array is returned, so this method will never return 
<code>null</code>.
+        * 
+        * @param name
+        *            the name of the parameter to get
+        * @return an int array of all parameter values that could be parsed as 
int
+        */
+       public int[] getMultipleIntParam(String name);
+
+       public HTTPUploadedFile getUploadedFile(String name);
+
+       public Bucket getPart(String name);
+
+       public boolean isPartSet(String name);
+
+       public String getPartAsString(String name, int maxlength);
+
+       public void freeParts();
+
+       public long getLongParam(String name, long defaultValue);
+
+}
\ No newline at end of file

Added: trunk/freenet/src/freenet/support/api/HTTPUploadedFile.java
===================================================================
--- trunk/freenet/src/freenet/support/api/HTTPUploadedFile.java                 
        (rev 0)
+++ trunk/freenet/src/freenet/support/api/HTTPUploadedFile.java 2006-12-15 
21:55:54 UTC (rev 11425)
@@ -0,0 +1,27 @@
+package freenet.support.api;
+
+
+public interface HTTPUploadedFile {
+
+       /**
+        * Returns the content type of the file.
+        * 
+        * @return The content type of the file
+        */
+       public String getContentType();
+
+       /**
+        * Returns the data of the file.
+        * 
+        * @return The data of the file
+        */
+       public Bucket getData();
+
+       /**
+        * Returns the name of the file.
+        * 
+        * @return The name of the file
+        */
+       public String getFilename();
+
+}
\ No newline at end of file

Modified: trunk/plugins/Librarian/Librarian.java
===================================================================
--- trunk/plugins/Librarian/Librarian.java      2006-12-15 21:39:13 UTC (rev 
11424)
+++ trunk/plugins/Librarian/Librarian.java      2006-12-15 21:55:54 UTC (rev 
11425)
@@ -10,7 +10,6 @@
 import freenet.client.FetchException;
 import freenet.client.FetchResult;
 import freenet.client.HighLevelSimpleClient;
-import freenet.clients.http.HTTPRequest;
 import freenet.clients.http.filter.CommentException;
 import freenet.clients.http.filter.FilterCallback;
 import freenet.keys.FreenetURI;
@@ -20,6 +19,7 @@
 import freenet.pluginmanager.PluginHTTPException;
 import freenet.pluginmanager.PluginRespirator;
 import freenet.support.HTMLEncoder;
+import freenet.support.api.HTTPRequest;

 public class Librarian implements FredPlugin, FredPluginHTTP, 
FredPluginThreadless {


Modified: trunk/plugins/TestGallery/TestGallery.java
===================================================================
--- trunk/plugins/TestGallery/TestGallery.java  2006-12-15 21:39:13 UTC (rev 
11424)
+++ trunk/plugins/TestGallery/TestGallery.java  2006-12-15 21:55:54 UTC (rev 
11425)
@@ -5,13 +5,13 @@
 import java.util.Random;

 import freenet.client.HighLevelSimpleClient;
-import freenet.clients.http.HTTPRequest;
 import freenet.keys.FreenetURI;
 import freenet.pluginmanager.FredPlugin;
 import freenet.pluginmanager.FredPluginHTTP;
 import freenet.pluginmanager.FredPluginThreadless;
 import freenet.pluginmanager.PluginHTTPException;
 import freenet.pluginmanager.PluginRespirator;
+import freenet.support.api.HTTPRequest;

 public class TestGallery implements FredPlugin, FredPluginHTTP, 
FredPluginThreadless {



Reply via email to