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
+ ")");
}