Hi suxuan,

Could you please fill a CXF jira ticket about this issue?

Thanks!
Freeman


On Mon, Jan 6, 2025 at 1:06 AM suxuan xu <suxuan.k...@gmail.com> wrote:

> 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
>

Reply via email to