Author: toad
Date: 2006-03-03 21:38:55 +0000 (Fri, 03 Mar 2006)
New Revision: 8150

Added:
   trunk/freenet/src/freenet/support/io/NullBucket.java
Modified:
   trunk/freenet/src/freenet/client/ArchiveManager.java
   trunk/freenet/src/freenet/client/async/ClientGetter.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/node/fcp/ClientGet.java
   trunk/freenet/src/freenet/node/fcp/FCPClient.java
   trunk/freenet/src/freenet/node/fcp/FCPConnectionOutputHandler.java
   trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
   
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
   trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
Log:
487:
ClientGet { Persistence=forever, ReturnType=disk|none|direct } all work now.

Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java        2006-03-03 
20:50:13 UTC (rev 8149)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java        2006-03-03 
21:38:55 UTC (rev 8150)
@@ -359,7 +359,7 @@

                byte[] cipherKey = new byte[32];
                random.nextBytes(cipherKey);
-               PaddedEphemerallyEncryptedBucket encryptedBucket = new 
PaddedEphemerallyEncryptedBucket(fb, 1024, random);
+               PaddedEphemerallyEncryptedBucket encryptedBucket = new 
PaddedEphemerallyEncryptedBucket(fb, 1024, random, true);
                return new TempStoreElement(myFile, fb, encryptedBucket);
        }


