Author: toad
Date: 2005-11-07 18:32:32 +0000 (Mon, 07 Nov 2005)
New Revision: 7491

Added:
   trunk/freenet/src/freenet/support/io/SpyInputStream.java
   trunk/freenet/src/freenet/support/io/SpyOutputStream.java
Modified:
   trunk/freenet/src/freenet/support/io/FileBucket.java
   trunk/freenet/src/freenet/support/io/TempFileBucket.java
Log:
Temp file stuff.

Modified: trunk/freenet/src/freenet/support/io/FileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/FileBucket.java        2005-11-06 
01:09:44 UTC (rev 7490)
+++ trunk/freenet/src/freenet/support/io/FileBucket.java        2005-11-07 
18:32:32 UTC (rev 7491)
@@ -21,12 +21,11 @@

        protected File file;
        protected boolean readOnly;
-       protected boolean newFile; // hack to get around deletes
+       protected boolean deleteOnFinalize;
        protected long length;
        // JVM caches File.size() and there is no way to flush the cache, so we
        // need to track it ourselves
-       
-       private int lastOutputStream;
+       protected long fileRestartCounter;

        protected static String tempDir = null;

@@ -42,13 +41,14 @@
        public FileBucket(File file, boolean readOnly, boolean 
deleteOnFinalize, boolean deleteOnExit) {
                this.readOnly = readOnly;
                this.file = file;
-               this.newFile = deleteOnFinalize;
+               this.deleteOnFinalize = deleteOnFinalize;
                if(deleteOnExit)
                        file.deleteOnExit();
                // Useful for finding temp file leaks.
                // System.err.println("-- FileBucket.ctr(0) -- " +
                // file.getAbsolutePath());
                // (new Exception("get stack")).printStackTrace();
+               fileRestartCounter = 0;
                if(file.exists()) {
                        length = file.length();
                        if(!file.canWrite())
@@ -61,7 +61,6 @@
         * Creates a new FileBucket in a random temporary file in the temporary
         * directory.
         */
-
        public FileBucket(RandomSource random) {
                file =
                        new File(
@@ -73,7 +72,7 @@
                //System.err.println("-- FileBucket.ctr(1) -- " +
                // file.getAbsolutePath());
                //(new Exception("get stack")).printStackTrace();
-               newFile = true;
+               deleteOnFinalize = true;
                length = 0;
                file.deleteOnExit();
        }
@@ -88,12 +87,12 @@
                        // FIXME: what about existing streams? Will ones on 
append append
                        // to the new truncated file? Do we want them to? What 
about
                        // truncated ones? We should kill old streams here, 
right?
-                       return newFileBucketOutputStream(file.getPath(), 
++lastOutputStream);
+                       return newFileBucketOutputStream(file.getPath(), 
++fileRestartCounter);
                }
        }

        protected FileBucketOutputStream newFileBucketOutputStream(
-               String s, int streamNumber) throws IOException {
+               String s, long streamNumber) throws IOException {
                return new FileBucketOutputStream(s, streamNumber);
        }

@@ -103,44 +102,42 @@

        class FileBucketOutputStream extends FileOutputStream {

-               private int streamNumber;
+               private long restartCount;

                protected FileBucketOutputStream(
-                       String s, int streamNumber)
+                       String s, long restartCount)
                        throws FileNotFoundException {
                        super(s, false);
                        resetLength();
-                       this.streamNumber = streamNumber;
+                       this.restartCount = restartCount;
                }
-
+               
+               protected void confirmWriteSynchronized() throws IOException {
+                       if (fileRestartCounter > restartCount)
+                               throw new IllegalStateException("writing to 
file after restart");
+                       if(readOnly)
+                               throw new IOException("File is read-only");
+               }
+               
                public void write(byte[] b) throws IOException {
-                       if(streamNumber != lastOutputStream)
-                               throw new IllegalStateException("Writing to old 
stream in "+getName());
                        synchronized (FileBucket.this) {
-                               if(readOnly)
-                                       throw new IOException("Bucket is 
read-only");
+                               confirmWriteSynchronized();
                                super.write(b);
                                length += b.length;
                        }
                }

                public void write(byte[] b, int off, int len) throws 
IOException {
-                       if(streamNumber != lastOutputStream)
-                               throw new IllegalStateException("Writing to old 
stream in "+getName());
                        synchronized (FileBucket.this) {
-                               if(readOnly)
-                                       throw new IOException("Bucket is 
read-only");
+                               confirmWriteSynchronized();
                                super.write(b, off, len);
                                length += len;
                        }
                }

                public void write(int b) throws IOException {
-                       if(streamNumber != lastOutputStream)
-                               throw new IllegalStateException("Writing to old 
stream in "+getName());
                        synchronized (FileBucket.this) {
-                               if(readOnly)
-                                       throw new IOException("Bucket is 
read-only");
+                               confirmWriteSynchronized();
                                super.write(b);
                                length++;
                        }
@@ -193,7 +190,7 @@
                if (Logger.shouldLog(Logger.DEBUG, this))
                        Logger.debug(this,
                                "FileBucket Finalizing " + file.getName());
-               if (newFile && file.exists()) {
+               if (deleteOnFinalize && file.exists()) {
                        Logger.debug(this,
                                "Deleting bucket " + file.getName());
                        deleteFile();
@@ -300,6 +297,6 @@
         * can do to recover it! Delete file on finalize, on the other hand, is 
reversible.
         */
        public void dontDeleteOnFinalize() {
-               newFile = false;
+               deleteOnFinalize = false;
        }
 }

Added: trunk/freenet/src/freenet/support/io/SpyInputStream.java
===================================================================
--- trunk/freenet/src/freenet/support/io/SpyInputStream.java    2005-11-06 
01:09:44 UTC (rev 7490)
+++ trunk/freenet/src/freenet/support/io/SpyInputStream.java    2005-11-07 
18:32:32 UTC (rev 7491)
@@ -0,0 +1,143 @@
+package freenet.support.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/*
+ * This code is part of fproxy, an HTTP proxy server for Freenet. It is
+ * distributed under the GNU Public Licence (GPL) version 2. See
+ * http://www.gnu.org/ for further details of the GPL.
+ */
+
+/**
+ * The purpose of all of this gobbledeygook is to keep rude FCPClient
+ * implementations from writing to temp files after the requests that own them
+ * have been canceled.
+ * 
+ * <p>
+ * These could be removed once FCPClient implementation deficiencies have been
+ * corrected but sanity checks are always useful.
+ * </p>
+ * 
+ * @author ian
+ * @see freenet.support.SpyOutputStream
+ */
+class SpyInputStream extends java.io.FilterInputStream {
+
+    private String prefix = "";
+       private TempFileBucket tfb = null;
+
+       private final void println(String text) {
+       }
+
+       private final void checkValid() throws IOException {
+               if (tfb.isReleased()) {
+                       throw new IOException(
+                               "Attempt to use a released TempFileBucket: " + 
prefix);
+               }
+       }
+
+       /**
+        * Constructor for the SpyInputStream object
+        * 
+        * @param tfb
+        * @param prefix
+        * @exception IOException
+        */
+       public SpyInputStream(TempFileBucket tfb, String prefix)
+               throws IOException {
+               super(null);
+               InputStream tmpIn = null;
+               try {
+                       this.prefix = prefix;
+                       this.tfb = tfb;
+                       checkValid();
+                       tmpIn = tfb.getRealInputStream();
+                       in = tmpIn;
+               } catch (IOException ioe) {
+                       try {
+                               if (tmpIn != null) {
+                                       tmpIn.close();
+                               }
+                       } catch (Exception e) {
+                               // NOP
+                       }
+                       throw ioe;
+               }
+               println("Created new InputStream");
+       }
+
+       public int read() throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".read()");
+                       checkValid();
+                       return in.read();
+               }
+       }
+
+       public int read(byte[] bytes) throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".read(byte[])");
+                       checkValid();
+                       return in.read(bytes);
+               }
+       }
+
+    public int read(byte[] bytes, int a, int b) throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".read(byte[], int, int)");
+                       checkValid();
+                       return in.read(bytes, a, b);
+               }
+       }
+    
+       public long skip(long a) throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".skip(long)");
+                       checkValid();
+                       return in.skip(a);
+               }
+       }
+
+    public int available() throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".available()");
+                       checkValid();
+                       return in.available();
+               }
+       }
+       
+       public void close() throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".close()");
+                       checkValid();
+                       in.close();
+                       if (tfb.streams.contains(in)) {
+                               tfb.streams.removeElement(in);
+                       }
+               }
+       }
+
+       
+       public void mark(int a) {
+               synchronized (tfb) {
+                       println(".mark(int)");
+                       in.mark(a);
+               }
+       }
+
+       public void reset() throws java.io.IOException {
+               synchronized (tfb) {
+                       println(".reset()");
+                       checkValid();
+                       in.reset();
+               }
+       }
+
+    public boolean markSupported() {
+               synchronized (tfb) {
+                       println(".markSupported()");
+                       return in.markSupported();
+               }
+       }
+}

