Skip to content

Commit 345a8fa

Browse files
committed
cap HTTP connection timeout at 20s to prevent DNS/handshake hangs
1 parent df47e90 commit 345a8fa

File tree

3 files changed

+22
-27
lines changed

3 files changed

+22
-27
lines changed

core/src/main/java/lucee/runtime/tag/Http.java

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
**/
145145
public final class Http extends BodyTagImpl {
146146

147+
private static final TimeSpan MAX_CONN_TIMEOUT_MS = TimeSpanImpl.fromMillis(20000L);
147148
public static final String MULTIPART_RELATED = "multipart/related";
148149
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
149150

@@ -955,8 +956,7 @@ else if (type == HttpParamBean.TYPE_CGI) {
955956
else if (type == HttpParamBean.TYPE_HEADER) {
956957
if (param.getName().equalsIgnoreCase("content-type")) hasContentType = true;
957958

958-
if (param.getName().equalsIgnoreCase("Content-Length")) {
959-
}
959+
if (param.getName().equalsIgnoreCase("Content-Length")) {}
960960
else if (param.getName().equalsIgnoreCase("Accept-Encoding")) {
961961
acceptEncoding.append(headerValue(param.getValueAsString()));
962962
acceptEncoding.append(", ");
@@ -1850,8 +1850,7 @@ public static Object getOutput(InputStream is, String contentType, String conten
18501850
try {
18511851
is = new GZIPInputStream(is);
18521852
}
1853-
catch (IOException e) {
1854-
}
1853+
catch (IOException e) {}
18551854
}
18561855

18571856
try {
@@ -1863,16 +1862,14 @@ public static Object getOutput(InputStream is, String contentType, String conten
18631862
try {
18641863
return IOUtil.toString(is, cs);
18651864
}
1866-
catch (IOException e) {
1867-
}
1865+
catch (IOException e) {}
18681866
}
18691867
// Binary
18701868
else {
18711869
try {
18721870
return IOUtil.toBytes(is);
18731871
}
1874-
catch (IOException e) {
1875-
}
1872+
catch (IOException e) {}
18761873
}
18771874
}
18781875
finally {
@@ -1921,29 +1918,27 @@ public static void setTimeout(HttpClientBuilder builder, TimeSpan timeout) {
19211918

19221919
private static void setTimeout(Http http, HttpClientBuilder builder, TimeSpan timeout, TimeSpan connectionTimeout, TimeSpan socketTimeout) {
19231920

1924-
// timeout is only of interest if we miss the others
1925-
if (connectionTimeout == null && timeout != null) connectionTimeout = timeout;
1926-
if (socketTimeout == null && timeout != null) socketTimeout = timeout;
1921+
// . Resolve Connection Timeout
1922+
if (connectionTimeout == null) connectionTimeout = timeout;
1923+
1924+
// Apply the ceiling: Use the smaller of the requested timeout or the 20s cap
1925+
if (connectionTimeout == null || connectionTimeout.getMillis() > MAX_CONN_TIMEOUT_MS.getMillis() || connectionTimeout.getMillis() <= 0) {
1926+
connectionTimeout = MAX_CONN_TIMEOUT_MS;
1927+
}
1928+
1929+
// 2. Resolve Socket/Read Timeout
1930+
if (socketTimeout == null) socketTimeout = timeout;
1931+
1932+
// Update the Http object for logging accuracy
19271933
if (http != null) {
19281934
http.timeout = timeout;
19291935
http.connectionTimeout = connectionTimeout;
19301936
http.socketTimeout = socketTimeout;
19311937
}
19321938

1933-
Builder b = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD);
1934-
1935-
// connection timeout
1936-
if ((connectionTimeout != null && connectionTimeout.getMillis() > 0)) {
1937-
int ms = (int) connectionTimeout.getMillis();
1938-
if (ms < 0) ms = Integer.MAX_VALUE;
1939-
b = b.setConnectionRequestTimeout(ms).setConnectTimeout(ms);
1940-
}
1941-
// socket timeout
1942-
if ((socketTimeout != null && socketTimeout.getMillis() > 0)) {
1943-
int ms = (int) socketTimeout.getMillis();
1944-
if (ms < 0) ms = Integer.MAX_VALUE;
1945-
b = b.setSocketTimeout(ms);
1946-
}
1939+
// Build the config - .getMillis() returns the int we need
1940+
Builder b = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).setConnectTimeout((int) connectionTimeout.getMillis())
1941+
.setConnectionRequestTimeout((int) connectionTimeout.getMillis()).setSocketTimeout(socketTimeout != null ? (int) socketTimeout.getMillis() : 0);
19471942

19481943
builder.setDefaultRequestConfig(b.build());
19491944
}

loader/build.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<project default="core" basedir="." name="Lucee"
33
xmlns:resolver="antlib:org.apache.maven.resolver.ant">
44

5-
<property name="version" value="7.0.2.88-SNAPSHOT"/>
5+
<property name="version" value="7.0.2.89-SNAPSHOT"/>
66

77
<taskdef uri="antlib:org.apache.maven.resolver.ant" resource="org/apache/maven/resolver/ant/antlib.xml">
88
<classpath>

loader/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
<groupId>org.lucee</groupId>
55
<artifactId>lucee</artifactId>
6-
<version>7.0.2.88-SNAPSHOT</version>
6+
<version>7.0.2.89-SNAPSHOT</version>
77
<packaging>jar</packaging>
88

99
<name>Lucee Loader Build</name>

0 commit comments

Comments
 (0)