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]

Reply via email to