Modified: trunk/freenet/src/freenet/client/async/ClientGetter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientGetter.java    2006-03-03 
20:50:13 UTC (rev 8149)
+++ trunk/freenet/src/freenet/client/async/ClientGetter.java    2006-03-03 
21:38:55 UTC (rev 8150)
@@ -70,6 +70,7 @@
                        try {
                                Logger.minor(this, "Copying - returnBucket not 
respected by client.async");
                                BucketTools.copy(from, to);
+                               from.free();
                        } catch (IOException e) {
                                onFailure(new 
FetchException(FetchException.BUCKET_ERROR), state /* not strictly to blame, 
but we're not ako ClientGetState... */);
                        }

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-03-03 20:50:13 UTC (rev 
8149)
+++ trunk/freenet/src/freenet/node/Version.java 2006-03-03 21:38:55 UTC (rev 
8150)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 486;
+       private static final int buildNumber = 487;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 475;

Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-03-03 20:50:13 UTC 
(rev 8149)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-03-03 21:38:55 UTC 
(rev 8150)
@@ -21,9 +21,12 @@
 import freenet.support.Bucket;
 import freenet.support.BucketTools;
 import freenet.support.Fields;
+import freenet.support.HexUtil;
 import freenet.support.Logger;
+import freenet.support.PaddedEphemerallyEncryptedBucket;
 import freenet.support.SimpleFieldSet;
 import freenet.support.io.FileBucket;
+import freenet.support.io.NullBucket;

 /**
  * A simple client fetch. This can of course fetch arbitrarily large
@@ -98,15 +101,28 @@
                fctx.maxOutputLength = message.maxSize;
                fctx.maxTempLength = message.maxTempSize;
                this.returnType = message.returnType;
+               Bucket ret = null;
                if(returnType == ClientGetMessage.RETURN_TYPE_DISK) {
                        this.targetFile = message.diskFile;
                        this.tempFile = message.tempFile;
-                       returnBucket = new FileBucket(message.tempFile, false, 
false, false, false);
+                       ret = new FileBucket(message.tempFile, false, false, 
false, false);
+               } else if(returnType == ClientGetMessage.RETURN_TYPE_NONE) {
+                       targetFile = null;
+                       tempFile = null;
+                       ret = new NullBucket();
                } else {
-                       returnBucket = null;
                        targetFile = null;
                        tempFile = null;
+                       try {
+                               ret = 
handler.server.node.persistentTempBucketFactory.makeEncryptedBucket();
+                       } catch (IOException e) {
+                               onFailure(new 
FetchException(FetchException.BUCKET_ERROR), null);
+                               getter = null;
+                               returnBucket = null;
+                               return;
+                       }
                }
+               returnBucket = ret;
                getter = new ClientGetter(this, client.node.fetchScheduler, 
uri, fctx, priorityClass, client, returnBucket);
        }

@@ -163,11 +179,20 @@
                                getFailedMessage = new 
GetFailedMessage(fs.subset("GetFailed"), false);
                        }
                }
+               Bucket ret = null;
                if(returnType == ClientGetMessage.RETURN_TYPE_DISK) {
-                       returnBucket = new FileBucket(tempFile, false, false, 
false, false);
-               } else
-                       returnBucket = null;
-
+                       ret = new FileBucket(tempFile, false, false, false, 
false);
+               } else if(returnType == ClientGetMessage.RETURN_TYPE_NONE) {
+                       ret = new NullBucket();
+               } else if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
+                       byte[] key = 
HexUtil.hexToBytes(fs.get("ReturnBucket.DecryptKey"));
+                       String fnam = fs.get("ReturnBucket.Filename");
+                       ret = 
client.server.node.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key);
+               } else {
+                       throw new IllegalArgumentException();
+               }
+               returnBucket = ret;
+               
                getter = new ClientGetter(this, client.node.fetchScheduler, 
uri, fctx, priorityClass, client, returnBucket);
                start();
        }
@@ -192,18 +217,19 @@

        public void onSuccess(FetchResult result, ClientGetter state) {
                Bucket data = result.asBucket();
+               if(returnBucket != data)
+                       Logger.error(this, "returnBucket = "+returnBucket+" but 
onSuccess() data = "+data);
                boolean dontFree = false;
                // FIXME I don't think this is a problem in this case...? (Disk 
write while locked..)
+               AllDataMessage adm = null;
                synchronized(this) {
                        if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
                                // Send all the data at once
                                // FIXME there should be other options
-                               trySendDataFoundOrGetFailed();
-                               AllDataMessage m = new AllDataMessage(data, 
identifier);
+                               adm = new AllDataMessage(data, identifier);
                                if(persistenceType == PERSIST_CONNECTION)
-                                       m.setFreeOnSent();
+                                       adm.setFreeOnSent();
                                dontFree = true;
-                               trySendAllDataMessage(m);
                        } else if(returnType == 
ClientGetMessage.RETURN_TYPE_NONE) {
                                // Do nothing
                        } else if(returnType == 
ClientGetMessage.RETURN_TYPE_DISK) {
@@ -221,7 +247,6 @@
                                        }
                                        if(!tempFile.renameTo(targetFile)) {
                                                postFetchProtocolErrorMessage = 
new ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false, 
null, identifier);
-                                               trySendDataFoundOrGetFailed();
                                                // Don't delete temp file, user 
might want it.
                                        }
                                } catch (FileNotFoundException e) {
@@ -237,13 +262,14 @@
                                }
                        }
                        progressPending = null;
-                       FCPMessage msg = new DataFoundMessage(result, 
identifier);
                        this.foundDataLength = data.size();
                        this.foundDataMimeType = result.getMimeType();
                        this.succeeded = true;
                        finished = true;
                }
                trySendDataFoundOrGetFailed();
+               if(adm != null)
+                       trySendAllDataMessage(adm);
                if(!dontFree)
                        data.free();
                finish();
@@ -253,17 +279,18 @@

                FCPMessage msg;

-               if(postFetchProtocolErrorMessage != null) {
-                       msg = postFetchProtocolErrorMessage;
-               } else if(succeeded) {
+               if(succeeded) {
                        msg = new DataFoundMessage(foundDataLength, 
foundDataMimeType, identifier);
                } else {
                        msg = getFailedMessage;
                }

                FCPConnectionHandler conn = client.getConnection();
-               if(conn != null)
+               if(conn != null) {
                        conn.outputHandler.queue(msg);
+                       if(postFetchProtocolErrorMessage != null)
+                               
conn.outputHandler.queue(postFetchProtocolErrorMessage);
+               }
        }

        private void trySendAllDataMessage(AllDataMessage msg) {
@@ -408,6 +435,12 @@
                                }
                        }
                }
+               // Return bucket
+               if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
+                       PaddedEphemerallyEncryptedBucket b = 
(PaddedEphemerallyEncryptedBucket) returnBucket;
+                       fs.put("ReturnBucket.DecryptKey", 
HexUtil.bytesToHex(b.getKey()));
+                       fs.put("ReturnBucket.Filename", 
((FileBucket)b.getUnderlying()).getName());
+               }
                return fs;
        }


Modified: trunk/freenet/src/freenet/node/fcp/FCPClient.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPClient.java   2006-03-03 20:50:13 UTC 
(rev 8149)
+++ trunk/freenet/src/freenet/node/fcp/FCPClient.java   2006-03-03 21:38:55 UTC 
(rev 8150)
@@ -126,8 +126,9 @@
                        req = (ClientRequest) 
clientRequestsByIdentifier.get(identifier);
                        if(req == null)
                                throw new 
MessageInvalidException(ProtocolErrorMessage.NO_SUCH_IDENTIFIER, null, 
identifier);
-                       else if(!(runningPersistentRequests.remove(req) || 
completedUnackedRequests.remove(req)))
+                       else if(!(runningPersistentRequests.remove(req) | 
completedUnackedRequests.remove(req)))
                                throw new 
MessageInvalidException(ProtocolErrorMessage.NO_SUCH_IDENTIFIER, null, 
identifier);
+                       clientRequestsByIdentifier.remove(identifier);
                }
                server.forceStorePersistentRequests();
        }

Modified: trunk/freenet/src/freenet/node/fcp/FCPConnectionOutputHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPConnectionOutputHandler.java  
2006-03-03 20:50:13 UTC (rev 8149)
+++ trunk/freenet/src/freenet/node/fcp/FCPConnectionOutputHandler.java  
2006-03-03 21:38:55 UTC (rev 8150)
@@ -56,6 +56,7 @@
        }

        public void queue(FCPMessage msg) {
+               if(msg == null) throw new NullPointerException();
                synchronized(outQueue) {
                        outQueue.add(msg);
                        outQueue.notifyAll();

Modified: 
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java     
2006-03-03 20:50:13 UTC (rev 8149)
+++ trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java     
2006-03-03 21:38:55 UTC (rev 8150)
@@ -22,6 +22,8 @@
        private final int minPaddedSize;
        private final RandomSource origRandom;
        private final Rijndael aes;
+       /** The decryption key. May be null. */
+       private final byte[] key;
        private long dataLength;
        private boolean readOnly;
        private int lastOutputStream;
@@ -34,7 +36,7 @@
         * @param origRandom Hard random number generator from which to obtain 
a seed for padding.
         * @throws UnsupportedCipherException 
         */
-       public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize, 
RandomSource origRandom) {
+       public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize, 
RandomSource origRandom, boolean forgetKey) {
                this.origRandom = origRandom;
                this.bucket = bucket;
                if(bucket.size() != 0) throw new 
IllegalArgumentException("Bucket must be empty");
@@ -46,8 +48,13 @@
                byte[] key = new byte[32];
                origRandom.nextBytes(key);
                aes.initialize(key);
-               // Might as well blank it
-               for(int i=0;i<key.length;i++) key[i] = 0;
+               if(forgetKey) {
+                       // Might as well blank it
+                       for(int i=0;i<key.length;i++) key[i] = 0;
+                       this.key = null;
+               } else {
+                       this.key = key;
+               }
                this.minPaddedSize = minSize;
                readOnly = false;
                lastOutputStream = 0;
@@ -64,8 +71,7 @@
                }
                origRandom.nextBytes(key);
                aes.initialize(key);
