Author: toad
Date: 2006-12-12 00:24:26 +0000 (Tue, 12 Dec 2006)
New Revision: 11347
Modified:
trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
trunk/freenet/src/freenet/clients/http/HTTPRequest.java
trunk/freenet/src/freenet/clients/http/NinjaSpider.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/keys/FreenetURI.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/fcp/ClientGet.java
trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java
trunk/freenet/src/freenet/node/fcp/ClientPutBase.java
trunk/freenet/src/freenet/node/fcp/FCPServer.java
trunk/freenet/src/freenet/node/fcp/GetFailedMessage.java
trunk/freenet/src/freenet/node/fcp/PersistentGet.java
trunk/freenet/src/freenet/node/fcp/PersistentPut.java
trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java
trunk/freenet/src/freenet/node/fcp/PutFetchableMessage.java
trunk/freenet/src/freenet/node/updater/NodeUpdaterManager.java
trunk/freenet/src/freenet/support/URLDecoder.java
trunk/freenet/src/freenet/support/URLEncoder.java
Log:
Use URL encoding/decoding for Freenet URI's.
They are a kind of URI, therefore they need to adhere to URI syntax.
Fixes #814. If you include a ? in a freenet URI, it will be encoded. You can
even include a slash in the middle of a manifest component (I think; try it),
as long as it's encoded.
Better to get this over with sooner rather than later...
Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -102,7 +102,7 @@
try {
if((!force) && (!forceDownload)) {
- FilterOutput fo = ContentFilter.filter(data,
bucketFactory, mimeType, new URI(basePath +
URLEncoder.encode(key.toString(false))), null);
+ FilterOutput fo = ContentFilter.filter(data,
bucketFactory, mimeType, key.toURI(basePath), null);
data = fo.data;
mimeType = fo.type;
@@ -121,20 +121,20 @@
HTMLNode optionList =
infoboxContent.addChild("ul");
HTMLNode option =
optionList.addChild("li");
- option.addChild("a", "href", basePath +
key.toString(false) + "?type=text/plain&force=" + getForceValue(key,
now)+extras, "Click here");
+ option.addChild("a", "href", basePath +
key.toString() + "?type=text/plain&force=" + getForceValue(key, now)+extras,
"Click here");
option.addChild("%", " to open the file
as plain text (this <b>may be dangerous</b> if you are running IE7 or FF2).");
// FIXME: is this safe? See bug
#131
option = optionList.addChild("li");
- option.addChild("a", "href", basePath +
key.toString(false) + "?forcedownload"+extras, "Click here");
+ option.addChild("a", "href", basePath +
key.toString() + "?forcedownload"+extras, "Click here");
option.addChild("%", " to try to force
your browser to download the file to disk (<b>this may also be dangerous if you
run Firefox 2.0.0 (2.0.1 should fix this)</b>).");
if(!mimeType.startsWith("text/plain")) {
option =
optionList.addChild("li");
- option.addChild("a", "href",
basePath + key.toString(false) + "?force=" + getForceValue(key, now)+extras,
"Click here");
+ option.addChild("a", "href",
basePath + key.toString() + "?force=" + getForceValue(key, now)+extras, "Click
here");
option.addChild("#", " to open
the file as " + mimeType);
option.addChild("%", " (<b>this
may also be dangerous</b>).");
}
option = optionList.addChild("li");
- option.addChild("a", "href", basePath +
key.toString(false) + "?type=application/xml+rss&force=" + getForceValue(key,
now)+extras, "Click here");
+ option.addChild("a", "href", basePath +
key.toString() + "?type=application/xml+rss&force=" + getForceValue(key,
now)+extras, "Click here");
option.addChild("%", " to open the file
as RSS (<b>this is dangerous if the site author is malicious</b>).");
if(referrer != null) {
option =
optionList.addChild("li");
@@ -177,14 +177,14 @@
infoboxContent.addChild("p", "Your options are:");
HTMLNode optionList = infoboxContent.addChild("ul");
HTMLNode option = optionList.addChild("li");
- option.addChild("a", "href", basePath +
key.toString(false) + "?type=text/plain"+extras, "Click here");
+ option.addChild("a", "href", basePath + key.toString()
+ "?type=text/plain"+extras, "Click here");
option.addChild("#", " to open the file as plain text
(this should not be dangerous but it may be garbled).");
// FIXME: is this safe? See bug #131
option = optionList.addChild("li");
- option.addChild("a", "href", basePath +
key.toString(false) + "?forcedownload"+extras, "Click here");
+ option.addChild("a", "href", basePath + key.toString()
+ "?forcedownload"+extras, "Click here");
option.addChild("#", " to force your browser to
download the file to disk.");
option = optionList.addChild("li");
- option.addChild("a", "href", basePath +
key.toString(false) + "?force=" + getForceValue(key, now)+extras, "Click here");
+ option.addChild("a", "href", basePath + key.toString()
+ "?force=" + getForceValue(key, now)+extras, "Click here");
option.addChild("#", " to open the file as " + mimeType
+ '.');
if(referrer != null) {
option = optionList.addChild("li");
@@ -350,7 +350,7 @@
String msg = e.getMessage();
String extra = "";
if(e.mode == FetchException.NOT_ENOUGH_PATH_COMPONENTS)
{
- this.writePermanentRedirect(ctx, "Not enough
meta-strings", '/' + key.toString(false) + '/' + override);
+ this.writePermanentRedirect(ctx, "Not enough
meta-strings", '/' + key.toString() + '/' + override);
} else if(e.newURI != null) {
this.writePermanentRedirect(ctx, msg, '/'
+e.newURI.toString() + override);
} else if(e.mode == FetchException.TOO_BIG) {
@@ -363,7 +363,7 @@
HTMLNode fileInformationList =
infoboxContent.addChild("ul");
HTMLNode option =
fileInformationList.addChild("li");
option.addChild("#", "Filename: ");
- option.addChild("a", "href", '/' +
key.toString(false), getFilename(e, key, e.getExpectedMimeType()));
+ option.addChild("a", "href", '/' +
key.toString(), getFilename(e, key, e.getExpectedMimeType()));
boolean finalized = e.finalizedSize();
if(e.expectedSize > 0) {
@@ -392,12 +392,12 @@
infoboxContent.addChild("#", "The Freenet key
you requested refers to a large file. Files of this size cannot generally be
sent directly to your browser since they take too long for your Freenet node to
retrieve. The following options are available:");
HTMLNode optionList =
infoboxContent.addChild("ul");
option = optionList.addChild("li");
- HTMLNode optionForm = option.addChild("form",
new String[] { "action", "method" }, new String[] {'/' + key.toString(false),
"get" });
+ HTMLNode optionForm = option.addChild("form",
new String[] { "action", "method" }, new String[] {'/' + key.toString(), "get"
});
optionForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "max-size",
String.valueOf(e.expectedSize == -1 ? Long.MAX_VALUE : e.expectedSize*2) });
optionForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "fetch", "Fetch anyway and
display file in browser" });
option = optionList.addChild("li");
optionForm = ctx.addFormChild(option,
"/queue/", "tooBigQueueForm");
- optionForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "key", key.toString(false)
});
+ optionForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "key", key.toString() });
optionForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "return-type", "disk" });
optionForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "persistence", "forever" });
if (mime != null) {
@@ -461,7 +461,7 @@
FreenetURI furi = new FreenetURI(path);
HTTPRequest req = new HTTPRequest(refererURI);
String type = req.getParam("type");
- referer = "/" + furi.toString(false);
+ referer = "/" + furi.toString();
if(type != null && type.length() > 0)
referer += "?type=" + type;
} catch (Throwable t) {
@@ -478,7 +478,7 @@
try{
bos.write(random);
- bos.write(key.toString(false).getBytes());
+ bos.write(key.toString().getBytes("UTF-8"));
bos.write(Long.toString(time /
FORCE_GRAIN_INTERVAL).getBytes());
} catch (IOException e) {
throw new Error(e);
Modified: trunk/freenet/src/freenet/clients/http/HTTPRequest.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/HTTPRequest.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/clients/http/HTTPRequest.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -9,6 +9,7 @@
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;
@@ -20,7 +21,6 @@
import freenet.support.Logger;
import freenet.support.MultiValueTable;
import freenet.support.SimpleReadOnlyArrayBucket;
-import freenet.support.URLDecoder;
import freenet.support.URLEncodedFormatException;
import freenet.support.io.Bucket;
import freenet.support.io.BucketFactory;
@@ -193,40 +193,37 @@
}
// url-decode the name and value
- try {
- if (doUrlDecoding) {
- name = URLDecoder.decode(name);
- value = URLDecoder.decode(value);
- if(logMINOR) {
- Logger.minor(this, "Decoded
name: "+name);
- Logger.minor(this, "Decoded
value: "+value);
- }
- }
-
- if(asParts) {
- // Store as a part
- byte[] buf;
+ if (doUrlDecoding) {
try {
- buf = value.getBytes("UTF-8");
+ name =
java.net.URLDecoder.decode(name, "UTF-8");
+ value =
java.net.URLDecoder.decode(value, "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);
+ }
+ if(logMINOR) {
+ Logger.minor(this, "Decoded name:
"+name);
+ Logger.minor(this, "Decoded value:
"+value);
}
- } catch (URLEncodedFormatException e) {
- // if we fail to decode the name or value we
fail spectacularly
- String msg = "Failed to decode request
parameter " + name
- + " with value '" + value +
'\'';
- throw new RuntimeException(msg, e);
}
+
+ 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);
+ }
}
}
Modified: trunk/freenet/src/freenet/clients/http/NinjaSpider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/NinjaSpider.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/clients/http/NinjaSpider.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -117,32 +117,17 @@
private synchronized void queueURI(FreenetURI uri) {
- byte[] uriBytes = uri.toString(false).getBytes();
-
/* Currently we don't handle PDF or other contents,
so it's not interresting to download them
*/
+ String tmp = uri.toString().toLowerCase();
+
if(htmlOnly
- && (uri.toString(false).toLowerCase().indexOf(".htm") < 0)
- && (uriBytes[uriBytes.length - 1] != '/'))
+ && (tmp.indexOf(".htm") < 0)
+ && (tmp.charAt(tmp.length()-1) != '/'))
return;
- /* We remove HTML targets from URI
(http://my.server/file#target) */
- /* Else we re-index already indexed file */
- String uriStr = null;
- try {
- uriStr = uri.toString(false);
- if(uriStr.indexOf("#") > 0)
- {
- uriStr = uriStr.substring(0,
uriStr.indexOf("#"));
- uri = new FreenetURI(uriStr);
- }
- } catch (MalformedURLException e) {
- Logger.error(this, "Spider: MalformedURLException:
"+uriStr+ ':' +e);
- return;
- }
-
if ((!visitedURIs.contains(uri)) && queuedURISet.add(uri)) {
queuedURIList.addLast(uri);
visitedURIs.add(uri);
@@ -198,11 +183,11 @@
Bucket data = result.asBucket();
String mimeType = cm.getMIMEType();
- sizeOfURIs.put(uri.toString(false), new Long(data.size()));
- mimeOfURIs.put(uri.toString(false), mimeType);
+ sizeOfURIs.put(uri.toString(), new Long(data.size()));
+ mimeOfURIs.put(uri.toString(), mimeType);
try {
- ContentFilter.filter(data, ctx.bucketFactory, mimeType,
new URI("http://127.0.0.1:8888/" + uri.toString(false)), this);
+ ContentFilter.filter(data, ctx.bucketFactory, mimeType,
new URI("http://127.0.0.1:8888/" + uri.toString()), this);
} catch (UnsafeContentTypeException e) {
return; // Ignore
} catch (IOException e) {
@@ -257,7 +242,7 @@
if((type != null) && (type.length() != 0) &&
type.toLowerCase().equals("title")
&& (s != null) && (s.length() != 0) && (s.indexOf('\n') <
0)) {
/* We should have a correct title */
- titlesOfURIs.put(uri.toString(false), s);
+ titlesOfURIs.put(uri.toString(), s);
type = "title";
}
else
@@ -268,7 +253,7 @@
Integer lastPosition = null;
- lastPosition =
(Integer)lastPositionByURI.get(uri.toString(false));
+ lastPosition = (Integer)lastPositionByURI.get(uri.toString());
if(lastPosition == null)
lastPosition = new Integer(1); /* We start to count
from 1 */
@@ -287,7 +272,7 @@
if(type == null) {
lastPosition = new Integer(lastPosition.intValue() +
words.length);
- lastPositionByURI.put(uri.toString(false),
lastPosition);
+ lastPositionByURI.put(uri.toString(), lastPosition);
}
}
@@ -307,12 +292,12 @@
/* Word position indexation */
- HashMap wordPositionsForOneUri =
(HashMap)positionsByWordByURI.get(uri.toString(false)); /* For a given URI,
take as key a word, and gives position */
+ HashMap wordPositionsForOneUri =
(HashMap)positionsByWordByURI.get(uri.toString()); /* For a given URI, take as
key a word, and gives position */
if(wordPositionsForOneUri == null) {
wordPositionsForOneUri = new HashMap();
wordPositionsForOneUri.put(word, new Integer[] { new
Integer(position) });
- positionsByWordByURI.put(uri.toString(false),
wordPositionsForOneUri);
+ positionsByWordByURI.put(uri.toString(),
wordPositionsForOneUri);
} else {
Integer[] positions =
(Integer[])wordPositionsForOneUri.get(word);
@@ -449,20 +434,20 @@
Element fileElement = xmlDoc.createElement("file");
fileElement.setAttribute("id", Integer.toString(i));
- fileElement.setAttribute("key",
uris[i].toString(false));
+ fileElement.setAttribute("key", uris[i].toString());
- Long size =
(Long)sizeOfURIs.get(uris[i].toString(false));
+ Long size = (Long)sizeOfURIs.get(uris[i].toString());
if(size == null) {
Logger.error(this, "Spider: size is missing");
} else {
fileElement.setAttribute("size",
size.toString());
}
- fileElement.setAttribute("mime",
((String)mimeOfURIs.get(uris[i].toString(false))));
+ fileElement.setAttribute("mime",
((String)mimeOfURIs.get(uris[i].toString())));
Element titleElement = xmlDoc.createElement("option");
titleElement.setAttribute("name", "title");
- titleElement.setAttribute("value",
(String)titlesOfURIs.get(uris[i].toString(false)));
+ titleElement.setAttribute("value",
(String)titlesOfURIs.get(uris[i].toString()));
fileElement.appendChild(titleElement);
filesElement.appendChild(fileElement);
@@ -493,7 +478,7 @@
uriElement.setAttribute("id", x.toString());
/* Position by position */
- HashMap positionsForGivenWord =
(HashMap)positionsByWordByURI.get(uri.toString(false));
+ HashMap positionsForGivenWord =
(HashMap)positionsByWordByURI.get(uri.toString());
Integer[] positions =
(Integer[])positionsForGivenWord.get(words[i]);
StringBuffer positionList = new StringBuffer();
Modified: trunk/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/QueueToadlet.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/clients/http/QueueToadlet.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -308,7 +308,7 @@
ClientRequest clientRequest =
clientRequests[requestIndex];
if (clientRequest.hasFinished() &&
(clientRequest instanceof ClientGet)) {
ClientGet clientGet =
(ClientGet) clientRequest;
- if
(clientGet.getURI().toString(false).equals(key.toString(false))) {
+ if
(clientGet.getURI().equals(key)) {
Bucket data =
clientGet.getBucket();
String mimeType =
clientGet.getMIMEType();
String
requestedMimeType = request.getParam("type", null);
@@ -767,7 +767,7 @@
private HTMLNode createDownloadCell(PageMaker pageMaker, ClientGet p) {
HTMLNode downloadCell = new HTMLNode("td", "class",
"request-download");
- downloadCell.addChild("a", "href", p.getURI().toString(false),
"Download");
+ downloadCell.addChild("a", "href", p.getURI().toString(),
"Download");
return downloadCell;
}
@@ -794,7 +794,7 @@
private HTMLNode createKeyCell(FreenetURI uri) {
HTMLNode keyCell = new HTMLNode("td", "class", "request-key");
if (uri != null) {
- keyCell.addChild("span", "class",
"key_is").addChild("a", "href", '/' + uri.toString(false), uri.toShortString());
+ keyCell.addChild("span", "class",
"key_is").addChild("a", "href", '/' + uri.toString(), uri.toShortString());
} else {
keyCell.addChild("span", "class", "key_unknown",
"unknown");
}
Modified: trunk/freenet/src/freenet/clients/http/Spider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Spider.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/clients/http/Spider.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -72,23 +72,6 @@
private boolean stopped = true;
private synchronized void queueURI(FreenetURI uri) {
- String uriStr = null;
-
- /* We remove HTML targets from URI
(http://my.server/file#target) */
- /* Else we re-index already indexed file */
- try {
- uriStr = uri.toString(false);
- if(uriStr.indexOf("#") > 0)
- {
- uriStr = uriStr.substring(0,
uriStr.indexOf("#"));
- uri = new FreenetURI(uriStr);
- }
- } catch (MalformedURLException e) {
- Logger.error(this, "Spider: MalformedURLException:
"+uriStr+ ':' +e);
- return;
- }
-
-
if ((!visitedURIs.contains(uri)) && queuedURISet.add(uri)) {
queuedURIList.addLast(uri);
visitedURIs.add(uri);
@@ -152,7 +135,7 @@
Bucket data = result.asBucket();
String mimeType = cm.getMIMEType();
try {
- ContentFilter.filter(data, ctx.bucketFactory, mimeType,
new URI("http://127.0.0.1:8888/" + uri.toString(false)), this);
+ ContentFilter.filter(data, ctx.bucketFactory, mimeType,
uri.toURI("http://127.0.0.1:8888/"), this);
} catch (UnsafeContentTypeException e) {
return; // Ignore
} catch (IOException e) {
@@ -207,7 +190,7 @@
if((type != null) && (type.length() != 0) &&
type.toLowerCase().equals("title")
&& (s != null) && (s.length() != 0) && (s.indexOf('\n') <
0)) {
/* We should have a correct title */
- titlesOfURIs.put(uri.toString(false), s);
+ titlesOfURIs.put(uri.toString(), s);
}
@@ -266,8 +249,8 @@
HashMap urisToNumbers = new HashMap();
for (int i = 0; i < uris.length; i++) {
urisToNumbers.put(uris[i], new Integer(i));
- bw.write('!' + uris[i].toString(false) + '\n');
- bw.write("+" +
titlesOfURIs.get(uris[i].toString(false)) + '\n');
+ bw.write('!' + uris[i].toString() + '\n');
+ bw.write("+" + titlesOfURIs.get(uris[i].toString()) +
'\n');
}
for (int i = 0; i < words.length; i++) {
StringBuffer s = new StringBuffer();
@@ -414,7 +397,7 @@
int itemCount = 0;
while (collectionItems.hasNext()) {
FreenetURI uri = (FreenetURI) collectionItems.next();
- listContent.addChild("#", uri.toString(false));
+ listContent.addChild("#", uri.toString());
listContent.addChild("br");
if (itemCount++ == maxCount) {
listContent.addChild("br");
Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -334,8 +334,9 @@
key = this.insert(block, filenameHint, false);
HTMLNode infobox =
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-success", "Insert
Succeeded"));
content =
ctx.getPageMaker().getContentNode(infobox);
+ String u = key.toString();
content.addChild("#", "The key ");
- content.addChild("a", "href", '/' +
key.toString(false), key.toString(false));
+ content.addChild("a", "href", '/' + u, u);
content.addChild("#", " has been inserted
successfully.");
} catch (InserterException e) {
HTMLNode infobox =
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Insert
Failed"));
Modified:
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
===================================================================
---
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
2006-12-11 20:59:56 UTC (rev 11346)
+++
trunk/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
2006-12-12 00:24:26 UTC (rev 11347)
@@ -44,7 +44,7 @@
public GenericReadFilterCallback(FreenetURI uri, FoundURICallback cb) {
try {
- this.baseURI = new URI('/' + uri.toString(false));
+ this.baseURI = uri.toRelativeURI();
this.cb = cb;
} catch (URISyntaxException e) {
throw new Error(e);
@@ -196,7 +196,7 @@
// Now what about the queries?
HTTPRequest req = new HTTPRequest(uri);
if(cb != null) cb.foundURI(furi);
- return finishProcess(req, overrideType, '/' +
furi.toString(false), uri, noRelative);
+ return finishProcess(req, overrideType, '/' +
furi.toString(false, false), uri, noRelative);
}
public String onBaseHref(String baseHref) {
Modified: trunk/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- trunk/freenet/src/freenet/keys/FreenetURI.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/keys/FreenetURI.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -8,7 +8,11 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.StringTokenizer;
@@ -19,8 +23,7 @@
import freenet.support.HexUtil;
import freenet.support.IllegalBase64Exception;
import freenet.support.Logger;
-import freenet.support.URLDecoder;
-import freenet.support.URLEncodedFormatException;
+import freenet.support.URLEncoder;
import freenet.client.InserterException;
/**
@@ -216,12 +219,12 @@
throw new MalformedURLException("No URI specified");
}
- int percent = URI.indexOf('%');
- int slash = URI.indexOf('/');
- if((percent>-1) && ((percent<slash) || (slash<0))){ /* likely
to be a copy/pasted url from a browser */
- try{
- URI=URLDecoder.decode(URI);
- }catch(URLEncodedFormatException e){
+ if(URI.indexOf('@') < 0 || URI.indexOf('/') < 0) {
+ // Encoded URL?
+ try {
+ URI=URLDecoder.decode(URI, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new Error(e);
}
}
@@ -246,7 +249,12 @@
int slash2;
sv = new Vector();
while ((slash2 = URI.lastIndexOf("/")) != -1) {
- String s = URI.substring(slash2 + "/".length());
+ String s;
+ try {
+ s = URLDecoder.decode(URI.substring(slash2 +
"/".length()), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new Error(e);
+ }
if (s != null)
sv.addElement(s);
URI = URI.substring(0, slash2);
@@ -493,10 +501,14 @@
}
public String toString() {
- return toString(true);
+ return toString(false, false);
}
+
+ public String toACIIString() {
+ return toString(true, true);
+ }
- public String toString(boolean prefix) {
+ public String toString(boolean prefix, boolean pureAscii) {
StringBuffer b;
if (prefix)
b = new StringBuffer("freenet:");
@@ -517,14 +529,14 @@
}
if (docName != null)
- b.append(docName);
+ b.append(URLEncoder.encode(docName, "/", pureAscii));
if(keyType.equals("USK")) {
b.append('/');
b.append(suggestedEdition);
}
if (metaStr != null) {
for (int i = 0; i < metaStr.length; i++) {
- b.append('/').append(metaStr[i]);
+
b.append('/').append(URLEncoder.encode(metaStr[i], "/", pureAscii));
}
}
return b.toString();
@@ -542,14 +554,14 @@
}
if (docName != null)
- b.append(docName);
+ b.append(URLEncoder.encode(docName, "/", false));
if(keyType.equals("USK")) {
b.append('/');
b.append(suggestedEdition);
}
if (metaStr != null) {
for (int i = 0; i < metaStr.length; i++) {
- b.append('/').append(metaStr[i]);
+
b.append('/').append(URLEncoder.encode(metaStr[i], "/", false));
}
}
return b.toString();
@@ -783,4 +795,14 @@
public static void checkInsertURI(FreenetURI uri) throws
InserterException { uri.checkInsertURI(); }
+ public URI toRelativeURI() throws URISyntaxException {
+ // Single-argument constructor used because it preserves
encoded /'es in path.
+ // Hence we can have slashes, question marks etc in the path,
but they are encoded.
+ return new URI('/' + toString(false, false));
+ }
+
+ public URI toURI(String basePath) throws URISyntaxException {
+ return new URI(basePath + toString(false, false));
+ }
+
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-12-11 20:59:56 UTC (rev
11346)
+++ trunk/freenet/src/freenet/node/Node.java 2006-12-12 00:24:26 UTC (rev
11347)
@@ -1622,7 +1622,7 @@
public SimpleFieldSet exportPrivateFieldSet() {
SimpleFieldSet fs = exportPublicFieldSet(false);
fs.put("dsaPrivKey", myPrivKey.asFieldSet());
- fs.put("ark.privURI",
this.myARK.getInsertURI().toString(false));
+ fs.put("ark.privURI", this.myARK.getInsertURI().toString(false,
false));
return fs;
}
@@ -1662,7 +1662,7 @@
fs.put("dsaPubKey", myPubKey.asFieldSet());
}
fs.put("ark.number", Long.toString(this.myARKNumber)); // Can
be changed on setup
- fs.put("ark.pubURI", this.myARK.getURI().toString(false)); //
Can be changed on setup
+ fs.put("ark.pubURI", this.myARK.getURI().toString(false,
false)); // Can be changed on setup
synchronized (referenceSync) {
if(myReferenceSignature == null || mySignedReference ==
null || !mySignedReference.equals(fs.toOrderedString())){
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -1948,7 +1948,7 @@
if(myARK != null) {
// Decrement it because we keep the number we would
like to fetch, not the last one fetched.
fs.put("ark.number",
Long.toString(myARK.suggestedEdition - 1));
- fs.put("ark.pubURI",
myARK.getBaseSSK().toString(false));
+ fs.put("ark.pubURI", myARK.getBaseSSK().toString(false,
false));
}
return fs;
}
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -558,13 +558,13 @@
}
} else if(uline.startsWith("MAKESSK")) {
InsertableClientSSK key = InsertableClientSSK.createRandom(r,
"");
- outsb.append("Insert URI:
").append(key.getInsertURI().toString(false)).append("\r\n");
- outsb.append("Request URI:
").append(key.getURI().toString(false)).append("\r\n");
+ outsb.append("Insert URI:
").append(key.getInsertURI().toString(false, false)).append("\r\n");
+ outsb.append("Request URI: ").append(key.getURI().toString(false,
false)).append("\r\n");
FreenetURI insertURI =
key.getInsertURI().setDocName("testsite");
- String fixedInsertURI = insertURI.toString(false);
+ String fixedInsertURI = insertURI.toString(false, false);
outsb.append("Note that you MUST add a filename to the end of the
above URLs e.g.:\r\n").append(fixedInsertURI).append("\r\n");
outsb.append("Normally you will then do PUTSSKDIR:<insert
URI>#<directory to upload>, for
example:\r\nPUTSSKDIR:").append(fixedInsertURI).append("#directoryToUpload/\r\n");
- outsb.append("This will then produce a manifest site containing
all the files, the default document can be accessed
at\r\n").append(key.getURI().toString(false)).append("testsite/");
+ outsb.append("This will then produce a manifest site containing
all the files, the default document can be accessed
at\r\n").append(key.getURI().toString(false, false)).append("testsite/");
} else if(uline.startsWith("PUTSSK:")) {
String cmd = line.substring("PUTSSK:".length());
cmd = cmd.trim();
Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -471,7 +471,7 @@
public synchronized SimpleFieldSet getFieldSet() {
SimpleFieldSet fs = new SimpleFieldSet(); // we will need
multi-level later...
fs.put("Type", "GET");
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
fs.put("Identifier", identifier);
fs.put("Verbosity", Integer.toString(verbosity));
fs.put("PriorityClass", Short.toString(priorityClass));
Modified: trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -188,7 +188,7 @@
public SimpleFieldSet getFieldSet() {
SimpleFieldSet fs = new SimpleFieldSet();
fs.put("IgnoreDS", Boolean.toString(ignoreDS));
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
fs.put("Identifier", identifier);
fs.put("Verbosity", Integer.toString(verbosity));
fs.put("ReturnType", getReturnTypeString());
Modified: trunk/freenet/src/freenet/node/fcp/ClientPutBase.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutBase.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutBase.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -245,7 +245,7 @@
public synchronized SimpleFieldSet getFieldSet() {
SimpleFieldSet fs = new SimpleFieldSet(); // we will need
multi-level later...
fs.put("Type", getTypeName());
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
fs.put("Identifier", identifier);
fs.put("Verbosity", Integer.toString(verbosity));
fs.put("PriorityClass", Short.toString(priorityClass));
@@ -258,7 +258,7 @@
fs.put("Succeeded", Boolean.toString(succeeded));
fs.put("GetCHKOnly", Boolean.toString(getCHKOnly));
if(generatedURI != null)
- fs.put("GeneratedURI", generatedURI.toString(false));
+ fs.put("GeneratedURI", generatedURI.toString(false,
false));
if(finished && (!succeeded))
// Should have a putFailedMessage... unless there is a
race condition.
fs.put("PutFailed",
putFailedMessage.getFieldSet(false));
Modified: trunk/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPServer.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/FCPServer.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -635,7 +635,7 @@
return;
} catch (IdentifierCollisionException e) {
try {
-
innerMakePersistentGlobalRequest(fetchURI, persistence, returnType,
"FProxy:"+fetchURI.toString(false), returnFilename, returnTempFilename);
+
innerMakePersistentGlobalRequest(fetchURI, persistence, returnType,
"FProxy:"+fetchURI.toString(false, false), returnFilename, returnTempFilename);
return;
} catch (IdentifierCollisionException e1) {
// FIXME maybe use DateFormat
Modified: trunk/freenet/src/freenet/node/fcp/GetFailedMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/GetFailedMessage.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/GetFailedMessage.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -119,7 +119,7 @@
if(finalizedExpected)
sfs.put("FinalizedExpected", "true");
if(redirectURI != null)
- sfs.put("RedirectURI", redirectURI.toString(false));
+ sfs.put("RedirectURI", redirectURI.toString(false,
false));
return sfs;
}
Modified: trunk/freenet/src/freenet/node/fcp/PersistentGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/PersistentGet.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/PersistentGet.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -51,7 +51,7 @@
public SimpleFieldSet getFieldSet() {
SimpleFieldSet fs = new SimpleFieldSet();
fs.put("Identifier", identifier);
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
fs.put("Verbosity", verbosity);
fs.put("ReturnType",
ClientGetMessage.returnTypeString(returnType));
fs.put("PersistenceType",
ClientRequest.persistenceTypeString(persistenceType));
Modified: trunk/freenet/src/freenet/node/fcp/PersistentPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/PersistentPut.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/PersistentPut.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -53,7 +53,7 @@
public SimpleFieldSet getFieldSet() {
SimpleFieldSet fs = new SimpleFieldSet();
fs.put("Identifier", identifier);
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
fs.put("Verbosity", verbosity);
fs.put("PriorityClass", priorityClass);
fs.put("UploadFrom",
ClientPutMessage.uploadFromString(uploadFrom));
Modified: trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -49,7 +49,7 @@
public SimpleFieldSet getFieldSet() {
SimpleFieldSet fs = new SimpleFieldSet();
fs.put("Identifier", identifier);
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
fs.put("Verbosity", Integer.toString(verbosity));
fs.put("PriorityClass", Short.toString(priorityClass));
fs.put("Persistence",
ClientRequest.persistenceTypeString(persistenceType));
Modified: trunk/freenet/src/freenet/node/fcp/PutFetchableMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/PutFetchableMessage.java 2006-12-11
20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/fcp/PutFetchableMessage.java 2006-12-12
00:24:26 UTC (rev 11347)
@@ -21,7 +21,7 @@
SimpleFieldSet fs = new SimpleFieldSet();
fs.put("Identifier", identifier);
if(uri != null)
- fs.put("URI", uri.toString(false));
+ fs.put("URI", uri.toString(false, false));
return fs;
}
Modified: trunk/freenet/src/freenet/node/updater/NodeUpdaterManager.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdaterManager.java
2006-12-11 20:59:56 UTC (rev 11346)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdaterManager.java
2006-12-12 00:24:26 UTC (rev 11347)
@@ -705,7 +705,7 @@
}
public String get() {
- return getURI(isExt).toString(false);
+ return getURI(isExt).toString(false, false);
}
public void set(String val) throws InvalidConfigValueException {
@@ -723,7 +723,7 @@
public class UpdateRevocationURICallback implements StringCallback {
public String get() {
- return getRevocationURI().toString(false);
+ return getRevocationURI().toString(false, false);
}
public void set(String val) throws InvalidConfigValueException {
Modified: trunk/freenet/src/freenet/support/URLDecoder.java
===================================================================
--- trunk/freenet/src/freenet/support/URLDecoder.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/support/URLDecoder.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -2,6 +2,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
/*
This code is part of the Java Adaptive Network Client by Ian Clarke.
@@ -11,28 +12,15 @@
/**
- * The class contains a utility method for converting a
- * <code>String</code> out of a MIME format called
- * "<code>x-www-form-urlencoded</code>" format.
- * <p>
- * To convert a <code>String</code>, each character is examined in turn:
- * <ul>
- * <li>The ASCII characters '<code>a</code>' through '<code>z</code>',
- * '<code>A</code>' through '<code>Z</code>', and '<code>0</code>'
- * through '<code>9</code>' remain the same.
- * <li>The plus sign '<code>+</code>' is converted into a
- * space character '<code> </code>'.
- * <li>The percent sign '<code>%</code>' must be followed by a
- * two-digit hexadecimal number, and is converted into the
- * corresponding 8-bit character.
- * <li>The following "safe" characters [RFC 1738] are passed as is,
- * if they appear:
- * <code>$ - _ . + ! * ' ( ) ,</code>
- * <li>Anything else encountered, though strictly speaking illegal,
- * is passed as is.
- * </ul>
- *
+ * Decode encoded URLs (or parts of URLs). @see URLEncoder.
+ * This class does NOT decode application/x-www-form-urlencoded
+ * strings, unlike @see java.net.URLDecoder. What it does is
+ * decode bits of URIs, in UTF-8. This simply means that it
+ * converts encoded characters (assuming a charset of UTF-8).
+ * java.net.URI does similar things internally.
+ *
* @author <a href="http://www.doc.ic.ac.uk/~twh1/">Theodore Hong</a>
+ * Originally!
**/
public class URLDecoder
@@ -45,11 +33,6 @@
}
/**
- * Characters which will be passed unaltered.
- **/
- private static final String safeCharList = "$-_.+!*'(),";
-
- /**
* Translates a string out of x-www-form-urlencoded format.
*
* @param s String to be translated.
@@ -66,10 +49,6 @@
char c = s.charAt(i);
if (Character.isLetterOrDigit(c))
decodedBytes.write(c);
- else if (c == '+')
- decodedBytes.write(' ');
- else if (safeCharList.indexOf(c) != -1)
- decodedBytes.write(c);
else if (c == '%') {
if (i >= len - 2) {
throw new URLEncodedFormatException(s);
@@ -88,9 +67,14 @@
} catch (NumberFormatException nfe) {
throw new URLEncodedFormatException(s);
}
- } else
- decodedBytes.write(c);
- // throw new URLEncodedFormatException(s);
+ } else {
+ try {
+ byte[] encoded =
(""+c).getBytes("UTF-8");
+ decodedBytes.write(encoded, 0,
encoded.length);
+ } catch (UnsupportedEncodingException e) {
+ throw new Error(e);
+ }
+ }
}
try {
decodedBytes.close();
Modified: trunk/freenet/src/freenet/support/URLEncoder.java
===================================================================
--- trunk/freenet/src/freenet/support/URLEncoder.java 2006-12-11 20:59:56 UTC
(rev 11346)
+++ trunk/freenet/src/freenet/support/URLEncoder.java 2006-12-12 00:24:26 UTC
(rev 11347)
@@ -1,39 +1,52 @@
package freenet.support;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Encodes strings for use in URIs. Note that this is <b>NOT</b> the same as
java.net.URLEncoder, which
+ * encodes strings to application/x-www-urlencoded. This is much closer to
what java.net.URI does. We
+ * don't turn spaces into +'s, and we allow through non-ascii characters
unless told not to.
+ */
public class URLEncoder {
// Moved here from FProxy by amphibian
- final static String safeURLCharacters =
"@*-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
+ final static String safeURLCharacters =
"*-_./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
/**
- * Encode a string for inclusion in HTML tags
+ * Encode a string for inclusion in a URI.
*
* @param URL String to encode
+ * @param force List of characters (in the form of a string) which must be
encoded as well as the built-in.
* @return HTML-safe version of string
*/
- public final static String encode(String URL) {
+ public final static String encode(String URL, String force, boolean ascii) {
StringBuffer enc = new StringBuffer(URL.length());
for (int i = 0; i < URL.length(); ++i) {
char c = URL.charAt(i);
- if (safeURLCharacters.indexOf(c) >= 0) {
+ if (((safeURLCharacters.indexOf(c) >= 0) || ((!ascii) && c >= 0200))
+ && (force == null || force.indexOf(c) < 0)) {
enc.append(c);
} else {
- // Too harsh.
- // if (c < 0 || c > 255)
- // throw new RuntimeException("illegal code "+c+" of char
'"+URL.charAt(i)+"'");
- // else
-
- // Just keep lsb like:
- // http://java.sun.com/j2se/1.3/docs/api/java/net/URLEncoder.html
- c = (char) (c & '\u00ff');
- if (c < 16) {
- enc.append("%0");
- } else {
- enc.append('%');
- }
- enc.append(Integer.toHexString(c));
+ try {
+ byte[] encoded = ("" + c).getBytes("UTF-8");
+ for(int j=0;j<encoded.length;j++) {
+ byte b = encoded[j];
+ int x = b & 0xFF;
+ if(x < 16)
+ enc.append("%0");
+ else
+ enc.append('%');
+ enc.append(Integer.toHexString(x));
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new Error(e);
+ }
}
}
return enc.toString();
}
+ public static String encode(String s) {
+ return encode(s, null, false);
+ }
+
}