Skip to content

Commit 5ee88fb

Browse files
Martin-Wegnerdsmiley
Martin-Wegner
authored andcommitted
Setting the read timeout in the RequestConfig is not enough. (mitre#150)
* Setting the read timeout in the RequectConfig is not enough. The read timeout must be set in the SocketConfig as well. Setting the read timeout only in the RequestConfig can cause hangs which could block the whole proxy forever. * SoTimeout cannot be negative -> -1 must be interpreted as 0 * add SocketConfig parameter to getProxyClient() Javadoc * refactor createHttpClient(RequestConfig, SocketConfig) to createHttpClient() and do not create a customized socket configuration if no read timeout is set * add change description for mitre#150
1 parent 3bcd879 commit 5ee88fb

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

CHANGES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44
\#151: Copy `HttpOnly` flag of proxy coookie to request clients, for fixing security vulnerabilities in cookies.
55
This also updates `javax.servlet-api` to `v3.0.1`.
66

7+
\#150 Setting the read timeout in the `RequestConfig` is not enough.
8+
The read timeout must be set in the `SocketConfig` as well.
9+
Setting the read timeout only in the `RequestConfig` can cause hangs which could
10+
block the whole proxy forever.
11+
Attention: Method signature of `createHttpClient(RequestConfig)` changed to
12+
`createHttpClient()`.
13+
Please override `buildRequestConfig()` and `buildSocketConfig()` to configure the
14+
Apache HttpClient.
15+
Thanks Martin Wegner.
16+
717
\#139: Use Java system properties for http proxy (and other settings) by default.
818
This is a regression; it used to work this way in 1.8 and prior.
919
Thanks Thorsten Möller.

src/main/java/org/mitre/dsmiley/httpproxy/ProxyServlet.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.http.client.config.RequestConfig;
2929
import org.apache.http.client.methods.AbortableHttpRequest;
3030
import org.apache.http.client.utils.URIUtils;
31+
import org.apache.http.config.SocketConfig;
3132
import org.apache.http.entity.InputStreamEntity;
3233
import org.apache.http.impl.client.HttpClientBuilder;
3334
import org.apache.http.message.BasicHeader;
@@ -49,7 +50,6 @@
4950
import java.util.BitSet;
5051
import java.util.Enumeration;
5152
import java.util.Formatter;
52-
import java.util.List;
5353

5454
/**
5555
* An HTTP reverse proxy/gateway servlet. It is designed to be extended for customization
@@ -91,10 +91,10 @@ public class ProxyServlet extends HttpServlet {
9191

9292
/** A integer parameter name to set the socket read timeout (millis) */
9393
public static final String P_READTIMEOUT = "http.read.timeout";
94-
94+
9595
/** A boolean parameter whether to use JVM-defined system properties to configure various networking aspects. */
9696
public static final String P_USESYSTEMPROPERTIES = "useSystemProperties";
97-
97+
9898
/** The parameter name for the target (destination) URI to proxy to. */
9999
protected static final String P_TARGET_URI = "targetUri";
100100
protected static final String ATTR_TARGET_URI =
@@ -177,7 +177,7 @@ public void init() throws ServletException {
177177
if (connectTimeoutString != null) {
178178
this.connectTimeout = Integer.parseInt(connectTimeoutString);
179179
}
180-
180+
181181
String readTimeoutString = getConfigParam(P_READTIMEOUT);
182182
if (readTimeoutString != null) {
183183
this.readTimeout = Integer.parseInt(readTimeoutString);
@@ -190,7 +190,7 @@ public void init() throws ServletException {
190190

191191
initTarget();//sets target*
192192

193-
proxyClient = createHttpClient(buildRequestConfig());
193+
proxyClient = createHttpClient();
194194
}
195195

196196
/**
@@ -205,6 +205,20 @@ protected RequestConfig buildRequestConfig() {
205205
.build();
206206
}
207207

208+
/**
209+
* Sub-classes can override specific behaviour of {@link org.apache.http.config.SocketConfig}.
210+
*/
211+
protected SocketConfig buildSocketConfig() {
212+
213+
if (readTimeout < 1) {
214+
return null;
215+
}
216+
217+
return SocketConfig.custom()
218+
.setSoTimeout(readTimeout)
219+
.build();
220+
}
221+
208222
protected void initTarget() throws ServletException {
209223
targetUri = getConfigParam(P_TARGET_URI);
210224
if (targetUri == null)
@@ -223,16 +237,18 @@ protected void initTarget() throws ServletException {
223237
* HttpClient offers many opportunities for customization.
224238
* In any case, it should be thread-safe.
225239
*/
226-
protected HttpClient createHttpClient(final RequestConfig requestConfig) {
227-
HttpClientBuilder clientBuilder = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig);
240+
protected HttpClient createHttpClient() {
241+
HttpClientBuilder clientBuilder = HttpClientBuilder.create()
242+
.setDefaultRequestConfig(buildRequestConfig())
243+
.setDefaultSocketConfig(buildSocketConfig());
228244
if (useSystemProperties)
229245
clientBuilder = clientBuilder.useSystemProperties();
230246
return clientBuilder.build();
231247
}
232248

233249
/**
234250
* The http client used.
235-
* @see #createHttpClient(RequestConfig)
251+
* @see #createHttpClient()
236252
*/
237253
protected HttpClient getProxyClient() {
238254
return proxyClient;
@@ -392,8 +408,8 @@ protected void closeQuietly(Closeable closeable) {
392408
}
393409
}
394410

395-
/**
396-
* Copy request headers from the servlet client to the proxy request.
411+
/**
412+
* Copy request headers from the servlet client to the proxy request.
397413
* This is easily overridden to add your own.
398414
*/
399415
protected void copyRequestHeaders(HttpServletRequest servletRequest, HttpRequest proxyRequest) {

0 commit comments

Comments
 (0)