-               // Might as well blank it
-               for(int i=0;i<key.length;i++) key[i] = 0;
+               this.key = key;
                this.minPaddedSize = minSize;
                readOnly = false;
                lastOutputStream = 0;
@@ -260,4 +266,11 @@
                bucket.free();
        }

+       /**
+        * Get the decryption key. May have been blanked out.
+        */
+       public byte[] getKey() {
+               return key;
+       }
+
 }

Modified: 
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
===================================================================
--- 
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java  
    2006-03-03 20:50:13 UTC (rev 8149)
+++ 
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java  
    2006-03-03 21:38:55 UTC (rev 8150)
@@ -22,7 +22,7 @@
        }

        public Bucket makeBucket(long size) throws IOException {
-               return new 
PaddedEphemerallyEncryptedBucket(baseFactory.makeBucket(size), minSize, random);
+               return new 
PaddedEphemerallyEncryptedBucket(baseFactory.makeBucket(size), minSize, random, 
true);
        }

        public void freeBucket(Bucket b) throws IOException {

Added: trunk/freenet/src/freenet/support/io/NullBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/NullBucket.java        2006-03-03 
20:50:13 UTC (rev 8149)
+++ trunk/freenet/src/freenet/support/io/NullBucket.java        2006-03-03 
21:38:55 UTC (rev 8150)
@@ -0,0 +1,64 @@
+package freenet.support.io;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import freenet.support.Bucket;
+
+public class NullBucket implements Bucket {
+
+    public final OutputStream nullOut = new NullOutputStream();
+    public final InputStream  nullIn  = new NullInputStream();
+
+    public final long length;
+    
+    public NullBucket() {
+        this(0);
+    }
+
+    public NullBucket(long length) {
+        this.length = length;
+    }
+    
+    /**
+     * Returns an OutputStream that is used to put data in this Bucket.
+     **/
+    public OutputStream getOutputStream() { return nullOut; }
+
+    /**
+     * Returns an InputStream that reads data from this Bucket. If there is
+     * no data in this bucket, null is returned.
+     **/
+    public InputStream getInputStream() { return nullIn; }
+
+    /**
+     * If resetWrite() is called on the object, the next getOutputStream
+     * should overwrite any other data in the bucket from the beginning,
+     * otherwise it should append it.
+     **/
+    public void resetWrite() {}
+
+    /**
+     * Returns the amount of data currently in this bucket.
+     **/
+    public long size() {
+        return length;
+    }
+
+    /** Returns the name of this NullBucket. */
+    public String getName() {
+       return "President George W. NullBucket";
+    }
+
+       public boolean isReadOnly() {
+               return false;
+       }
+
+       public void setReadOnly() {
+               // Do nothing
+       }
+
+       public void free() {
+               // Do nothing
+       }
+}
+

Modified: trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java       
2006-03-03 20:50:13 UTC (rev 8149)
+++ trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java       
2006-03-03 21:38:55 UTC (rev 8150)
@@ -85,8 +85,7 @@
        public void completedInit() {
                Iterator i = originalFiles.iterator();
                while(i.hasNext()) {
-                       String s = (String) (i.next());
-                       File f = new File(s);
+                       File f = (File) (i.next());
                        f.delete();
                }
        }
@@ -97,7 +96,7 @@

        public Bucket makeEncryptedBucket() throws IOException {
                Bucket b = makeBucket(-1);
-               return new PaddedEphemerallyEncryptedBucket(b, 1024, rand);
+               return new PaddedEphemerallyEncryptedBucket(b, 1024, rand, 
false);
        }

        public Bucket registerEncryptedBucket(String filename, byte[] key) {


Reply via email to