You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2024/04/25 08:54:19 UTC
(httpcomponents-client) branch 5.3.x updated: Made handling of refused tunnel exception consistent between the classic and async protocol handler implementations; Proxy response body no longer gets buffered in memory in order to avoid excessive resource allocation in case of a proxy misbehavior
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch 5.3.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git
The following commit(s) were added to refs/heads/5.3.x by this push:
new 024a5c57f Made handling of refused tunnel exception consistent between the classic and async protocol handler implementations; Proxy response body no longer gets buffered in memory in order to avoid excessive resource allocation in case of a proxy misbehavior
024a5c57f is described below
commit 024a5c57fb587305c5df99ea525aefd4bab48ab3
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Apr 25 10:51:56 2024 +0200
Made handling of refused tunnel exception consistent between the classic and async protocol handler implementations; Proxy response body no longer gets buffered in memory in order to avoid excessive resource allocation in case of a proxy misbehavior
---
.../org/apache/hc/client5/http/impl/async/AsyncConnectExec.java | 6 ++++--
.../java/org/apache/hc/client5/http/impl/classic/ConnectExec.java | 7 ++-----
.../java/org/apache/hc/client5/http/impl/classic/ProxyClient.java | 7 ++-----
.../org/apache/hc/client5/http/impl/classic/TestConnectExec.java | 4 +---
4 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
index 493ab6c9e..af752dc06 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
@@ -122,6 +122,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
volatile boolean challenged;
volatile boolean tunnelRefused;
+ volatile HttpResponse tunnelResponse;
}
@@ -298,7 +299,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
if (LOG.isDebugEnabled()) {
LOG.debug("{} tunnel refused", exchangeId);
}
- asyncExecCallback.failed(new TunnelRefusedException("Tunnel refused", null));
+ asyncExecCallback.failed(new TunnelRefusedException("CONNECT refused by proxy: " + new StatusLine(state.tunnelResponse), null));
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("{} tunnel to target created", exchangeId);
@@ -463,7 +464,8 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
state.challenged = false;
if (status >= HttpStatus.SC_REDIRECTION) {
state.tunnelRefused = true;
- entityConsumerRef.set(asyncExecCallback.handleResponse(response, entityDetails));
+ state.tunnelResponse = response;
+ entityConsumerRef.set(null);
} else if (status == HttpStatus.SC_OK) {
asyncExecCallback.completed();
} else {
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ConnectExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ConnectExec.java
index 56fee6aad..cdc8cadbf 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ConnectExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ConnectExec.java
@@ -276,12 +276,9 @@ public final class ConnectExec implements ExecChainHandler {
final int status = response.getCode();
if (status != HttpStatus.SC_OK) {
-
- // Buffer response content
- final HttpEntity entity = response.getEntity();
- final String responseMessage = entity != null ? EntityUtils.toString(entity) : null;
+ EntityUtils.consume(response.getEntity());
execRuntime.disconnectEndpoint();
- throw new TunnelRefusedException("CONNECT refused by proxy: " + new StatusLine(response), responseMessage);
+ throw new TunnelRefusedException("CONNECT refused by proxy: " + new StatusLine(response), null);
}
// How to decide on security of the tunnelled connection?
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ProxyClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ProxyClient.java
index 8b4965cef..38ea03687 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ProxyClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ProxyClient.java
@@ -205,12 +205,9 @@ public class ProxyClient {
final int status = response.getCode();
if (status > 299) {
-
- // Buffer response content
- final HttpEntity entity = response.getEntity();
- final String responseMessage = entity != null ? EntityUtils.toString(entity) : null;
+ EntityUtils.consume(response.getEntity());
conn.close();
- throw new TunnelRefusedException("CONNECT refused by proxy: " + new StatusLine(response), responseMessage);
+ throw new TunnelRefusedException("CONNECT refused by proxy: " + new StatusLine(response), null);
}
return conn.getSocket();
}
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
index e9b9db15d..dd6a0e7fd 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
@@ -218,9 +218,7 @@ public class TestConnectExec {
Mockito.any())).thenReturn(response);
final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, execRuntime, context);
- final TunnelRefusedException exception = Assertions.assertThrows(TunnelRefusedException.class, () ->
- exec.execute(request, scope, execChain));
- Assertions.assertEquals("Ka-boom", exception.getResponseMessage());
+ Assertions.assertThrows(TunnelRefusedException.class, () -> exec.execute(request, scope, execChain));
Mockito.verify(execRuntime, Mockito.atLeastOnce()).disconnectEndpoint();
Mockito.verify(execRuntime).discardEndpoint();
}