Dear Apache CXF Development Team, I would like to report a bug in the `HttpClientWrappedOutputStream` class within the `org.apache.cxf.transport.http` package. The issue occurs during the handling of an `IOException` when the `close` method is invoked.
**Description of the Issue:** When the `close` method of the parent class `org.apache.cxf.transport.http.HTTPConduit.WrappedOutputStream` is called, a timeout occurs at line 1420, resulting in an `IOException`. This exception is caught at line 1428 and subsequently rethrown to the upper layer. The upper layer, specifically the `close` method in `org.apache.cxf.transport.http.HttpClientHTTPConduit.HttpClientWrappedOutputStream`, does not properly handle the exception. As a result, the `pout` resource (which corresponds to the socket for writing) is not released, leading to a connection leak. **Steps to Reproduce:** 1. Invoke the `close` method on an instance of `HttpClientWrappedOutputStream`. 2. Simulate a timeout condition that triggers an `IOException` in the parent class's `close` method. 3. Observe that the `pout` resource is not released, causing a connection leak. 4. The relevant Java exception stack trace is as follows: Caused by: java.net.http.HttpTimeoutException: HttpTimeoutException invoking https://reporting.api.bingads.microsoft.com/Reporting/v13/GenerateReport/Poll: Timeout at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1452) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1433) at org.apache.cxf.transport.http.HttpClientHTTPConduit$HttpClientWrappedOutputStream.close(HttpClientHTTPConduit.java:824) at org.apache.cxf.io.AbstractWrappedOutputStream.close(AbstractWrappedOutputStream.java:77) at org.apache.cxf.io.AbstractWrappedOutputStream.close(AbstractWrappedOutputStream.java:77) at org.apache.cxf.io.AbstractThresholdOutputStream.close(AbstractThresholdOutputStream.java:102) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:717) at org.apache.cxf.transport.http.HttpClientHTTPConduit.close(HttpClientHTTPConduit.java:261) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) at org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:717) at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1085) ... 17 more Caused by: java.net.http.HttpTimeoutException: Timeout at org.apache.cxf.transport.http.HttpClientHTTPConduit$HttpClientWrappedOutputStream.getResponse(HttpClientHTTPConduit.java:1074) at org.apache.cxf.transport.http.HttpClientHTTPConduit$HttpClientWrappedOutputStream.getResponseCode(HttpClientHTTPConduit.java:1081) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.doProcessResponseCode(HTTPConduit.java:1653) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1684) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1626) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1420) ... 28 more Caused by: java.util.concurrent.TimeoutException at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1960) at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095) at org.apache.cxf.transport.http.HttpClientHTTPConduit$HttpClientWrappedOutputStream.getResponse(HttpClientHTTPConduit.java:1052) ... 33 more **Expected Behavior:** The `close` method in `HttpClientWrappedOutputStream` should ensure that all resources, including `pout`, are properly released even if an `IOException` is thrown by the parent class's `close` method. **Proposed Fix:** The `close` method in `HttpClientWrappedOutputStream` should be modified to include a `finally` block that guarantees the release of the `pout` resource, regardless of whether an exception is thrown. Here is a suggested code snippet: ```java @Override public void close() throws IOException { try { super.close(); } finally { if (pout != null) { try { pout.close(); } catch (IOException e) { // Log the exception if necessary } } } } ``` This ensures that `pout` is always closed, preventing connection leaks. **Environment:** - Apache CXF Version: 4.0.5 - Java Version: OpenJDK 17.0.12 - Operating System: Ubuntu 18.04 AMD 64 **Additional Information:** Please let me know if you need any further details or if there is any additional information I can provide to assist in resolving this issue. Thank you for your attention to this matter. Best regards, suxuan
