You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by bu...@apache.org on 2006/03/17 15:36:44 UTC

DO NOT REPLY [Bug 39014] New: - HTTP Client 3.0 doesn't close sockets

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=39014>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=39014

           Summary: HTTP Client 3.0 doesn't close sockets
           Product: HttpClient
           Version: 3.0 Final
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: critical
          Priority: P2
         Component: Commons HttpClient
        AssignedTo: httpclient-dev@jakarta.apache.org
        ReportedBy: kuebeck@qenta.com


For some reason, HTTPClient doesn't close underlying sockets,
which caused several OutOfMemoryErrorS in my application.
Maybe I did something wrong but the following code prooves
that the connection keeps open although I call releaseConnection(), 
a phenomenon that didn't occur with Version 2!

I'm using jdk 1.4.2_10 for Windows XP and Linux (SuSE 9.2)
and get the same results for both. 

Regards,

Sebastian



public class ConnectionLeak {

	public static void main(String args[]) {
		Factory f = new Factory();
		Protocol.registerProtocol("myhttp", new Protocol("myhttp", f, 80));
		HttpClient client = new HttpClient();
		GetMethod get = null;
		InputStream is = null;
		try {
			client = new HttpClient();
			get = new GetMethod("myhttp://www.apache.org");
			client.executeMethod(get);
			is = get.getResponseBodyAsStream();
			byte b[] = new byte[1024]; int l = 0;
			while((l = is.read(b)) > 0) {
				System.out.print(new String(b, 0, l));
			}
		} catch(IOException e) {
			e.printStackTrace();
			return;
		} finally {
			if(is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
			
			if(get != null) {
				get.releaseConnection();
			}
		}
		
		if(!f.socket.closeCalled) {
			System.out.println("CLOSE NOT CALLED!!!");
		}
	}

	public static class Factory implements ProtocolSocketFactory {
		public SocketWrapper socket = null;
		
		public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3,
HttpConnectionParams arg4) throws IOException, UnknownHostException,
ConnectTimeoutException {
			return socket = new SocketWrapper(new Socket(arg0, arg1, arg2, arg3));
		}

		public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
throws IOException, UnknownHostException {
			return socket = new SocketWrapper(new Socket(arg0, arg1, arg2, arg3));
		}

		public Socket createSocket(String arg0, int arg1) throws IOException,
UnknownHostException {
			return socket = new SocketWrapper(new Socket(arg0, arg1));
		}
	}
	
	public static class SocketWrapper extends Socket {
		Log log = LogFactory.getLog(SocketWrapper.class);
		boolean closeCalled = false;

		Socket socket;
		
		public SocketWrapper(Socket socket) {
			this.socket = socket;
		}

		public synchronized void close() throws IOException {
			socket.close();
			closeCalled = true;
		}
		
		public void bind(SocketAddress arg0) throws IOException {
			socket.bind(arg0);
		}

		public void connect(SocketAddress arg0, int arg1) throws IOException {
			socket.connect(arg0, arg1);
		}

		public void connect(SocketAddress arg0) throws IOException {
			socket.connect(arg0);
		}

		public SocketChannel getChannel() {
			return socket.getChannel();
		}

		public InetAddress getInetAddress() {
			return socket.getInetAddress();
		}

		public InputStream getInputStream() throws IOException {
			return socket.getInputStream();
		}

		public boolean getKeepAlive() throws SocketException {
			return socket.getKeepAlive();
		}

		public InetAddress getLocalAddress() {
			return socket.getLocalAddress();
		}

		public int getLocalPort() {
			return socket.getLocalPort();
		}

		public SocketAddress getLocalSocketAddress() {
			return socket.getLocalSocketAddress();
		}

		public boolean getOOBInline() throws SocketException {
			return socket.getOOBInline();
		}

		public OutputStream getOutputStream() throws IOException {
			return socket.getOutputStream();
		}

		public int getPort() {
			return socket.getPort();
		}

		public synchronized int getReceiveBufferSize() throws SocketException {
			return socket.getReceiveBufferSize();
		}

		public SocketAddress getRemoteSocketAddress() {
			return socket.getRemoteSocketAddress();
		}