Added: trunk/freenet/src/freenet/support/io/SpyOutputStream.java
===================================================================
--- trunk/freenet/src/freenet/support/io/SpyOutputStream.java   2005-11-06 
01:09:44 UTC (rev 7490)
+++ trunk/freenet/src/freenet/support/io/SpyOutputStream.java   2005-11-07 
18:32:32 UTC (rev 7491)
@@ -0,0 +1,114 @@
+package freenet.support.io;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import freenet.support.Logger;
+
+/*
+ * This code is part of fproxy, an HTTP proxy server for Freenet. It is
+ * distributed under the GNU Public Licence (GPL) version 2. See
+ * http://www.gnu.org/ for further details of the GPL.
+ */
+
+/**
+ * @author ian
+ * @see freenet.support.SpyInputStream
+ */
+public class SpyOutputStream extends FilterOutputStream {
+
+       private String prefix = "";
+       private TempFileBucket tfb = null;
+
+       private void debugPrintLn(String text) {
+               if (Logger.shouldLog(Logger.DEBUG,this))
+                       Logger.debug(this, text);
+       }
+
+       private final void checkValid() throws IOException {
+               if (tfb.isReleased()) {
+                       throw new IOException(
+                               "Attempt to use a released TempFileBucket: " + 
prefix);
+               }
+       }
+
+       /**
+        * Constructor for the SpyOutputStream object
+        * 
+        * @param tfb
+        * @param pref
+        * @exception IOException
+        */
+       public SpyOutputStream(TempFileBucket tfb, String pref)
+               throws IOException {
+               super(null);
+               OutputStream tmpOut = null;
+               try {
+                       this.prefix = pref;
+                       this.tfb = tfb;
+                       checkValid();
+                       tmpOut = tfb.getRealOutputStream();
+                       out = tmpOut;
+               } catch (IOException ioe) {
+                       //ioe.printStackTrace();
+                       debugPrintLn("SpyOutputStream ctr failed!: " + 
ioe.toString());
+                       try {
+                               if (tmpOut != null) {
+                                       tmpOut.close();
+                               }
+                       } catch (Exception e0) {
+                               // NOP
+                       }
+                       debugPrintLn("SpyOutputStream ctr failed!: " + 
ioe.toString());
+                       throw ioe;
+               }
+               debugPrintLn("Created new OutputStream");
+       }
+
+       ////////////////////////////////////////////////////////////
+       // FilterOutputStream implementation
+
+       public void write(int b) throws IOException {
+               synchronized (tfb) {
+                       //       println(".write(b)");
+                       checkValid();
+                       out.write(b);
+               }
+       }
+
+       public void write(byte[] buf) throws IOException {
+               synchronized (tfb) {
+                       //       println(".write(buf)");
+                       checkValid();
+                       out.write(buf);
+               }
+       }
+
+       public void write(byte[] buf, int off, int len) throws IOException {
+               synchronized (tfb) {
+                       //       println(".write(buf,off,len)");
+                       checkValid();
+                       out.write(buf, off, len);
+               }
+       }
+
+       public void flush() throws IOException {
+               synchronized (tfb) {
+                       debugPrintLn(".flush()");
+                       checkValid();
+                       out.flush();
+               }
+       }
+
+       public void close() throws IOException {
+               synchronized (tfb) {
+                       debugPrintLn(".close()");
+                       checkValid();
+                       out.close();
+                       if (tfb.streams.contains(out)) {
+                               tfb.streams.removeElement(out);
+                       }
+               }
+       }
+}

