Author: toad
Date: 2006-01-14 20:24:24 +0000 (Sat, 14 Jan 2006)
New Revision: 7857
Added:
trunk/freenet/src/freenet/client/MultiFileInserter.java
Modified:
trunk/freenet/src/freenet/client/BlockInserter.java
trunk/freenet/src/freenet/client/FileInserter.java
trunk/freenet/src/freenet/client/HighLevelSimpleClient.java
trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
trunk/freenet/src/freenet/client/InserterException.java
trunk/freenet/src/freenet/client/Metadata.java
trunk/freenet/src/freenet/client/SplitInserter.java
trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/Version.java
Log:
353:
Revamp PUTDIR. It is now part of freenet/client/.
- Much faster (we insert 5 files at a time)
- More efficient (we aggregate the metadata)
- Will detect {index|default}.{htm|html} as default
- Can be exposed to FCP (not yet obviously), and later support containers etc
Also minor fproxy changes.
Modified: trunk/freenet/src/freenet/client/BlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/BlockInserter.java 2006-01-14 17:36:25 UTC
(rev 7856)
+++ trunk/freenet/src/freenet/client/BlockInserter.java 2006-01-14 20:24:24 UTC
(rev 7857)
@@ -73,8 +73,8 @@
FileInserter inserter = new FileInserter(ctx);
try {
if(uri == null && !getCHKOnly)
- uri = inserter.run(block, false, true, true);
- uri = inserter.run(block, false, getCHKOnly, true);
+ uri = inserter.run(block, false, true, true,
null);
+ uri = inserter.run(block, false, getCHKOnly, true,
null);
succeeded = true;
tracker.success(this);
} catch (InserterException e) {
Modified: trunk/freenet/src/freenet/client/FileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/FileInserter.java 2006-01-14 17:36:25 UTC
(rev 7856)
+++ trunk/freenet/src/freenet/client/FileInserter.java 2006-01-14 20:24:24 UTC
(rev 7857)
@@ -1,19 +1,17 @@
package freenet.client;
+import java.io.DataOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
-import freenet.client.events.BlockInsertErrorEvent;
import freenet.client.events.SimpleBlockPutEvent;
import freenet.keys.CHKBlock;
import freenet.keys.CHKEncodeException;
import freenet.keys.ClientCHKBlock;
-import freenet.keys.ClientSSK;
import freenet.keys.ClientSSKBlock;
import freenet.keys.FreenetURI;
import freenet.keys.InsertableClientSSK;
import freenet.keys.NodeCHK;
-import freenet.keys.NodeSSK;
import freenet.keys.SSKBlock;
import freenet.keys.SSKEncodeException;
import freenet.node.LowLevelPutException;
@@ -37,11 +35,15 @@
/**
* Do an insert.
* @param block The data to insert.
- * @param localOnly
+ * @param localOnly
+ * @param returnMetadata If not null, return the metadata in this
bucket, rather
+ * than inserting it; return the *data* CHK only. This is used by e.g.
+ * MultiFileInserter, where we will aggregate the metadata elsewhere.
+ * Only supported on CHKs.
* @return The URI of the inserted data.
* @throws InserterException
*/
- public FreenetURI run(InsertBlock block, boolean metadata, boolean
getCHKOnly, boolean noRetries) throws InserterException {
+ public FreenetURI run(InsertBlock block, boolean metadata, boolean
getCHKOnly, boolean noRetries, Bucket returnMetadata) throws InserterException {
if(block.data == null)
throw new NullPointerException();
if(block.desiredURI.getKeyType().equalsIgnoreCase("CHK")) {
@@ -149,7 +151,7 @@
if(isSSK) {
// Insert as CHK
// Create metadata pointing to it (include the
clientMetadata if there is any).
- FreenetURI uri = run(new InsertBlock(block.data, new
ClientMetadata(), FreenetURI.EMPTY_CHK_URI), metadata, getCHKOnly, noRetries);
+ FreenetURI uri = run(new InsertBlock(block.data, new
ClientMetadata(), FreenetURI.EMPTY_CHK_URI), metadata, getCHKOnly, noRetries,
null);
Metadata m = new Metadata(Metadata.SIMPLE_REDIRECT,
uri, block.clientMetadata);
Bucket bucket;
try {
@@ -157,7 +159,7 @@
} catch (IOException e) {
throw new
InserterException(InserterException.INTERNAL_ERROR, e, isk.getURI());
}
- return run(new InsertBlock(bucket, new
ClientMetadata(), block.desiredURI), metadata, getCHKOnly, noRetries);
+ return run(new InsertBlock(bucket, new
ClientMetadata(), block.desiredURI), metadata, getCHKOnly, noRetries, null);
}
if(data.size() <= NodeCHK.BLOCK_SIZE) {
@@ -175,11 +177,11 @@
Logger.error(this, "Unexpected error: "+e, e);
throw new
InserterException(InserterException.INTERNAL_ERROR, null);
}
- return simplePutCHK(chk, block.clientMetadata,
getCHKOnly, noRetries);
+ return simplePutCHK(chk, block.clientMetadata,
getCHKOnly, noRetries, returnMetadata);
}
// Too big, encode to a splitfile
- SplitInserter splitInsert = new SplitInserter(data,
block.clientMetadata, bestCodec, ctx.splitfileAlgorithm, ctx, this,
NodeCHK.BLOCK_SIZE, getCHKOnly, metadata);
+ SplitInserter splitInsert = new SplitInserter(data,
block.clientMetadata, bestCodec, ctx.splitfileAlgorithm, ctx, this,
NodeCHK.BLOCK_SIZE, getCHKOnly, metadata, returnMetadata);
return splitInsert.run();
}
@@ -188,10 +190,13 @@
* @param chk The data encoded into a single CHK.
* @param clientMetadata The client metadata. If this is non-trivial,
we will have to
* create a redirect document just to put the metadata in.
+ * @param returnMetadata If not null, return the metadata in this
bucket, rather
+ * than inserting it; return the *data* CHK only. This is used by e.g.
+ * MultiFileInserter, where we will aggregate the metadata elsewhere.
* @return The URI of the resulting CHK.
* @throws InserterException If there was an error inserting the block.
*/
- private FreenetURI simplePutCHK(ClientCHKBlock chk, ClientMetadata
clientMetadata, boolean getCHKOnly, boolean noRetries) throws InserterException
{
+ private FreenetURI simplePutCHK(ClientCHKBlock chk, ClientMetadata
clientMetadata, boolean getCHKOnly, boolean noRetries, Bucket returnMetadata)
throws InserterException {
LowLevelPutException le = null;
int rnfs = 0;
for(int i=0;i<=ctx.maxInsertRetries;i++) {
@@ -224,11 +229,22 @@
if(clientMetadata == null || clientMetadata.isTrivial())
// Don't need a redirect for the metadata
- uri = chk.getClientKey().getURI();
+ uri = chk.getClientKey().getURI();
else {
// Do need a redirect for the metadata
Metadata metadata = new
Metadata(Metadata.SIMPLE_REDIRECT, chk.getClientKey().getURI(), clientMetadata);
- uri = putMetadataCHK(metadata, getCHKOnly, noRetries);
+ if(returnMetadata != null) {
+ uri = chk.getClientKey().getURI();
+ try {
+ DataOutputStream dos = new
DataOutputStream(returnMetadata.getOutputStream());
+ metadata.writeTo(dos);
+ dos.close();
+ } catch (IOException e) {
+ throw new
InserterException(InserterException.BUCKET_ERROR);
+ }
+ } else {
+ uri = putMetadataCHK(metadata, getCHKOnly,
noRetries);
+ }
}
if(le != null)
@@ -306,6 +322,6 @@
throw new
InserterException(InserterException.BUCKET_ERROR, null);
}
InsertBlock block = new InsertBlock(bucket, null,
FreenetURI.EMPTY_CHK_URI);
- return run(block, true, getCHKOnly, noRetries);
+ return run(block, true, getCHKOnly, noRetries, null);
}
}
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClient.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClient.java 2006-01-14
17:36:25 UTC (rev 7856)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClient.java 2006-01-14
20:24:24 UTC (rev 7857)
@@ -38,7 +38,7 @@
/**
* Blocking insert of multiple files as a manifest (or zip manifest,
etc).
*/
- public FreenetURI insertManifest(FreenetURI insertURI, HashMap
bucketsByName) throws InserterException;
+ public FreenetURI insertManifest(FreenetURI insertURI, HashMap
bucketsByName, String defaultName) throws InserterException;
/**
* Add a ClientEventListener.
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-01-14 17:36:25 UTC (rev 7856)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-01-14 20:24:24 UTC (rev 7857)
@@ -109,14 +109,14 @@
InserterContext context = new InserterContext(client,
bucketFactory, random, INSERT_RETRIES, CONSECUTIVE_RNFS_ASSUME_SUCCESS,
SPLITFILE_INSERT_THREADS,
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT,
globalEventProducer, insertStarter, cacheLocalRequests);
FileInserter i = new FileInserter(context);
- return i.run(insert, false, getCHKOnly, false);
+ return i.run(insert, false, getCHKOnly, false, null);
}
public FreenetURI insert(InsertBlock insert, boolean getCHKOnly,
boolean metadata) throws InserterException {
InserterContext context = new InserterContext(client,
bucketFactory, random, INSERT_RETRIES, CONSECUTIVE_RNFS_ASSUME_SUCCESS,
SPLITFILE_INSERT_THREADS,
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT,
globalEventProducer, insertStarter, cacheLocalRequests);
FileInserter i = new FileInserter(context);
- return i.run(insert, metadata, getCHKOnly, false);
+ return i.run(insert, metadata, getCHKOnly, false, null);
}
public FreenetURI insertRedirect(FreenetURI insertURI, FreenetURI
targetURI) throws InserterException {
@@ -133,12 +133,14 @@
InserterContext context = new InserterContext(client,
bucketFactory, random, INSERT_RETRIES, CONSECUTIVE_RNFS_ASSUME_SUCCESS,
SPLITFILE_INSERT_THREADS,
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT,
globalEventProducer, insertStarter, cacheLocalRequests);
FileInserter i = new FileInserter(context);
- return i.run(block, true, false, false);
+ return i.run(block, true, false, false, null);
}
- public FreenetURI insertManifest(FreenetURI insertURI, HashMap
bucketsByName) throws InserterException {
- // FIXME
- throw new UnsupportedOperationException();
+ public FreenetURI insertManifest(FreenetURI insertURI, HashMap
bucketsByName, String defaultName) throws InserterException {
+ InserterContext context = new InserterContext(client,
bucketFactory, random, INSERT_RETRIES, CONSECUTIVE_RNFS_ASSUME_SUCCESS,
+ SPLITFILE_INSERT_THREADS,
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT,
globalEventProducer, insertStarter, cacheLocalRequests);
+ MultiFileInserter mfi = new MultiFileInserter(insertURI,
bucketsByName, context, defaultName);
+ return mfi.run();
}
public void addGlobalHook(ClientEventListener listener) {
Modified: trunk/freenet/src/freenet/client/InserterException.java
===================================================================
--- trunk/freenet/src/freenet/client/InserterException.java 2006-01-14
17:36:25 UTC (rev 7856)
+++ trunk/freenet/src/freenet/client/InserterException.java 2006-01-14
20:24:24 UTC (rev 7857)
@@ -51,6 +51,7 @@
}
public InserterException(int mode) {
+ super(getMessage(mode));
this.mode = mode;
this.errorCodes = null;
this.uri = null;
Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java 2006-01-14 17:36:25 UTC
(rev 7856)
+++ trunk/freenet/src/freenet/client/Metadata.java 2006-01-14 20:24:24 UTC
(rev 7857)
@@ -292,7 +292,35 @@
ret.addRedirectionManifest(dir);
return ret;
}
+
+ /**
+ * Create a Metadata object and add manifest entries from the given
array. */
+ public static Metadata mkRedirectionManifestWithMetadata(HashMap dir) {
+ Metadata ret = new Metadata();
+ ret.addRedirectionManifestWithMetadata(dir);
+ return ret;
+ }
+ private void addRedirectionManifestWithMetadata(HashMap dir) {
+ // Simple manifest - contains actual redirects.
+ // Not zip manifest, which is basically a redirect.
+ documentType = SIMPLE_MANIFEST;
+ noMIME = true;
+ //mimeType = null;
+ //clientMetadata = new ClientMetadata(null);
+ manifestEntries = new HashMap();
+ int count = 0;
+ for(Iterator i = dir.keySet().iterator();i.hasNext();) {
+ String key = (String) i.next();
+ count++;
+ byte[] data = (byte[]) dir.get(key);
+ if(data == null)
+ throw new NullPointerException();
+ manifestEntries.put(key, data);
+ }
+ manifestEntryCount = count;
+ }
+
/**
* Create a Metadata object for an archive which does not have its own
* metadata.
Added: trunk/freenet/src/freenet/client/MultiFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/MultiFileInserter.java 2006-01-14
17:36:25 UTC (rev 7856)
+++ trunk/freenet/src/freenet/client/MultiFileInserter.java 2006-01-14
20:24:24 UTC (rev 7857)
@@ -0,0 +1,191 @@
+package freenet.client;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import freenet.keys.FreenetURI;
+import freenet.support.ArrayBucket;
+import freenet.support.Bucket;
+import freenet.support.BucketTools;
+import freenet.support.Logger;
+
+public class MultiFileInserter {
+
+ public class MFInserter implements Runnable {
+
+ final int num;
+
+ MFInserter(int x) {
+ num = x;
+ }
+
+ public void run() {
+ try {
+ while(true) {
+ String name = null;
+ Bucket data = null;
+ synchronized(bucketsByName) {
+ if(bucketsByName.isEmpty()) break;
+ name = (String)
bucketsByName.keySet().iterator().next();
+ data = (Bucket)
bucketsByName.remove(name);
+ }
+ String mimeType =
DefaultMIMETypes.guessMIMEType(name);
+ Logger.minor(this, "Name: "+name+"\nBucket
size: "+data.size()+"\nGuessed MIME type: "+mimeType);
+ byte[] metaByteArray;
+ try {
+ metaByteArray = getMetadata(name, data,
mimeType);
+ } catch (InserterException e) {
+ Logger.normal(this, "Error inserting
"+name+": "+e.getMessage());
+ errorCodes.inc(e.getMode());
+ synchronized(this) {
+ errors++;
+ }
+ continue;
+ } catch (Throwable t) {
+ Logger.error(this, "Caught "+t);
+
errorCodes.inc(InserterException.INTERNAL_ERROR);
+ synchronized(this) {
+ errors++;
+ }
+ continue;
+ }
+ if(metaByteArray != null) {
+ synchronized(namesToMetadataByteArrays)
{
+
namesToMetadataByteArrays.put(name, metaByteArray);
+ }
+ Logger.minor(this, "Inserted "+name);
+ } else {
+ Logger.normal(this, "Insert failed:
"+name);
+ }
+
+ }
+ } finally {
+ synchronized(MultiFileInserter.this) {
+ finished[num] = true;
+ MultiFileInserter.this.notifyAll();
+ }
+ }
+ }
+
+ }
+
+ final FreenetURI targetURI;
+ final HashMap bucketsByName;
+ final InserterContext ctx;
+ final String defaultName;
+ final HashMap namesToMetadataByteArrays;
+ final FailureCodeTracker errorCodes;
+ private int errors;
+ private final boolean[] finished;
+
+ public MultiFileInserter(FreenetURI insertURI, HashMap bucketsByName,
InserterContext context, String defaultName) {
+ this.targetURI = insertURI;
+ this.bucketsByName = bucketsByName;
+ this.ctx = context;
+ this.defaultName = defaultName;
+ this.namesToMetadataByteArrays = new HashMap();
+ this.errorCodes = new FailureCodeTracker(true);
+ if(bucketsByName.get(defaultName) == null)
+ // FIXME make this an InserterException.
+ throw new IllegalArgumentException();
+ finished = new boolean[5];
+ }
+
+ public FreenetURI run() throws InserterException {
+ // For each file, guess MIME type, insert it, get the metadata.
+ // Then put all the metadata at once into one manifest.
+ // Then return it.
+
+ // FIXME scaling issues; have to keep everything in RAM...
+
+ for(int j=0;j<finished.length;j++) {
+ MFInserter it = new MFInserter(j);
+ Thread t = new Thread(it, "Inserter #"+j);
+ t.setDaemon(true);
+ t.start();
+ }
+
+ synchronized(this) {
+ while(true) {
+ boolean stillRunning = false;
+ for(int i=0;i<finished.length;i++) {
+ if(!finished[i]) stillRunning = true;
+ }
+ if(!stillRunning) break;
+ try {
+ wait(10000);
+ } catch (InterruptedException e) {
+ // Impossible??
+ }
+ }
+ }
+
+ if(defaultName != null) {
+ synchronized(namesToMetadataByteArrays) {
+ byte[] defaultData = (byte[])
namesToMetadataByteArrays.get(defaultName);
+ if(defaultData != null)
+ namesToMetadataByteArrays.put("",
defaultData);
+ else {
+ Logger.error(this, "Default name
"+defaultName+" does not exist");
+
if(namesToMetadataByteArrays.containsKey(defaultName))
+ Logger.error(this, "Default
name exists but has null bytes!");
+ // It existed ... and now it doesn't?!
+ throw new
InserterException(InserterException.INTERNAL_ERROR);
+ }
+ }
+ }
+
+ Metadata manifestMetadata =
Metadata.mkRedirectionManifestWithMetadata(namesToMetadataByteArrays);
+
+ Bucket metadata = new
ArrayBucket(manifestMetadata.writeToByteArray());
+
+ FileInserter fi = new FileInserter(ctx);
+
+ InsertBlock block = new InsertBlock(metadata, null, targetURI);
+
+ FreenetURI uri = fi.run(block, true, false, false, null);
+
+ if(errors > 0) {
+ throw new
InserterException(InserterException.FATAL_ERRORS_IN_BLOCKS, errorCodes, uri);
+ }
+
+ return uri;
+ }
+
+ private byte[] getMetadata(String name, Bucket data, String mimeType)
throws InserterException {
+ FileInserter fi = new FileInserter(ctx);
+ InsertBlock block = new InsertBlock(data, new
ClientMetadata(mimeType), FreenetURI.EMPTY_CHK_URI);
+ ArrayBucket metaBucket = new ArrayBucket();
+ FreenetURI uri;
+ // FIXME make a client event and switch this to logger.log(...)
+ System.out.println("Inserting "+name+" ("+data.size()+" bytes,
"+mimeType+")");
+ try {
+ uri = fi.run(block, false, false, false, metaBucket);
+ } catch (InserterException e1) {
+ if(e1.uri != null && e1.getMode() ==
InserterException.COLLISION || e1.getMode() ==
InserterException.ROUTE_NOT_FOUND || e1.getMode() ==
InserterException.ROUTE_REALLY_NOT_FOUND) {
+ Logger.minor(this, "Ignoring "+e1);
+ uri = e1.uri;
+ } else {
+ // Clear the uri.
+ throw new InserterException(e1.getMode());
+ }
+ }
+ byte[] metaByteArray;
+ if(metaBucket.size() == 0) {
+ // It didn't give us any metadata
+ Logger.minor(this, "Did not return metadata: creating
our own");
+ Metadata m = new Metadata(Metadata.SIMPLE_REDIRECT,
uri, null);
+ metaByteArray = m.writeToByteArray();
+ if(metaByteArray == null) throw new
NullPointerException();
+ } else {
+ try {
+ metaByteArray =
BucketTools.toByteArray(metaBucket);
+ if(metaByteArray == null) throw new
NullPointerException();
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ }
+ return metaByteArray;
+ }
+
+}
Modified: trunk/freenet/src/freenet/client/SplitInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/SplitInserter.java 2006-01-14 17:36:25 UTC
(rev 7856)
+++ trunk/freenet/src/freenet/client/SplitInserter.java 2006-01-14 20:24:24 UTC
(rev 7857)
@@ -1,5 +1,6 @@
package freenet.client;
+import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;
@@ -28,6 +29,7 @@
final int checkSegmentSize;
final int blockSize;
final boolean isMetadata;
+ final Bucket returnMetadata;
SplitfileBlock[] origDataBlocks;
InsertSegment encodingSegment;
InsertSegment[] segments;
@@ -40,7 +42,11 @@
private SplitfileBlock[] fatalErrorBlocks;
private FileInserter inserter;
- public SplitInserter(Bucket data, ClientMetadata clientMetadata,
Compressor compressor, short splitfileAlgorithm, InserterContext ctx,
FileInserter inserter, int blockLength, boolean getCHKOnly, boolean isMetadata)
throws InserterException {
+ /**
+ * @param returnMetadata If not null, then write the metadata to this
bucket,
+ * rather than inserting it.
+ */
+ public SplitInserter(Bucket data, ClientMetadata clientMetadata,
Compressor compressor, short splitfileAlgorithm, InserterContext ctx,
FileInserter inserter, int blockLength, boolean getCHKOnly, boolean isMetadata,
Bucket returnMetadata) throws InserterException {
this.origData = data;
this.getCHKOnly = getCHKOnly;
this.blockSize = blockLength;
@@ -62,6 +68,7 @@
}
this.inserter = inserter;
this.isMetadata = isMetadata;
+ this.returnMetadata = returnMetadata;
}
/**
@@ -122,31 +129,45 @@
Metadata metadata = new Metadata(splitfileAlgorithm,
dataURIs, checkURIs, segmentSize, checkSegmentSize, clientMetadata, dataLength,
compressionCodec, isMetadata);
- Bucket mbucket;
- try {
- mbucket =
BucketTools.makeImmutableBucket(ctx.bf, metadata.writeToByteArray());
- } catch (IOException e) {
- throw new
InserterException(InserterException.BUCKET_ERROR, null);
- }
+ if(returnMetadata != null) {
+ DataOutputStream dos;
+ try {
+ dos = new
DataOutputStream(returnMetadata.getOutputStream());
+ metadata.writeTo(dos);
+ dos.close();
+ } catch (IOException e) {
+ throw new
InserterException(InserterException.BUCKET_ERROR);
+ }
+ } else {
- if(inserter == null)
- inserter = new FileInserter(ctx);
-
- InsertBlock mblock = new InsertBlock(mbucket, null,
FreenetURI.EMPTY_CHK_URI);
-
- // FIXME probably should uncomment below so it doesn't
get inserted at all?
- // FIXME this is a hack for small network support...
but we will need that IRL... hmmm
- try {
- uri = inserter.run(mblock, true, getCHKOnly/*
|| (fatalErrors > 0 || failed > 0)*/, false);
- } catch (InserterException e) {
- e.errorCodes =
tracker.getAccumulatedNonFatalErrorCodes().merge(tracker.getAccumulatedFatalErrorCodes());
- throw e;
+ Bucket mbucket;
+ try {
+ mbucket =
BucketTools.makeImmutableBucket(ctx.bf, metadata.writeToByteArray());
+ } catch (IOException e) {
+ throw new
InserterException(InserterException.BUCKET_ERROR, null);
+ }
+
+ if(inserter == null)
+ inserter = new FileInserter(ctx);
+
+ InsertBlock mblock = new InsertBlock(mbucket,
null, FreenetURI.EMPTY_CHK_URI);
+
+ // FIXME probably should uncomment below so it
doesn't get inserted at all?
+ // FIXME this is a hack for small network
support... but we will need that IRL... hmmm
+ try {
+ uri = inserter.run(mblock, true,
getCHKOnly/* || (fatalErrors > 0 || failed > 0)*/, false, null);
+ } catch (InserterException e) {
+ e.errorCodes =
tracker.getAccumulatedNonFatalErrorCodes().merge(tracker.getAccumulatedFatalErrorCodes());
+ throw e;
+ }
}
+
}
// Did we succeed?
- ctx.eventProducer.produceEvent(new GeneratedURIEvent(uri));
+ if(uri != null)
+ ctx.eventProducer.produceEvent(new
GeneratedURIEvent(uri));
if(fatalErrors > 0) {
throw new
InserterException(InserterException.FATAL_ERRORS_IN_BLOCKS,
tracker.getAccumulatedFatalErrorCodes(), uri);
Modified: trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2006-01-14 17:36:25 UTC (rev 7856)
+++ trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2006-01-14 20:24:24 UTC (rev 7857)
@@ -12,6 +12,8 @@
import freenet.support.BucketTools;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.URLDecoder;
+import freenet.support.URLEncodedFormatException;
import freenet.support.io.LineReadingInputStream;
import freenet.support.io.TooLongException;
@@ -131,10 +133,13 @@
URI uri;
try {
- uri = new URI(split[1]);
+ uri = new
URI(URLDecoder.decode(split[1]));
} catch (URISyntaxException e) {
sendURIParseError(sock.getOutputStream(), true);
return;
+ } catch (URLEncodedFormatException e) {
+
sendURIParseError(sock.getOutputStream(), true);
+ return;
}
String method = split[0];
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-01-14
17:36:25 UTC (rev 7856)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-01-14
20:24:24 UTC (rev 7857)
@@ -284,61 +284,41 @@
line = line.split("#")[0];
}
- // Get files as name and keys
- HashMap manifestBase = dirPut(line, getCHKOnly);
+ HashMap bucketsByName =
+ makeBucketsByName(line);
- // Set defaultfile
- if (defaultFile != null) {
- HashMap currPos = manifestBase;
- String splitpath[] = defaultFile.split("/");
- int i = 0;
- for( ; i < (splitpath.length - 1) ; i++)
- currPos = (HashMap)currPos.get(splitpath[i]);
-
- if (currPos.get(splitpath[i]) != null) {
- // Add key as default
- manifestBase.put("", currPos.get(splitpath[i]));
- System.out.println("Using default key: " +
currPos.get(splitpath[i]));
- }else{
- System.err.println("Default key not found. No
default document.");
+ if(defaultFile == null) {
+ String[] defaultFiles =
+ new String[] { "index.html", "index.htm",
"default.html", "default.htm" };
+ for(int i=0;i<defaultFiles.length;i++) {
+ if(bucketsByName.containsKey(defaultFiles[i])) {
+ defaultFile = defaultFiles[i];
+ break;
+ }
}
- //getchkdir:/home/cyberdo/fort/new#filelist
}
- // Create metadata
- Metadata med = Metadata.mkRedirectionManifest(manifestBase);
- ClientMetadata md = med.getClientMetadata();
-
- // Extract binary data from metadata
- ArrayBucket metabucket = new ArrayBucket();
- DataOutputStream mdos = new DataOutputStream(
metabucket.getOutputStream() );
- med.writeTo(mdos);
- mdos.close();
-
- // Insert metadata
- InsertBlock block = new InsertBlock(metabucket, md,
FreenetURI.EMPTY_CHK_URI);
-
- FreenetURI uri;
- try {
- uri = ((HighLevelSimpleClientImpl)client).insert(block,
getCHKOnly, true);
- } catch (InserterException e) {
- System.out.println("Error: "+e.getMessage());
- if(e.uri != null)
+ FreenetURI uri;
+ try {
+ uri =
client.insertManifest(FreenetURI.EMPTY_CHK_URI, bucketsByName, defaultFile);
+ uri.addMetaStrings(new String[] { "" });
+
System.out.println("=======================================================");
+ System.out.println("URI: "+uri);
+
System.out.println("=======================================================");
+ } catch (InserterException e) {
+ System.out.println("Finished insert but: "+e.getMessage());
+ if(e.uri != null) {
+ uri = e.uri;
+ uri.addMetaStrings(new String[] { "" });
System.out.println("URI would have been: "+e.uri);
- int mode = e.getMode();
- if(mode == InserterException.FATAL_ERRORS_IN_BLOCKS || mode ==
InserterException.TOO_MANY_RETRIES_IN_BLOCKS) {
- System.out.println("Splitfile-specific
error:\n"+e.errorCodes.toVerboseString());
}
- return;
- }
+ if(e.errorCodes != null) {
+ System.out.println("Splitfile errors breakdown:");
+ System.out.println(e.errorCodes.toVerboseString());
+ }
+ Logger.error(this, "Caught "+e, e);
+ }
- String filelist = dirPutToList(manifestBase, "");
-
System.out.println("=======================================================");
- System.out.println(filelist);
-
System.out.println("=======================================================");
- System.out.println("URI: "+uri);
-
System.out.println("=======================================================");
-
} else if(uline.startsWith("PUTFILE:") || (getCHKOnly =
uline.startsWith("GETCHKFILE:"))) {
// Just insert to local store
if(getCHKOnly) {
@@ -481,8 +461,42 @@
}
}
-
- private String dirPutToList(HashMap dir, String basedir) {
+ /**
+ * Create a map of String -> Bucket for every file in a directory
+ * and its subdirs.
+ */
+ private HashMap makeBucketsByName(String directory) {
+
+ if (!directory.endsWith("/"))
+ directory = directory + "/";
+ File thisdir = new File(directory);
+
+ System.out.println("Listing dir: "+thisdir);
+
+ HashMap ret = new HashMap();
+
+ File filelist[] = thisdir.listFiles();
+ for(int i = 0 ; i < filelist.length ; i++) {
+ if (filelist[i].isFile() && filelist[i].canRead()) {
+ File f = filelist[i];
+
+ FileBucket bucket = new FileBucket(f, true, false,
false);
+
+ ret.put(f.getName(), bucket);
+ } else if(filelist[i].isDirectory()) {
+ HashMap subdir = makeBucketsByName(directory +
filelist[i].getName());
+ Iterator it = subdir.keySet().iterator();
+ while(it.hasNext()) {
+ String key = (String) it.next();
+ Bucket bucket = (Bucket) subdir.get(key);
+ ret.put(filelist[i].getName() + "/" + key,
bucket);
+ }
+ }
+ }
+ return ret;
+ }
+
+ private String dirPutToList(HashMap dir, String basedir) {
String ret = "";
for(Iterator i = dir.keySet().iterator();i.hasNext();) {
String key = (String) i.next();
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-01-14 17:36:25 UTC (rev
7856)
+++ trunk/freenet/src/freenet/node/Version.java 2006-01-14 20:24:24 UTC (rev
7857)
@@ -20,7 +20,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- public static final int buildNumber = 352;
+ public static final int buildNumber = 353;
/** Oldest build of Fred we will talk to */
public static final int lastGoodBuild = 348;