Author: toad
Date: 2006-05-18 19:13:36 +0000 (Thu, 18 May 2006)
New Revision: 8774
Added:
trunk/freenet/src/freenet/client/MetadataUnresolvedException.java
Modified:
trunk/freenet/src/freenet/client/ArchiveManager.java
trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
trunk/freenet/src/freenet/client/Metadata.java
trunk/freenet/src/freenet/client/async/ClientPutState.java
trunk/freenet/src/freenet/client/async/ClientPutter.java
trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java
trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
trunk/freenet/src/freenet/client/async/SingleFileInserter.java
trunk/freenet/src/freenet/client/async/SplitFileInserter.java
trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
trunk/freenet/src/freenet/client/async/USKInserter.java
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/freenet/node/fcp/ClientPut.java
Log:
723: Automatically chain manifests to avoid size limitations. => much bigger
freesites are now possible.
Small freesite inserting tested, medium size insert not tested yet i.e. this
may not work.
Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java 2006-05-18
15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java 2006-05-18
19:13:36 UTC (rev 8774)
@@ -274,16 +274,43 @@
}
Metadata metadata = new Metadata(dir);
TempStoreElement element = makeTempStoreBucket(-1);
- try {
- OutputStream os = element.bucket.getOutputStream();
- metadata.writeTo(new DataOutputStream(os));
- os.close();
- } catch (IOException e) {
- throw new ArchiveFailureException("Failed to create
metadata: "+e, e);
+ int x = 0;
+ while(true) {
+ try {
+ byte[] buf = metadata.writeToByteArray();
+ OutputStream os =
element.bucket.getOutputStream();
+ os.write(buf);
+ os.close();
+ addStoreElement(ctx, key, ".metadata", element);
+ break;
+ } catch (MetadataUnresolvedException e) {
+ try {
+ x = resolve(e, x, element, ctx, key);
+ } catch (IOException e1) {
+ throw new
ArchiveFailureException("Failed to create metadata: "+e1, e1);
+ }
+ } catch (IOException e1) {
+ throw new ArchiveFailureException("Failed to
create metadata: "+e1, e1);
+ }
}
- addStoreElement(ctx, key, ".metadata", element);
}
+ private int resolve(MetadataUnresolvedException e, int x,
TempStoreElement element, ArchiveStoreContext ctx, FreenetURI key) throws
IOException {
+ Metadata[] m = e.mustResolve;
+ for(int i=0;i<m.length;i++) {
+ try {
+ byte[] buf = m[i].writeToByteArray();
+ OutputStream os =
element.bucket.getOutputStream();
+ os.write(buf);
+ os.close();
+ addStoreElement(ctx, key, ".metadata-"+(x++),
element);
+ } catch (MetadataUnresolvedException e1) {
+ x = resolve(e, x, element, ctx, key);
+ }
+ }
+ return x;
+ }
+
private void addToDirectory(HashMap dir, String name, String prefix)
throws ArchiveFailureException {
int x = name.indexOf('/');
if(x < 0) {
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -127,8 +127,11 @@
try {
b = BucketTools.makeImmutableBucket(bucketFactory,
m.writeToByteArray());
} catch (IOException e) {
- Logger.error(this, "Bucket error: "+e);
+ Logger.error(this, "Bucket error: "+e, e);
throw new
InserterException(InserterException.INTERNAL_ERROR, e, null);
+ } catch (MetadataUnresolvedException e) {
+ Logger.error(this, "Impossible error: "+e, e);
+ throw new
InserterException(InserterException.INTERNAL_ERROR, e, null);
}
ClientKey k;
InsertBlock block = new InsertBlock(b, null, insertURI);
Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java 2006-05-18 15:30:32 UTC
(rev 8773)
+++ trunk/freenet/src/freenet/client/Metadata.java 2006-05-18 19:13:36 UTC
(rev 8774)
@@ -9,11 +9,15 @@
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Vector;
import freenet.keys.BaseClientKey;
import freenet.keys.ClientCHK;
import freenet.keys.FreenetURI;
import freenet.support.Bucket;
+import freenet.support.BucketFactory;
+import freenet.support.BucketTools;
import freenet.support.Fields;
import freenet.support.Logger;
@@ -26,6 +30,9 @@
/** Soft limit, to avoid memory DoS */
static final int MAX_SPLITFILE_BLOCKS = 100*1000;
+ // URI at which this Metadata has been/will be inserted.
+ FreenetURI resolvedURI;
+
// Actual parsed data
// document type
@@ -569,8 +576,9 @@
/**
* Write the data to a byte array.
+ * @throws MetadataUnresolvedException
*/
- public byte[] writeToByteArray() {
+ public byte[] writeToByteArray() throws MetadataUnresolvedException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
@@ -710,8 +718,9 @@
}
/** Write the metadata as binary.
- * @throws IOException If an I/O error occurred while writing the data.
*/
- public void writeTo(DataOutputStream dos) throws IOException {
+ * @throws IOException If an I/O error occurred while writing the data.
+ * @throws MetadataUnresolvedException */
+ public void writeTo(DataOutputStream dos) throws IOException,
MetadataUnresolvedException {
dos.writeLong(FREENET_METADATA_MAGIC);
dos.writeShort(0); // version
dos.writeByte(documentType);
@@ -783,6 +792,8 @@
if(documentType == SIMPLE_MANIFEST) {
dos.writeInt(manifestEntryCount);
+ boolean kill = false;
+ LinkedList unresolvedMetadata = null;
for(Iterator
i=manifestEntries.keySet().iterator();i.hasNext();) {
String name = (String) i.next();
byte[] nameData = name.getBytes("UTF-8");
@@ -790,11 +801,35 @@
dos.writeShort(nameData.length);
dos.write(nameData);
Metadata meta = (Metadata)
manifestEntries.get(name);
- byte[] data = meta.writeToByteArray();
- if(data.length > Short.MAX_VALUE) throw new
IllegalArgumentException("Manifest data too long");
- dos.writeShort(data.length);
- dos.write(data);
+ try {
+ byte[] data = meta.writeToByteArray();
+ if(data.length > Short.MAX_VALUE) {
+ FreenetURI uri =
meta.resolvedURI;
+ if(uri != null) {
+ meta = new
Metadata(SIMPLE_REDIRECT, uri, null);
+ data =
meta.writeToByteArray();
+ } else {
+ kill = true;
+ if(unresolvedMetadata
== null)
+
unresolvedMetadata = new LinkedList();
+
unresolvedMetadata.addLast(meta);
+ }
+ }
+ dos.writeShort(data.length);
+ dos.write(data);
+ } catch (MetadataUnresolvedException e) {
+ Metadata[] m = e.mustResolve;
+ if(unresolvedMetadata == null)
+ unresolvedMetadata = new
LinkedList();
+ for(int j=0;j<m.length;j++)
+
unresolvedMetadata.addFirst(m[j]);
+ }
}
+ if(kill) {
+ Metadata[] meta =
+ (Metadata[])
unresolvedMetadata.toArray(new Metadata[unresolvedMetadata.size()]);
+ throw new MetadataUnresolvedException(meta,
"Manifest data too long and not resolved");
+ }
}
if(documentType == ZIP_INTERNAL_REDIRECT) {
@@ -843,4 +878,17 @@
public long uncompressedDataLength() {
return this.decompressedLength;
}
+
+ public FreenetURI getResolvedURI() {
+ return resolvedURI;
+ }
+
+ public void resolve(FreenetURI uri) {
+ this.resolvedURI = uri;
+ }
+
+ public Bucket toBucket(BucketFactory bf) throws
MetadataUnresolvedException, IOException {
+ byte[] buf = writeToByteArray();
+ return BucketTools.makeImmutableBucket(bf, buf);
+ }
}
Added: trunk/freenet/src/freenet/client/MetadataUnresolvedException.java
===================================================================
--- trunk/freenet/src/freenet/client/MetadataUnresolvedException.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/MetadataUnresolvedException.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -0,0 +1,12 @@
+package freenet.client;
+
+public class MetadataUnresolvedException extends Exception {
+
+ public final Metadata[] mustResolve;
+
+ MetadataUnresolvedException(Metadata[] mustResolve, String message) {
+ super(message);
+ this.mustResolve = mustResolve;
+ }
+
+}
Modified: trunk/freenet/src/freenet/client/async/ClientPutState.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientPutState.java 2006-05-18
15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/ClientPutState.java 2006-05-18
19:13:36 UTC (rev 8774)
@@ -14,4 +14,6 @@
public abstract void cancel();
public abstract void schedule() throws InserterException;
+
+ public Object getToken();
}
Modified: trunk/freenet/src/freenet/client/async/ClientPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientPutter.java 2006-05-18
15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/ClientPutter.java 2006-05-18
19:13:36 UTC (rev 8774)
@@ -54,7 +54,7 @@
public void start() throws InserterException {
try {
currentState =
- new SingleFileInserter(this, this, new
InsertBlock(data, cm, targetURI), isMetadata, ctx, false, getCHKOnly, false);
+ new SingleFileInserter(this, this, new
InsertBlock(data, cm, targetURI), isMetadata, ctx, false, getCHKOnly, false,
null);
((SingleFileInserter)currentState).start();
} catch (InserterException e) {
finished = true;
Modified: trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java
===================================================================
--- trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -21,12 +21,14 @@
private InserterException e;
private boolean finished;
private boolean started;
+ public final Object token;
- public MultiPutCompletionCallback(PutCompletionCallback cb,
BaseClientPutter parent) {
+ public MultiPutCompletionCallback(PutCompletionCallback cb,
BaseClientPutter parent, Object token) {
this.cb = cb;
this.waitingFor = new LinkedList();
this.waitingForBlockSet = new LinkedList();
this.parent = parent;
+ this.token = token;
finished = false;
}
@@ -144,4 +146,8 @@
// Do nothing
}
+ public Object getToken() {
+ return token;
+ }
+
}
Modified: trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -12,6 +12,7 @@
import freenet.client.InserterContext;
import freenet.client.InserterException;
import freenet.client.Metadata;
+import freenet.client.MetadataUnresolvedException;
import freenet.client.events.SplitfileProgressEvent;
import freenet.keys.BaseClientKey;
import freenet.keys.FreenetURI;
@@ -31,7 +32,7 @@
InsertBlock block =
new InsertBlock(data, cm,
FreenetURI.EMPTY_CHK_URI);
this.origSFI =
- new SingleFileInserter(this, this, block,
false, ctx, false, getCHKOnly, true);
+ new SingleFileInserter(this, this, block,
false, ctx, false, getCHKOnly, true, null);
currentState = origSFI;
metadata = null;
}
@@ -167,11 +168,12 @@
private final boolean getCHKOnly;
private boolean insertedAllFiles;
private boolean insertedManifest;
- private ClientPutState currentMetadataInserterState;
+ private final HashMap metadataPuttersByMetadata;
private final String defaultName;
private int numberOfFiles;
private long totalSize;
private boolean metadataBlockSetFinalized;
+ private Metadata baseMetadata;
private final static String[] defaultDefaultNames =
new String[] { "index.html", "index.htm", "default.html",
"default.htm" };
@@ -188,6 +190,7 @@
runningPutHandlers = new HashSet();
putHandlersWaitingForMetadata = new HashSet();
waitingForBlockSets = new HashSet();
+ metadataPuttersByMetadata = new HashMap();
makePutHandlers(manifestElements, putHandlersByName);
}
@@ -277,27 +280,71 @@
}
}
}
- Metadata meta =
+ baseMetadata =
Metadata.mkRedirectionManifestWithMetadata(namesToByteArrays);
- Bucket bucket;
- try {
- bucket = BucketTools.makeImmutableBucket(ctx.bf,
meta.writeToByteArray());
- } catch (IOException e) {
- fail(new
InserterException(InserterException.BUCKET_ERROR, e, null));
- return;
+ resolveAndStartBase();
+ }
+
+ private void resolveAndStartBase() {
+ Bucket bucket = null;
+ synchronized(this) {
+
if(this.metadataPuttersByMetadata.containsKey(baseMetadata)) return;
}
+ while(true) {
+ try {
+ bucket =
BucketTools.makeImmutableBucket(ctx.bf, baseMetadata.writeToByteArray());
+ break;
+ } catch (IOException e) {
+ fail(new
InserterException(InserterException.BUCKET_ERROR, e, null));
+ return;
+ } catch (MetadataUnresolvedException e) {
+ try {
+ resolve(e);
+ } catch (IOException e1) {
+ fail(new
InserterException(InserterException.BUCKET_ERROR, e, null));
+ return;
+ } catch (InserterException e2) {
+ fail(e2);
+ }
+ }
+ }
+ if(bucket == null) return;
InsertBlock block =
new InsertBlock(bucket, null, targetURI);
try {
SingleFileInserter metadataInserter =
- new SingleFileInserter(this, this, block, true,
ctx, false, getCHKOnly, false);
- this.currentMetadataInserterState = metadataInserter;
+ new SingleFileInserter(this, this, block, true,
ctx, false, getCHKOnly, false, baseMetadata);
+ Logger.minor(this, "Inserting main metadata:
"+metadataInserter);
+ this.metadataPuttersByMetadata.put(baseMetadata,
metadataInserter);
metadataInserter.start();
} catch (InserterException e) {
fail(e);
}
}
-
+
+ private void resolve(MetadataUnresolvedException e) throws
InserterException, IOException {
+ Metadata[] metas = e.mustResolve;
+ for(int i=0;i<metas.length;i++) {
+ Metadata m = metas[i];
+ synchronized(this) {
+ if(metadataPuttersByMetadata.containsKey(m))
continue;
+ }
+ try {
+ Bucket b = m.toBucket(ctx.bf);
+ InsertBlock ib = new InsertBlock(b, null,
FreenetURI.EMPTY_CHK_URI);
+ SingleFileInserter metadataInserter =
+ new SingleFileInserter(this, this, ib,
true, ctx, false, getCHKOnly, false, m);
+ Logger.minor(this, "Inserting subsidiary
metadata: "+metadataInserter+" for "+m);
+ synchronized(this) {
+ this.metadataPuttersByMetadata.put(m,
metadataInserter);
+ }
+ metadataInserter.start();
+ } catch (MetadataUnresolvedException e1) {
+ resolve(e1);
+ }
+ }
+ }
+
private void namesToByteArrays(HashMap putHandlersByName, HashMap
namesToByteArrays) {
Iterator i = putHandlersByName.keySet().iterator();
while(i.hasNext()) {
@@ -358,8 +405,13 @@
}
public void onSuccess(ClientPutState state) {
- Logger.minor(this, "Inserted manifest successfully on "+this);
synchronized(this) {
+ metadataPuttersByMetadata.remove(state.getToken());
+ if(!metadataPuttersByMetadata.isEmpty()) {
+ Logger.minor(this, "Still running metadata
putters: "+metadataPuttersByMetadata.size());
+ return;
+ }
+ Logger.minor(this, "Inserted manifest successfully on
"+this);
insertedManifest = true;
if(finished) {
Logger.minor(this, "Already finished");
@@ -375,27 +427,31 @@
}
public void onFailure(InserterException e, ClientPutState state) {
- // FIXME check state == currentMetadataInserterState ??
fail(e);
}
public void onEncode(BaseClientKey key, ClientPutState state) {
- this.finalURI = key.getURI();
- Logger.minor(this, "Got metadata key: "+finalURI);
- cb.onGeneratedURI(finalURI, this);
+ if(state.getToken() == baseMetadata) {
+ this.finalURI = key.getURI();
+ Logger.minor(this, "Got metadata key: "+finalURI);
+ cb.onGeneratedURI(finalURI, this);
+ } else {
+ // It's a sub-Metadata
+ Metadata m = (Metadata) state.getToken();
+ m.resolve(key.getURI());
+ Logger.minor(this, "Resolved "+m+" : "+key.getURI());
+ resolveAndStartBase();
+ }
}
public void onTransition(ClientPutState oldState, ClientPutState
newState) {
- if(oldState == currentMetadataInserterState)
- currentMetadataInserterState = newState;
- else
- Logger.error(this, "Current state =
"+currentMetadataInserterState+" called onTransition(old="+oldState+",
new="+newState+")",
- new Exception("debug"));
+ synchronized(this) {
+ Logger.minor(this, "Transition: "+oldState+" ->
"+newState);
+ }
}
public void onMetadata(Metadata m, ClientPutState state) {
- Logger.error(this, "Got metadata from "+state+" on "+this+"
(metadata inserter = "+currentMetadataInserterState);
- fail(new InserterException(InserterException.INTERNAL_ERROR));
+ // Ignore
}
public void notifyClients() {
Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -39,13 +39,15 @@
private ClientKey key;
private WeakReference refToClientKeyBlock;
final int token; // for e.g. splitfiles
+ private final Object tokenObject;
final boolean isMetadata;
final boolean getCHKOnly;
final int sourceLength;
private int consecutiveRNFs;
- public SingleBlockInserter(BaseClientPutter parent, Bucket data, short
compressionCodec, FreenetURI uri, InserterContext ctx, PutCompletionCallback
cb, boolean isMetadata, int sourceLength, int token, boolean getCHKOnly,
boolean addToParent, boolean dontSendEncoded) throws InserterException {
+ public SingleBlockInserter(BaseClientPutter parent, Bucket data, short
compressionCodec, FreenetURI uri, InserterContext ctx, PutCompletionCallback
cb, boolean isMetadata, int sourceLength, int token, boolean getCHKOnly,
boolean addToParent, boolean dontSendEncoded, Object tokenObject) throws
InserterException {
this.consecutiveRNFs = 0;
+ this.tokenObject = tokenObject;
this.token = token;
this.parent = parent;
this.dontSendEncoded = dontSendEncoded;
@@ -278,4 +280,8 @@
return parent;
}
+ public Object getToken() {
+ return tokenObject;
+ }
+
}
Modified: trunk/freenet/src/freenet/client/async/SingleFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileInserter.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/SingleFileInserter.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -7,6 +7,7 @@
import freenet.client.InserterContext;
import freenet.client.InserterException;
import freenet.client.Metadata;
+import freenet.client.MetadataUnresolvedException;
import freenet.client.events.FinishedCompressionEvent;
import freenet.client.events.StartedCompressionEvent;
import freenet.keys.BaseClientKey;
@@ -42,6 +43,7 @@
* update our parent to point to us as current put-stage. */
private boolean cancelled = false;
private boolean reportMetadataOnly;
+ public final Object token;
/**
* @param parent
@@ -56,8 +58,9 @@
*/
SingleFileInserter(BaseClientPutter parent, PutCompletionCallback cb,
InsertBlock block,
boolean metadata, InserterContext ctx, boolean
dontCompress,
- boolean getCHKOnly, boolean reportMetadataOnly) throws
InserterException {
+ boolean getCHKOnly, boolean reportMetadataOnly, Object
token) throws InserterException {
this.reportMetadataOnly = reportMetadataOnly;
+ this.token = token;
this.parent = parent;
this.block = block;
this.ctx = ctx;
@@ -150,6 +153,7 @@
if(parent == cb) {
ctx.eventProducer.produceEvent(new
FinishedCompressionEvent(bestCodec == null ? -1 :
bestCodec.codecNumberForMetadata(), origSize, data.size()));
+ Logger.minor(this, "Compressed "+origSize+" to
"+data.size()+" on "+this);
}
// Compressed data
@@ -174,7 +178,7 @@
if (data.size() < ClientCHKBlock.MAX_COMPRESSED_DATA_LENGTH) {
// Insert single block, then insert pointer to it
if(reportMetadataOnly) {
- SingleBlockInserter dataPutter = new
SingleBlockInserter(parent, data, codecNumber, FreenetURI.EMPTY_CHK_URI, ctx,
cb, metadata, (int)origSize, -1, getCHKOnly, true, true);
+ SingleBlockInserter dataPutter = new
SingleBlockInserter(parent, data, codecNumber, FreenetURI.EMPTY_CHK_URI, ctx,
cb, metadata, (int)origSize, -1, getCHKOnly, true, true, token);
Metadata meta = new
Metadata(Metadata.SIMPLE_REDIRECT, dataPutter.getURI(), block.clientMetadata);
cb.onMetadata(meta, this);
cb.onTransition(this, dataPutter);
@@ -182,14 +186,19 @@
cb.onBlockSetFinished(this);
} else {
MultiPutCompletionCallback mcb =
- new MultiPutCompletionCallback(cb,
parent);
- SingleBlockInserter dataPutter = new
SingleBlockInserter(parent, data, codecNumber, FreenetURI.EMPTY_CHK_URI, ctx,
mcb, metadata, (int)origSize, -1, getCHKOnly, true, false);
+ new MultiPutCompletionCallback(cb,
parent, token);
+ SingleBlockInserter dataPutter = new
SingleBlockInserter(parent, data, codecNumber, FreenetURI.EMPTY_CHK_URI, ctx,
mcb, metadata, (int)origSize, -1, getCHKOnly, true, false, token);
Metadata meta = new
Metadata(Metadata.SIMPLE_REDIRECT, dataPutter.getURI(), block.clientMetadata);
Bucket metadataBucket;
try {
metadataBucket =
BucketTools.makeImmutableBucket(ctx.bf, meta.writeToByteArray());
} catch (IOException e) {
+ Logger.error(this, "Caught "+e, e);
throw new
InserterException(InserterException.BUCKET_ERROR, e, null);
+ } catch (MetadataUnresolvedException e) {
+ // Impossible, we're not inserting a
manifest.
+ Logger.error(this, "Caught "+e, e);
+ throw new
InserterException(InserterException.INTERNAL_ERROR, "Got
MetadataUnresolvedException in SingleFileInserter: "+e.toString(), null);
}
ClientPutState metaPutter =
createInserter(parent, metadataBucket, (short) -1, block.desiredURI, ctx, mcb,
true, (int)origSize, -1, getCHKOnly, true);
mcb.addURIGenerator(metaPutter);
@@ -208,12 +217,12 @@
// insert it. Then when the splitinserter has finished, and the
// metadata insert has finished too, tell the master callback.
if(reportMetadataOnly) {
- SplitFileInserter sfi = new SplitFileInserter(parent,
cb, data, bestCodec, block.clientMetadata, ctx, getCHKOnly, metadata);
+ SplitFileInserter sfi = new SplitFileInserter(parent,
cb, data, bestCodec, block.clientMetadata, ctx, getCHKOnly, metadata, token);
cb.onTransition(this, sfi);
sfi.start();
} else {
SplitHandler sh = new SplitHandler();
- SplitFileInserter sfi = new SplitFileInserter(parent,
sh, data, bestCodec, block.clientMetadata, ctx, getCHKOnly, metadata);
+ SplitFileInserter sfi = new SplitFileInserter(parent,
sh, data, bestCodec, block.clientMetadata, ctx, getCHKOnly, metadata, token);
sh.sfi = sfi;
cb.onTransition(this, sh);
sfi.start();
@@ -227,13 +236,13 @@
if(uri.getKeyType().equals("USK")) {
try {
return new USKInserter(parent, data,
compressionCodec, uri, ctx, cb, isMetadata, sourceLength, token,
- getCHKOnly, addToParent);
+ getCHKOnly, addToParent, this.token);
} catch (MalformedURLException e) {
throw new
InserterException(InserterException.INVALID_URI, e, null);
}
} else {
return new SingleBlockInserter(parent, data,
compressionCodec, uri, ctx, cb, isMetadata, sourceLength, token,
- getCHKOnly, addToParent, false);
+ getCHKOnly, addToParent, false, this.token);
}
}
@@ -307,10 +316,16 @@
InserterException ex = new
InserterException(InserterException.BUCKET_ERROR, e, null);
fail(ex);
return;
+ } catch (MetadataUnresolvedException e)
{
+ Logger.error(this, "Impossible:
"+e, e);
+ InserterException ex = new
InserterException(InserterException.INTERNAL_ERROR,
"MetadataUnresolvedException in SingleFileInserter.SplitHandler: "+e, null);
+ ex.initCause(e);
+ fail(ex);
+ return;
}
InsertBlock newBlock = new
InsertBlock(metadataBucket, null, block.desiredURI);
try {
- metadataPutter = new
SingleFileInserter(parent, this, newBlock, true, ctx, false, getCHKOnly, false);
+ metadataPutter = new
SingleFileInserter(parent, this, newBlock, true, ctx, false, getCHKOnly, false,
token);
Logger.minor(this, "Putting
metadata on "+metadataPutter);
} catch (InserterException e) {
cb.onFailure(e, this);
@@ -368,6 +383,10 @@
public void schedule() throws InserterException {
// Do nothing
}
+
+ public Object getToken() {
+ return token;
+ }
}
@@ -382,4 +401,8 @@
public void schedule() throws InserterException {
start();
}
+
+ public Object getToken() {
+ return token;
+ }
}
Modified: trunk/freenet/src/freenet/client/async/SplitFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserter.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserter.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -34,9 +34,11 @@
final ClientMetadata cm;
final boolean isMetadata;
private boolean finished;
+ public final Object token;
- public SplitFileInserter(BaseClientPutter put, PutCompletionCallback
cb, Bucket data, Compressor bestCodec, ClientMetadata clientMetadata,
InserterContext ctx, boolean getCHKOnly, boolean isMetadata) throws
InserterException {
+ public SplitFileInserter(BaseClientPutter put, PutCompletionCallback
cb, Bucket data, Compressor bestCodec, ClientMetadata clientMetadata,
InserterContext ctx, boolean getCHKOnly, boolean isMetadata, Object token)
throws InserterException {
this.parent = put;
+ this.token = token;
this.finished = false;
this.isMetadata = isMetadata;
this.cm = clientMetadata;
@@ -272,4 +274,8 @@
start();
}
+ public Object getToken() {
+ return token;
+ }
+
}
Modified: trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
2006-05-18 15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
2006-05-18 19:13:36 UTC (rev 8774)
@@ -55,7 +55,7 @@
public void start() throws InserterException {
for(int i=0;i<dataBlockInserters.length;i++) {
dataBlockInserters[i] =
- new SingleBlockInserter(parent.parent,
dataBlocks[i], (short)-1, FreenetURI.EMPTY_CHK_URI, blockInsertContext, this,
false, ClientCHKBlock.DATA_LENGTH, i, getCHKOnly, false, false);
+ new SingleBlockInserter(parent.parent,
dataBlocks[i], (short)-1, FreenetURI.EMPTY_CHK_URI, blockInsertContext, this,
false, ClientCHKBlock.DATA_LENGTH, i, getCHKOnly, false, false, parent.token);
dataBlockInserters[i].schedule();
}
if(splitfileAlgo == null) {
@@ -81,7 +81,7 @@
// Start the inserts
for(int i=0;i<checkBlockInserters.length;i++) {
checkBlockInserters[i] =
- new SingleBlockInserter(parent.parent,
checkBlocks[i], (short)-1, FreenetURI.EMPTY_CHK_URI, blockInsertContext, this,
false, ClientCHKBlock.DATA_LENGTH, i + dataBlocks.length, getCHKOnly, false,
false);
+ new SingleBlockInserter(parent.parent,
checkBlocks[i], (short)-1, FreenetURI.EMPTY_CHK_URI, blockInsertContext, this,
false, ClientCHKBlock.DATA_LENGTH, i + dataBlocks.length, getCHKOnly, false,
false, parent.token);
checkBlockInserters[i].schedule();
}
// Tell parent only after have started the inserts.
Modified: trunk/freenet/src/freenet/client/async/USKInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKInserter.java 2006-05-18
15:30:32 UTC (rev 8773)
+++ trunk/freenet/src/freenet/client/async/USKInserter.java 2006-05-18
19:13:36 UTC (rev 8774)
@@ -32,6 +32,7 @@
final int sourceLength;
final int token;
final boolean getCHKOnly;
+ public final Object tokenObject;
final InsertableUSK privUSK;
final USK pubUSK;
@@ -108,7 +109,7 @@
Logger.minor(this, "scheduling insert for
"+pubUSK.getURI()+" "+edition);
try {
sbi = new SingleBlockInserter(parent, data,
compressionCodec, privUSK.getInsertableSSK(edition).getInsertURI(),
- ctx, this, isMetadata,
sourceLength, token, getCHKOnly, false, true /* we don't use it */);
+ ctx, this, isMetadata,
sourceLength, token, getCHKOnly, false, true /* we don't use it */,
tokenObject);
} catch (InserterException e) {
cb.onFailure(e, this);
return;
@@ -155,7 +156,8 @@
public USKInserter(BaseClientPutter parent, Bucket data, short
compressionCodec, FreenetURI uri,
InserterContext ctx, PutCompletionCallback cb, boolean
isMetadata, int sourceLength, int token,
- boolean getCHKOnly, boolean addToParent) throws
MalformedURLException {
+ boolean getCHKOnly, boolean addToParent, Object
tokenObject) throws MalformedURLException {
+ this.tokenObject = tokenObject;
this.parent = parent;
this.data = data;
this.compressionCodec = compressionCodec;
@@ -217,4 +219,8 @@
// Ignore
}
+ public Object getToken() {
+ return tokenObject;
+ }
+
}
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-05-18 15:30:32 UTC (rev
8773)
+++ trunk/freenet/src/freenet/node/Version.java 2006-05-18 19:13:36 UTC (rev
8774)
@@ -18,7 +18,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 722;
+ private static final int buildNumber = 723;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 698;
Modified: trunk/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPut.java 2006-05-18 15:30:32 UTC
(rev 8773)
+++ trunk/freenet/src/freenet/node/fcp/ClientPut.java 2006-05-18 19:13:36 UTC
(rev 8774)
@@ -6,6 +6,7 @@
import freenet.client.ClientMetadata;
import freenet.client.InserterException;
import freenet.client.Metadata;
+import freenet.client.MetadataUnresolvedException;
import freenet.client.async.ClientPutter;
import freenet.keys.FreenetURI;
import freenet.support.Bucket;
@@ -46,7 +47,18 @@
this.targetURI = message.redirectTarget;
Metadata m = new Metadata(Metadata.SIMPLE_REDIRECT,
targetURI, cm);
cm = null;
- byte[] d = m.writeToByteArray();
+ byte[] d;
+ try {
+ d = m.writeToByteArray();
+ } catch (MetadataUnresolvedException e) {
+ // Impossible
+ Logger.error(this, "Impossible: "+e, e);
+ onFailure(new
InserterException(InserterException.INTERNAL_ERROR, "Impossible: "+e+" in
ClientPut", null), null);
+ this.data = null;
+ clientMetadata = null;
+ inserter = null;
+ return;
+ }
data = new SimpleReadOnlyArrayBucket(d);
isMetadata = true;
} else
@@ -115,7 +127,19 @@
targetURI = new FreenetURI(target);
Metadata m = new Metadata(Metadata.SIMPLE_REDIRECT,
targetURI, cm);
cm = null;
- byte[] d = m.writeToByteArray();
+ byte[] d;
+ try {
+ d = m.writeToByteArray();
+ } catch (MetadataUnresolvedException e) {
+ // Impossible
+ Logger.error(this, "Impossible: "+e, e);
+ onFailure(new
InserterException(InserterException.INTERNAL_ERROR, "Impossible: "+e+" in
ClientPut", null), null);
+ this.data = null;
+ clientMetadata = null;
+ origFilename = null;
+ inserter = null;
+ return;
+ }
data = new SimpleReadOnlyArrayBucket(d);
origFilename = null;
isMetadata = true;