		public boolean getReuseAddress() throws SocketException {
			return socket.getReuseAddress();
		}

		public synchronized int getSendBufferSize() throws SocketException {
			return socket.getSendBufferSize();
		}

		public int getSoLinger() throws SocketException {
			return socket.getSoLinger();
		}

		public synchronized int getSoTimeout() throws SocketException {
			return socket.getSoTimeout();
		}

		public boolean getTcpNoDelay() throws SocketException {
			return socket.getTcpNoDelay();
		}

		public int getTrafficClass() throws SocketException {
			return socket.getTrafficClass();
		}

		public boolean isBound() {
			return socket.isBound();
		}

		public boolean isClosed() {
			return socket.isClosed();
		}

		public boolean isConnected() {
			return socket.isConnected();
		}

		public boolean isInputShutdown() {
			return socket.isInputShutdown();
		}

		public boolean isOutputShutdown() {
			return socket.isOutputShutdown();
		}

		public void sendUrgentData(int arg0) throws IOException {
			socket.sendUrgentData(arg0);
		}
		
		public void setKeepAlive(boolean arg0) throws SocketException {
			socket.setKeepAlive(arg0);
		}

		public void setOOBInline(boolean arg0) throws SocketException {
			socket.setOOBInline(arg0);
		}

		public synchronized void setReceiveBufferSize(int arg0) throws SocketException {
			socket.setReceiveBufferSize(arg0);
		}

		public void setReuseAddress(boolean arg0) throws SocketException {
			socket.setReuseAddress(arg0);
		}

		public synchronized void setSendBufferSize(int arg0) throws SocketException {
			socket.setSendBufferSize(arg0);
		}

		public void setSoLinger(boolean arg0, int arg1) throws SocketException {
			socket.setSoLinger(arg0, arg1);
		}

		public synchronized void setSoTimeout(int arg0) throws SocketException {
			socket.setSoTimeout(arg0);
		}

		public void setTcpNoDelay(boolean arg0) throws SocketException {
			socket.setTcpNoDelay(arg0);
		}

		public void setTrafficClass(int arg0) throws SocketException {
			socket.setTrafficClass(arg0);
		}

		public void shutdownInput() throws IOException {
			socket.shutdownInput();
		}

		public void shutdownOutput() throws IOException {
			socket.shutdownOutput();
		}

		public String toString() {
			return socket.toString();
		}
	}
}

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


DO NOT REPLY [Bug 39014] - HTTP Client 3.0 doesn't close sockets

Posted by bu...@apache.org.
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=39014>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=39014


odi@odi.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID




------- Additional Comments From odi@odi.ch  2006-03-17 14:48 -------
It's a feature, not a bug. Of course releaseConnection() doesn't imply the
socket is closed. HttpClient manages a connection pool even with the simple
connection manager. If you want your sockets to close immediately, include a
"Connection: close" header in your request or resort to HTTP/1.0. You may also
call HttpConnectionManager.closeIdleConnections(0).

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


DO NOT REPLY [Bug 39014] - HTTP Client 3.0 doesn't close sockets

Posted by bu...@apache.org.
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=39014>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=39014





------- Additional Comments From odi@odi.ch  2006-03-17 15:27 -------
HttpClient fully supports persistent connections as defined per section 8.1 of
RFC 2616. The connection pool implementation is responsbile for closing physical
connections when they become stale.

I guess your application does not profit of connection pooling as it never hits
the same host twice. So open connections keep accumulating in the pool. Thus you
should disable the pooling by the measures outlined earlier. A different very
simple solution is to use the MultithreadedConnectionManager which supports
setting a limit via its setMaxTotalConnections method. If none of those
suggestions meet your needs you can always implement your own connection manager.



-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


DO NOT REPLY [Bug 39014] - HTTP Client 3.0 doesn't close sockets

Posted by bu...@apache.org.
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=39014>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=39014





------- Additional Comments From kuebeck@qenta.com  2006-03-17 15:05 -------
Interesting feature!
How does the connection pool make sure the connections are closed after all?
In my experience, the client creates new sockets untill the VM memory
is exhausted. 
Is this behaviour documented somewhere so that other people don't
fall into that trap?

Sebastian

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org