mbecke 2003/03/31 18:13:09
Modified: httpclient/src/java/org/apache/commons/httpclient
HttpConnection.java
Log:
An attempt to make reusing HttpConnections more reliable. Connections are now
closed whenever an exception occurs during writing. All exceptions that occur
when writing to reused connections are now treated as recoverable.
PR: 18507
Reviewed by: Oleg Kalnichevski
Revision Changes Path
1.52 +72 -34
jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java
Index: HttpConnection.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- HttpConnection.java 13 Mar 2003 01:33:07 -0000 1.51
+++ HttpConnection.java 1 Apr 2003 02:13:09 -0000 1.52
@@ -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�ck
+ * @author Ortwin Gl�ck
* @author <a href="mailto:[EMAIL PROTECTED]">Jeff Dever</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Mike Bowler</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a>
@@ -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
/** <tt>"\r\n"</tt>, 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;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]