Index: java/org/apache/commons/httpclient/HttpConnection.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v
retrieving revision 1.51
diff -u -r1.51 HttpConnection.java
--- java/org/apache/commons/httpclient/HttpConnection.java 13 Mar 2003 01:33:07 -0000 1.51
+++ java/org/apache/commons/httpclient/HttpConnection.java 31 Mar 2003 04:47:20 -0000
@@ -63,6 +63,7 @@
package org.apache.commons.httpclient;
+import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -100,7 +101,7 @@
*
* @author Rod Waldhoff
* @author Sean C. Sullivan
- * @author Ortwin Gl�
+ * @author Ortwin Gl�ck
* @author Jeff Dever
* @author Mike Bowler
* @author Oleg Kalnichevski
@@ -542,8 +543,9 @@
socket.setTcpNoDelay(soNodelay);
socket.setSoTimeout(soTimeout);
inputStream = socket.getInputStream();
- outputStream = socket.getOutputStream();
+ outputStream = new WrappedOutputStream(socket.getOutputStream());
isOpen = true;
+ used = false;
} catch (IOException e) {
// Connection wasn't opened properly
// so close everything out
@@ -638,12 +640,11 @@
throws IOException, IllegalStateException {
LOG.trace("enter HttpConnection.getRequestOutputStream(boolean)");
- assertOpen();
+ OutputStream out = getRequestOutputStream();
if (useChunking) {
- return new ChunkedOutputStream(outputStream);
- } else {
- return outputStream;
+ out = new ChunkedOutputStream(out);
}
+ return out;
}
/**
@@ -743,6 +744,8 @@
try {
outputStream.write(data, offset, length);
+ } catch (HttpRecoverableException hre) {
+ throw hre;
} catch (SocketException se) {
LOG.debug(
"HttpConnection: Socket exception while writing data",
@@ -766,19 +769,8 @@
public void writeLine(byte[] data)
throws IOException, IllegalStateException, HttpRecoverableException {
LOG.trace("enter HttpConnection.writeLine(byte[])");
-
- assertOpen();
-
- try {
- outputStream.write(data);
- writeLine();
- } catch (SocketException se) {
- LOG.info("SocketException while writing data to output", se);
- throw new HttpRecoverableException(se.toString());
- } catch (IOException ioe) {
- LOG.info("IOException while writing data to output", ioe);
- throw ioe;
- }
+ write(data);
+ writeLine();
}
/**
@@ -792,16 +784,7 @@
public void writeLine()
throws IOException, IllegalStateException, HttpRecoverableException {
LOG.trace("enter HttpConnection.writeLine()");
-
- try {
- outputStream.write(CRLF);
- } catch (SocketException se) {
- LOG.warn("HttpConnection: Socket exception while writing data", se);
- throw new HttpRecoverableException(se.toString());
- } catch (IOException ioe) {
- LOG.warn("HttpConnection: IO exception while writing data", ioe);
- throw ioe;
- }
+ write(CRLF);
}
/**
@@ -922,6 +905,8 @@
// connections so we want to close them after one use
close();
}
+ // we are assuming that the connection will only be released once used
+ used = true;
if (httpConnectionManager != null) {
httpConnectionManager.releaseConnection(this);
}
@@ -1046,6 +1031,55 @@
}
}
+ /**
+ * A wrapper for output streams that closes the connection and converts to recoverable
+ * exceptions as appropriable when an IOException occurs.
+ */
+ private class WrappedOutputStream extends FilterOutputStream {
+
+ /**
+ * @param out the output stream to wrap
+ */
+ public WrappedOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ /**
+ * Closes the connection and conditionally converts exception to recoverable.
+ * @param ioe the exception that occurred
+ * @return the exception to be thrown
+ */
+ private IOException handleException(IOException ioe) {
+ HttpConnection.this.close();
+ if (used) {
+ LOG.debug(
+ "Output exception occurred on a used connection. Will treat as recoverable.",
+ ioe
+ );
+ return new HttpRecoverableException(ioe.toString());
+ } else {
+ return ioe;
+ }
+ }
+
+ public void write(int b) throws IOException {
+ try {
+ super.write(b);
+ } catch (IOException ioe) {
+ throw handleException(ioe);
+ }
+ }
+
+ public void flush() throws IOException {
+ try {
+ super.flush();
+ } catch (IOException ioe) {
+ throw handleException(ioe);
+ }
+ }
+
+ }
+
// ------------------------------------------------------- Static Variable
/** "\r\n", as bytes. */
@@ -1054,7 +1088,11 @@
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(HttpConnection.class);
- // ----------------------------------------------------- Instance Variables
+ // ----------------------------------------------------- Instance Variables
+
+ /** A flag indicating if this connection has been used since being opened */
+ private boolean used = false;
+
/** My host. */
private String hostName = null;