Author: toad
Date: 2007-05-23 23:08:25 +0000 (Wed, 23 May 2007)
New Revision: 13348
Modified:
trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
trunk/freenet/src/freenet/client/async/ClientGetter.java
trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
trunk/freenet/src/freenet/clients/http/NinjaSpider.java
trunk/freenet/src/freenet/clients/http/Spider.java
trunk/freenet/src/freenet/keys/CHKBlock.java
trunk/freenet/src/freenet/keys/KeyBlock.java
trunk/freenet/src/freenet/keys/SSKBlock.java
trunk/freenet/src/freenet/node/fcp/ClientGet.java
trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java
trunk/freenet/src/freenet/node/updater/NodeUpdater.java
trunk/freenet/src/freenet/node/updater/RevocationChecker.java
Log:
Binary blobs part 1: The ability to download a freesite as a binary blob file
(a series of raw keys packed into a file which can be reinserted with part 2).
This will allow for migration of your favourite content between disconnected
networks, and for update over mandatory.
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2007-05-23 22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2007-05-23 23:08:25 UTC (rev 13348)
@@ -111,7 +111,7 @@
if(uri == null) throw new NullPointerException();
FetchContext context = getFetchContext();
FetchWaiter fw = new FetchWaiter();
- ClientGetter get = new ClientGetter(fw,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, context, priorityClass, this, null);
+ ClientGetter get = new ClientGetter(fw,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, context, priorityClass, this, null, null);
get.start();
return fw.waitForCompletion();
}
@@ -124,7 +124,7 @@
if(uri == null) throw new NullPointerException();
FetchWaiter fw = new FetchWaiter();
FetchContext context = getFetchContext(overrideMaxSize);
- ClientGetter get = new ClientGetter(fw,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, context, priorityClass, clientContext, null);
+ ClientGetter get = new ClientGetter(fw,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, context, priorityClass, clientContext, null, null);
get.start();
return fw.waitForCompletion();
}
Modified: trunk/freenet/src/freenet/client/async/ClientGetter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientGetter.java 2007-05-23
22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/client/async/ClientGetter.java 2007-05-23
23:08:25 UTC (rev 13348)
@@ -3,8 +3,10 @@
* http://www.gnu.org/ for further details of the GPL. */
package freenet.client.async;
+import java.io.DataOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.util.HashSet;
import freenet.client.ArchiveContext;
import freenet.client.ClientMetadata;
@@ -13,6 +15,8 @@
import freenet.client.FetchContext;
import freenet.client.events.SplitfileProgressEvent;
import freenet.keys.FreenetURI;
+import freenet.keys.Key;
+import freenet.keys.KeyBlock;
import freenet.support.Logger;
import freenet.support.api.Bucket;
import freenet.support.io.BucketTools;
@@ -31,6 +35,11 @@
private int archiveRestarts;
/** If not null, Bucket to return the data in */
final Bucket returnBucket;
+ /** If not null, Bucket to return a binary blob in */
+ final Bucket binaryBlobBucket;
+ /** If not null, HashSet to track keys already added for a binary blob
*/
+ final HashSet binaryBlobKeysAddedAlready;
+ private DataOutputStream binaryBlobStream;
/**
* Fetch a key.
@@ -45,7 +54,7 @@
* former, obviously!
*/
public ClientGetter(ClientCallback client, ClientRequestScheduler
chkSched, ClientRequestScheduler sskSched,
- FreenetURI uri, FetchContext ctx, short
priorityClass, Object clientContext, Bucket returnBucket) {
+ FreenetURI uri, FetchContext ctx, short
priorityClass, Object clientContext, Bucket returnBucket, Bucket
binaryBlobBucket) {
super(priorityClass, chkSched, sskSched, clientContext);
this.client = client;
this.returnBucket = returnBucket;
@@ -53,6 +62,11 @@
this.ctx = ctx;
this.finished = false;
this.actx = new ArchiveContext(ctx.maxArchiveLevels);
+ this.binaryBlobBucket = binaryBlobBucket;
+ if(binaryBlobBucket != null) {
+ binaryBlobKeysAddedAlready = new HashSet();
+ } else
+ binaryBlobKeysAddedAlready = null;
archiveRestarts = 0;
}
@@ -80,8 +94,17 @@
returnBucket, true);
}
if(cancelled) cancel();
- if(currentState != null && !finished)
+ if(currentState != null && !finished) {
+ if(binaryBlobBucket != null) {
+ try {
+ writeBinaryBlobHeader();
+ } catch (IOException e) {
+ onFailure(new
FetchException(FetchException.BUCKET_ERROR, "Failed to open binary blob
bucket"), null);
+ return false;
+ }
+ }
currentState.schedule();
+ }
if(cancelled) cancel();
} catch (MalformedURLException e) {
throw new FetchException(FetchException.INVALID_URI, e);
@@ -90,6 +113,7 @@
}
public void onSuccess(FetchResult result, ClientGetState state) {
+ if(!closeBinaryBlobStream()) return;
synchronized(this) {
finished = true;
currentState = null;
@@ -120,6 +144,7 @@
}
public void onFailure(FetchException e, ClientGetState state) {
+ closeBinaryBlobStream();
while(true) {
if(e.mode == FetchException.ARCHIVE_RESTART) {
int ar;
@@ -213,4 +238,84 @@
public String toString() {
return super.toString()+ ':' +uri;
}
-}
+
+ public static final long BINARY_BLOB_MAGIC = 0x6d58249f72d67ed9L;
+ public static final short BINARY_BLOB_OVERALL_VERSION = 0;
+
+ private void writeBinaryBlobHeader() throws IOException {
+ binaryBlobStream = new
DataOutputStream(binaryBlobBucket.getOutputStream());
+ binaryBlobStream.writeLong(BINARY_BLOB_MAGIC);
+ binaryBlobStream.writeShort(BINARY_BLOB_OVERALL_VERSION);
+ }
+
+ static final short BLOB_BLOCK = 1;
+ static final short BLOB_BLOCK_VERSION = 0;
+
+ static final short BLOB_END = 2;
+ static final short BLOB_END_VERSION = 0;
+
+ void addKeyToBinaryBlob(KeyBlock block) {
+ if(binaryBlobKeysAddedAlready == null) return;
+ Key key = block.getKey();
+ synchronized(binaryBlobKeysAddedAlready) {
+ if(binaryBlobStream == null) return;
+ if(binaryBlobKeysAddedAlready.contains(key)) return;
+ binaryBlobKeysAddedAlready.add(key);
+ byte[] keyData = key.getRoutingKey();
+ byte[] headers = block.getRawHeaders();
+ byte[] data = block.getRawData();
+ byte[] pubkey = block.getPubkeyBytes();
+ try {
+ writeBlobHeader(BLOB_BLOCK, BLOB_BLOCK_VERSION,
7+keyData.length+headers.length+data.length);
+
binaryBlobStream.writeShort(block.getKey().getType());
+ binaryBlobStream.writeByte(keyData.length);
+ binaryBlobStream.writeShort(headers.length);
+ binaryBlobStream.writeShort(data.length);
+ binaryBlobStream.writeShort(pubkey == null ? 0
: pubkey.length);
+ binaryBlobStream.write(keyData);
+ binaryBlobStream.write(headers);
+ binaryBlobStream.write(data);
+ if(pubkey != null)
+ binaryBlobStream.write(pubkey);
+ } catch (IOException e) {
+ Logger.error(this, "Failed to write key to
binary blob stream: "+e, e);
+ onFailure(new
FetchException(FetchException.BUCKET_ERROR, "Failed to write key to binary blob
stream: "+e), null);
+ binaryBlobStream = null;
+ binaryBlobKeysAddedAlready.clear();
+ }
+ }
+ }
+
+ /**
+ * Close the binary blob stream.
+ * @return True unless a failure occurred, in which case we will have
already
+ * called onFailure() with an appropriate error.
+ */
+ private boolean closeBinaryBlobStream() {
+ if(binaryBlobBucket == null) return true;
+ synchronized(binaryBlobKeysAddedAlready) {
+ try {
+ writeBlobHeader(BLOB_END, BLOB_END_VERSION, 0);
+ binaryBlobStream.close();
+ return true;
+ } catch (IOException e) {
+ Logger.error(this, "Failed to close binary blob
stream: "+e, e);
+ onFailure(new
FetchException(FetchException.BUCKET_ERROR, "Failed to close binary blob
stream: "+e), null);
+ return false;
+ } finally {
+ binaryBlobStream = null;
+ binaryBlobKeysAddedAlready.clear();
+ }
+ }
+ }
+
+ private void writeBlobHeader(short type, short version, int length)
throws IOException {
+ binaryBlobStream.writeInt(length);
+ binaryBlobStream.writeShort(type);
+ binaryBlobStream.writeShort(version);
+ }
+
+ boolean collectingBinaryBlob() {
+ return binaryBlobBucket != null;
+ }
+}
\ No newline at end of file
Modified: trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
2007-05-23 22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/client/async/SimpleSingleFileFetcher.java
2007-05-23 23:08:25 UTC (rev 13348)
@@ -113,6 +113,8 @@
}
public void onSuccess(ClientKeyBlock block, boolean fromStore, int
reqTokenIgnored) {
+ if(parent instanceof ClientGetter)
+ ((ClientGetter)parent).addKeyToBinaryBlob(block);
Bucket data = extract(block);
if(data == null) return; // failed
if(!block.isMetadata()) {
Modified: trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2007-05-23 22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2007-05-23 23:08:25 UTC (rev 13348)
@@ -116,6 +116,8 @@
// Process the completed data. May result in us going to a
// splitfile, or another SingleFileFetcher, etc.
public void onSuccess(ClientKeyBlock block, boolean fromStore, int
token) {
+ if(parent instanceof ClientGetter)
+ ((ClientGetter)parent).addKeyToBinaryBlob(block);
parent.completedBlock(fromStore);
// Extract data
Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
2007-05-23 22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
2007-05-23 23:08:25 UTC (rev 13348)
@@ -18,7 +18,10 @@
import freenet.client.SplitfileBlock;
import freenet.client.FECCodec.StandardOnionFECCodecEncoderCallback;
import freenet.keys.CHKBlock;
+import freenet.keys.CHKEncodeException;
import freenet.keys.ClientCHK;
+import freenet.keys.ClientCHKBlock;
+import freenet.keys.ClientKeyBlock;
import freenet.support.Logger;
import freenet.support.api.Bucket;
import freenet.support.io.BucketTools;
@@ -140,9 +143,11 @@
return fatallyFailedBlocks;
}
- public void onSuccess(Bucket data, int blockNo, boolean dontNotify,
SplitFileFetcherSubSegment seg) {
+ public void onSuccess(Bucket data, int blockNo, boolean dontNotify,
SplitFileFetcherSubSegment seg, ClientKeyBlock block) {
boolean decodeNow = false;
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ if(parentFetcher.parent instanceof ClientGetter)
+
((ClientGetter)parentFetcher.parent).addKeyToBinaryBlob(block);
synchronized(this) {
if(isFinished()) return;
if(blockNo < dataKeys.length) {
@@ -237,14 +242,16 @@
}
}
- public void onEncodedSegment() {
+ public void onEncodedSegment() {
// Now insert *ALL* blocks on which we had at least one
failure, and didn't eventually succeed
for(int i=0;i<dataBuckets.length;i++) {
boolean heal = false;
+ Bucket data = dataBuckets[i].getData();
+ maybeAddToBinaryBlob(data, i, false);
if(dataRetries[i] > 0)
heal = true;
if(heal) {
- queueHeal(dataBuckets[i].getData());
+ queueHeal(data);
} else {
dataBuckets[i].data.free();
dataBuckets[i].data = null;
@@ -254,6 +261,8 @@
}
for(int i=0;i<checkBuckets.length;i++) {
boolean heal = false;
+ Bucket data = dataBuckets[i].getData();
+ maybeAddToBinaryBlob(data, i, true);
if(checkRetries[i] > 0)
heal = true;
if(heal) {
@@ -266,6 +275,26 @@
}
}
+ private void maybeAddToBinaryBlob(Bucket data, int i, boolean check) {
+ if(parentFetcher.parent instanceof ClientGetter) {
+ ClientGetter getter = (ClientGetter)
(parentFetcher.parent);
+ if(getter.collectingBinaryBlob()) {
+ try {
+ ClientCHKBlock block =
+ ClientCHKBlock.encode(data,
false, true, (short)-1, data.size());
+ getter.addKeyToBinaryBlob(block);
+ } catch (CHKEncodeException e) {
+ Logger.error(this, "Failed to encode
(collecting binary blob) "+(check?"check":"data")+" block "+i+": "+e, e);
+ fail(new
FetchException(FetchException.INTERNAL_ERROR, "Failed to encode for binary
blob: "+e));
+ return;
+ } catch (IOException e) {
+ fail(new
FetchException(FetchException.BUCKET_ERROR, "Failed to encode for binary blob:
"+e));
+ return;
+ }
+ }
+ }
+ }
+
private void queueHeal(Bucket data) {
if(logMINOR) Logger.minor(this, "Queueing healing insert");
fetchContext.healingQueue.queue(data);
Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
2007-05-23 22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
2007-05-23 23:08:25 UTC (rev 13348)
@@ -158,19 +158,19 @@
}
}
if(!block.isMetadata()) {
- onSuccess(data, fromStore, token);
+ onSuccess(data, fromStore, token, block);
} else {
onFailure(new
FetchException(FetchException.INVALID_METADATA, "Metadata where expected
data"), token);
}
}
- protected void onSuccess(Bucket data, boolean fromStore, int blockNo) {
+ protected void onSuccess(Bucket data, boolean fromStore, int blockNo,
ClientKeyBlock block) {
if(parent.isCancelled()) {
data.free();
onFailure(new FetchException(FetchException.CANCELLED),
blockNo);
return;
}
- segment.onSuccess(data, blockNo, fromStore, this);
+ segment.onSuccess(data, blockNo, fromStore, this, block);
}
/** Convert a ClientKeyBlock to a Bucket. If an error occurs, report it
via onFailure
Modified: trunk/freenet/src/freenet/clients/http/NinjaSpider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/NinjaSpider.java 2007-05-23
22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/clients/http/NinjaSpider.java 2007-05-23
23:08:25 UTC (rev 13348)
@@ -174,7 +174,7 @@
}
private ClientGetter makeGetter(FreenetURI uri) {
- ClientGetter g = new ClientGetter(this,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, ctx, PRIORITY_CLASS, this, null);
+ ClientGetter g = new ClientGetter(this,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, ctx, PRIORITY_CLASS, this, null, null);
return g;
}
Modified: trunk/freenet/src/freenet/clients/http/Spider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Spider.java 2007-05-23 22:40:31 UTC
(rev 13347)
+++ trunk/freenet/src/freenet/clients/http/Spider.java 2007-05-23 23:08:25 UTC
(rev 13348)
@@ -122,7 +122,7 @@
}
private ClientGetter makeGetter(FreenetURI uri) {
- ClientGetter g = new ClientGetter(this,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, ctx, PRIORITY_CLASS, this, null);
+ ClientGetter g = new ClientGetter(this,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
uri, ctx, PRIORITY_CLASS, this, null, null);
return g;
}
Modified: trunk/freenet/src/freenet/keys/CHKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/CHKBlock.java 2007-05-23 22:40:31 UTC
(rev 13347)
+++ trunk/freenet/src/freenet/keys/CHKBlock.java 2007-05-23 23:08:25 UTC
(rev 13348)
@@ -105,4 +105,8 @@
public byte[] getRawData() {
return data;
}
+
+ public byte[] getPubkeyBytes() {
+ return null;
+ }
}
Modified: trunk/freenet/src/freenet/keys/KeyBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/KeyBlock.java 2007-05-23 22:40:31 UTC
(rev 13347)
+++ trunk/freenet/src/freenet/keys/KeyBlock.java 2007-05-23 23:08:25 UTC
(rev 13348)
@@ -13,5 +13,6 @@
public Key getKey();
public byte[] getRawHeaders();
public byte[] getRawData();
+ public byte[] getPubkeyBytes();
}
Modified: trunk/freenet/src/freenet/keys/SSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/SSKBlock.java 2007-05-23 22:40:31 UTC
(rev 13347)
+++ trunk/freenet/src/freenet/keys/SSKBlock.java 2007-05-23 23:08:25 UTC
(rev 13348)
@@ -163,4 +163,8 @@
return pubKey;
}
+ public byte[] getPubkeyBytes() {
+ return pubKey.asBytes();
+ }
+
}
Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java 2007-05-23 22:40:31 UTC
(rev 13347)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java 2007-05-23 23:08:25 UTC
(rev 13348)
@@ -41,6 +41,7 @@
private final File tempFile;
/** Bucket passed in to the ClientGetter to return data in. Null unless
returntype=disk */
private Bucket returnBucket;
+ private final boolean binaryBlob;
// Verbosity bitmasks
private int VERBOSITY_SPLITFILE_PROGRESS = 1;
@@ -86,6 +87,7 @@
fctx.maxTempLength = maxOutputLength;
Bucket ret = null;
this.returnType = returnType;
+ binaryBlob = false;
if(returnType == ClientGetMessage.RETURN_TYPE_DISK) {
this.targetFile = returnFilename;
this.tempFile = returnTempFilename;
@@ -119,14 +121,13 @@
ret.free();
throw e;
}
- getter = new ClientGetter(this,
client.core.requestStarters.chkFetchScheduler,
client.core.requestStarters.sskFetchScheduler, uri, fctx, priorityClass,
client.lowLevelClient, returnBucket);
+ getter = new ClientGetter(this,
client.core.requestStarters.chkFetchScheduler,
client.core.requestStarters.sskFetchScheduler, uri, fctx, priorityClass,
client.lowLevelClient, returnBucket, null);
if(persistenceType != PERSIST_CONNECTION) {
FCPMessage msg = persistentTagMessage();
client.queueClientRequestMessage(msg, 0);
}
}
-
public ClientGet(FCPConnectionHandler handler, ClientGetMessage
message) throws IdentifierCollisionException, MessageInvalidException {
super(message.uri, message.identifier, message.verbosity,
handler, message.priorityClass,
message.persistenceType, message.clientToken,
message.global);
@@ -144,6 +145,7 @@
fctx.maxOutputLength = message.maxSize;
fctx.maxTempLength = message.maxTempSize;
this.returnType = message.returnType;
+ this.binaryBlob = message.binaryBlob;
Bucket ret = null;
if(returnType == ClientGetMessage.RETURN_TYPE_DISK) {
this.targetFile = message.diskFile;
@@ -180,7 +182,10 @@
ret.free();
throw e;
}
- getter = new ClientGetter(this,
client.core.requestStarters.chkFetchScheduler,
client.core.requestStarters.sskFetchScheduler, uri, fctx, priorityClass,
client.lowLevelClient, returnBucket);
+ getter = new ClientGetter(this,
client.core.requestStarters.chkFetchScheduler,
+ client.core.requestStarters.sskFetchScheduler,
uri, fctx, priorityClass,
+ client.lowLevelClient, binaryBlob ? new
NullBucket() : returnBucket,
+ binaryBlob ? returnBucket :
null);
if(persistenceType != PERSIST_CONNECTION) {
FCPMessage msg = persistentTagMessage();
client.queueClientRequestMessage(msg, 0);
@@ -219,6 +224,7 @@
fctx.ignoreStore = ignoreDS;
fctx.maxNonSplitfileRetries = maxRetries;
fctx.maxSplitfileBlockRetries = maxRetries;
+ binaryBlob = Fields.stringToBool(fs.get("BinaryBlob"), false);
succeeded = Fields.stringToBool(fs.get("Succeeded"), false);
if(finished) {
if(succeeded) {
@@ -260,7 +266,11 @@
}
returnBucket = ret;
- getter = new ClientGetter(this,
client.core.requestStarters.chkFetchScheduler,
client.core.requestStarters.sskFetchScheduler, uri, fctx, priorityClass,
client.lowLevelClient, returnBucket);
+ getter = new ClientGetter(this,
client.core.requestStarters.chkFetchScheduler,
+ client.core.requestStarters.sskFetchScheduler,
uri,
+ fctx, priorityClass, client.lowLevelClient,
+ binaryBlob ? new NullBucket() : returnBucket,
+ binaryBlob ? returnBucket : null);
if(persistenceType != PERSIST_CONNECTION) {
FCPMessage msg = persistentTagMessage();
@@ -310,8 +320,12 @@
public void onSuccess(FetchResult result, ClientGetter state) {
Logger.minor(this, "Succeeded: "+identifier);
Bucket data = result.asBucket();
- if(returnBucket != data)
+ if(returnBucket != data && !binaryBlob) {
Logger.error(this, "returnBucket = "+returnBucket+" but
onSuccess() data = "+data);
+ // Caller guarantees that data == returnBucket
+ onFailure(new
FetchException(FetchException.INTERNAL_ERROR, "Data != returnBucket"), null);
+ return;
+ }
boolean dontFree = false;
// FIXME I don't think this is a problem in this case...? (Disk
write while locked..)
AllDataMessage adm = null;
@@ -323,7 +337,7 @@
if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
// Send all the data at once
// FIXME there should be other options
- adm = new AllDataMessage(data, identifier,
global);
+ adm = new AllDataMessage(returnBucket,
identifier, global);
if(persistenceType == PERSIST_CONNECTION)
adm.setFreeOnSent();
dontFree = true;
@@ -335,17 +349,11 @@
// Write to temp file, then rename over filename
FileOutputStream fos = null;
boolean closed = false;
- // Caller guarantees that data ==
returnBucket
- if(data != returnBucket) {
- Logger.error(this, "Data !=
returnBucket for "+this);
- onFailure(new
FetchException(FetchException.INTERNAL_ERROR, "Data != returnBucket"), null);
- return;
- }
- if(!tempFile.renameTo(targetFile)) {
- postFetchProtocolErrorMessage =
new ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false,
null, identifier, global);
- // Don't delete temp file, user
might want it.
- }
- returnBucket = new
FileBucket(targetFile, false, true, false, false, false);
+ if(!tempFile.renameTo(targetFile)) {
+ postFetchProtocolErrorMessage = new
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false, null,
identifier, global);
+ // Don't delete temp file, user might
want it.
+ }
+ returnBucket = new FileBucket(targetFile,
false, true, false, false, false);
try {
if((fos != null) && !closed)
fos.close();
@@ -354,8 +362,11 @@
}
}
progressPending = null;
- this.foundDataLength = data.size();
- this.foundDataMimeType = result.getMimeType();
+ this.foundDataLength = returnBucket.size();
+ if(!binaryBlob)
+ this.foundDataMimeType = result.getMimeType();
+ else
+ this.foundDataMimeType =
"application/x-freenet-binary-blob";
this.succeeded = true;
finished = true;
}
@@ -533,6 +544,7 @@
bucketToFS(fs, "ReturnBucket", false, returnBucket);
}
fs.putSingle("Global", Boolean.toString(client.isGlobalQueue));
+ fs.put("BinaryBlob", binaryBlob);
return fs;
}
Modified: trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java 2007-05-23
22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/node/fcp/ClientGetMessage.java 2007-05-23
23:08:25 UTC (rev 13348)
@@ -54,6 +54,7 @@
final File tempFile;
final String clientToken;
final boolean global;
+ final boolean binaryBlob;
// FIXME move these to the actual getter process
static final short RETURN_TYPE_DIRECT = 0; // over FCP
@@ -189,6 +190,7 @@
if(global && (persistenceType ==
ClientRequest.PERSIST_CONNECTION)) {
throw new
MessageInvalidException(ProtocolErrorMessage.NOT_SUPPORTED, "Global requests
must be persistent", identifier, global);
}
+ binaryBlob = Fields.stringToBool(fs.get("BinaryBlob"), false);
}
public SimpleFieldSet getFieldSet() {
@@ -201,6 +203,7 @@
fs.putSingle("MaxSize", Long.toString(maxSize));
fs.putSingle("MaxTempSize", Long.toString(maxTempSize));
fs.putSingle("MaxRetries", Integer.toString(maxRetries));
+ fs.put("BinaryBlob", binaryBlob);
return fs;
}
Modified: trunk/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdater.java 2007-05-23
22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdater.java 2007-05-23
23:08:25 UTC (rev 13348)
@@ -117,7 +117,7 @@
System.err.println("Starting
"+(extUpdate?"freenet-ext.jar ":"")+"fetch for "+availableVersion);
cg = new ClientGetter(this,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
URI.setSuggestedEdition(availableVersion), ctx,
RequestStarter.UPDATE_PRIORITY_CLASS,
- this, new
ArrayBucket());
+ this, new
ArrayBucket(), null);
toStart = cg;
}
isFetching = true;
Modified: trunk/freenet/src/freenet/node/updater/RevocationChecker.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/RevocationChecker.java
2007-05-23 22:40:31 UTC (rev 13347)
+++ trunk/freenet/src/freenet/node/updater/RevocationChecker.java
2007-05-23 23:08:25 UTC (rev 13348)
@@ -85,7 +85,7 @@
cg = revocationGetter = new
ClientGetter(this, core.requestStarters.chkFetchScheduler,
core.requestStarters.sskFetchScheduler, manager.revocationURI, ctxRevocation,
aggressive ?
RequestStarter.MAXIMUM_PRIORITY_CLASS :
RequestStarter.IMMEDIATE_SPLITFILE_PRIORITY_CLASS,
- this, null);
+ this, null, null);
if(logMINOR) Logger.minor(this, "Queued
another revocation fetcher");
}
}