Modified: trunk/freenet/src/freenet/support/io/TempFileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/TempFileBucket.java    2005-11-06 
01:09:44 UTC (rev 7490)
+++ trunk/freenet/src/freenet/support/io/TempFileBucket.java    2005-11-07 
18:32:32 UTC (rev 7491)
@@ -49,7 +49,7 @@

                // Make sure finalize wacks temp file 
                // if it is not explictly freed.
-               newFile = true;
+               deleteOnFinalize = true;

                //System.err.println("FproxyServlet.TempFileBucket -- created: 
" +
                //         f.getAbsolutePath());
@@ -174,12 +174,12 @@
                                                        "closed open 
OutputStream !: "
                                                                + 
file.getAbsolutePath(),
                                                        new Exception("debug"));
-                                               if (os instanceof 
FileBucketOutputStream) {
-                                                       Logger.debug(
-                                                               this,
-                                                               "Open 
OutputStream created: ",
-                                                               
((FileBucketOutputStream) os).e);
-                                               }
+//                                             if (os instanceof 
FileBucketOutputStream) {
+//                                                     Logger.debug(
+//                                                             this,
+//                                                             "Open 
OutputStream created: ",
+//                                                             
((FileBucketOutputStream) os).e);
+//                                             }

                                        }
                                }
@@ -240,16 +240,16 @@
                return released;
        }

-       /**
-        *  Finalize
-        *
-        * @exception  Throwable  Description of the Exception
-        */
-       public void finalize() throws Throwable {
-               if (logDebug)
-                       Logger.debug(this, "Finalizing TempFileBucket for " + 
file);
-               super.finalize();
-       }
+//     /**
+//      *  Finalize
+//      *
+//      * @exception  Throwable  Description of the Exception
+//      */
+//     public void finalize() throws Throwable {
+//             if (logDebug)
+//                     Logger.debug(this, "Finalizing TempFileBucket for " + 
file);
+//             super.finalize();
+//     }

        protected Vector streams = new Vector();
        private boolean released;
@@ -263,9 +263,9 @@
                        Logger.debug(this,
                                "Creating new HookedFileBucketOutputStream for 
" + file);
                if (hook != null)
-                       return new HookedFileBucketOutputStream(s, append, 
restartCount);
+                       return new HookedFileBucketOutputStream(s, 
restartCount);
                else
-                       return super.newFileBucketOutputStream(s, append, 
restartCount);
+                       return super.newFileBucketOutputStream(s, restartCount);
        }

        protected void deleteFile() {
@@ -342,10 +342,9 @@

                protected HookedFileBucketOutputStream(
                        String s,
-                       boolean append,
                        long restartCount)
                        throws IOException {
-                       super(s, append, restartCount);
+                       super(s, restartCount);
                        streams.addElement(this);
                        if (Logger.shouldLog(Logger.DEBUG, this))
                                Logger.debug(
@@ -353,8 +352,6 @@
                                        "Created HookedFileBucketOutputStream("
                                                + s
                                                + ","
-                                               + append
-                                               + ","
                                                + restartCount
                                                + ")");
                }


Reply via email to