Skip to content

Commit 94b0eab

Browse files
author
Vitaly Dyachkov
committed
Http connection are not released to the pool when exception
Fix for an issue #1308
1 parent e2eb047 commit 94b0eab

File tree

1 file changed

+102
-90
lines changed

1 file changed

+102
-90
lines changed

geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSHttpHelper.java

Lines changed: 102 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.hc.client5.http.classic.methods.HttpPost;
3434
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
3535
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
36+
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
3637
import org.apache.hc.core5.http.ClassicHttpResponse;
3738
import org.apache.hc.core5.http.HttpException;
3839
import org.apache.hc.core5.http.NameValuePair;
@@ -239,106 +240,117 @@ private void connectAndCheckHeaders(
239240
ClassicHttpResponse method = null;
240241
final int responseCode;
241242
int responseLength = 0;
242-
243243
try {
244-
method = executeRequest(wmsBackendUrl, wmsParams, backendTimeout, httpRequestMode);
245-
responseCode = method.getCode();
246-
if (responseCode == 200) {
247-
if (method.getFirstHeader("length") != null) {
248-
responseLength =
249-
Integer.parseInt(method.getFirstHeader("length").getValue());
250-
} else if (method.getFirstHeader("Content-Length") != null) {
251-
responseLength = Integer.parseInt(
252-
method.getFirstHeader("Content-Length").getValue());
253-
} else if (method.getEntity() != null) {
254-
responseLength = Math.toIntExact(method.getEntity().getContentLength());
255-
} else {
256-
throw new ServiceException("Unable to determine response length from: " + wmsBackendUrl.toString());
244+
try {
245+
method = executeRequest(wmsBackendUrl, wmsParams, backendTimeout, httpRequestMode);
246+
responseCode = method.getCode();
247+
if (responseCode == 200) {
248+
if (method.getFirstHeader("length") != null) {
249+
responseLength =
250+
Integer.parseInt(method.getFirstHeader("length").getValue());
251+
} else if (method.getFirstHeader("Content-Length") != null) {
252+
responseLength = Integer.parseInt(
253+
method.getFirstHeader("Content-Length").getValue());
254+
} else if (method.getEntity() != null) {
255+
responseLength = Math.toIntExact(method.getEntity().getContentLength());
256+
} else {
257+
throw new ServiceException("Unable to determine response length from: " + wmsBackendUrl.toString());
258+
}
257259
}
260+
// Do not set error at this stage
261+
} catch (IOException ce) {
262+
if (log.isLoggable(Level.FINE)) {
263+
String message = "Error forwarding request " + wmsBackendUrl.toString();
264+
log.log(Level.FINE, message, ce);
265+
}
266+
throw new GeoWebCacheException(ce);
258267
}
259-
// Do not set error at this stage
260-
} catch (IOException ce) {
261-
if (log.isLoggable(Level.FINE)) {
262-
String message = "Error forwarding request " + wmsBackendUrl.toString();
263-
log.log(Level.FINE, message, ce);
268+
// Check that the response code is okay
269+
tileRespRecv.setStatus(responseCode);
270+
if (responseCode != 200 && responseCode != 204) {
271+
tileRespRecv.setError();
272+
throw new ServiceException(
273+
"Unexpected response code from backend: " + responseCode + " for " + wmsBackendUrl.toString());
264274
}
265-
throw new GeoWebCacheException(ce);
266-
}
267-
// Check that the response code is okay
268-
tileRespRecv.setStatus(responseCode);
269-
if (responseCode != 200 && responseCode != 204) {
270-
tileRespRecv.setError();
271-
throw new ServiceException(
272-
"Unexpected response code from backend: " + responseCode + " for " + wmsBackendUrl.toString());
273-
}
274-
275-
// Check that we're not getting an error MIME back.
276-
String responseMime = method.getFirstHeader("Content-Type").getValue();
277-
if (responseCode != 204 && responseMime != null && !requestMimeType.isCompatible(responseMime)) {
278-
String message = null;
279-
if (responseMime.equalsIgnoreCase(ErrorMime.vnd_ogc_se_inimage.getFormat())) {
280-
// TODO: revisit: I don't understand why it's trying to create a String message
281-
// out of an ogc_se_inimage response?
282-
283-
try (InputStream stream = method.getEntity().getContent()) {
284-
byte[] error = IOUtils.toByteArray(stream);
285-
message = new String(error);
286-
} catch (IOException ioe) {
287-
// Do nothing
288-
}
289-
} else if (responseMime != null && responseMime.toLowerCase().startsWith("application/vnd.ogc.se_xml")) {
290-
try (InputStream stream = method.getEntity().getContent()) {
291-
message = IOUtils.toString(stream, StandardCharsets.UTF_8);
292-
} catch (IOException e) {
293-
//
275+
276+
// Check that we're not getting an error MIME back.
277+
String responseMime = method.getFirstHeader("Content-Type").getValue();
278+
if (responseCode != 204 && responseMime != null && !requestMimeType.isCompatible(responseMime)) {
279+
String message = null;
280+
if (responseMime.equalsIgnoreCase(ErrorMime.vnd_ogc_se_inimage.getFormat())) {
281+
// TODO: revisit: I don't understand why it's trying to create a String message
282+
// out of an ogc_se_inimage response?
283+
284+
try (InputStream stream = method.getEntity().getContent()) {
285+
byte[] error = IOUtils.toByteArray(stream);
286+
message = new String(error);
287+
} catch (IOException ioe) {
288+
// Do nothing
289+
}
290+
} else if (responseMime != null && responseMime.toLowerCase().startsWith("application/vnd.ogc.se_xml")) {
291+
try (InputStream stream = method.getEntity().getContent()) {
292+
message = IOUtils.toString(stream, StandardCharsets.UTF_8);
293+
} catch (IOException e) {
294+
//
295+
}
294296
}
297+
String msg = "MimeType mismatch, expected "
298+
+ requestMimeType
299+
+ " but got "
300+
+ responseMime
301+
+ " from "
302+
+ wmsBackendUrl.toString()
303+
+ (message == null ? "" : (":\n" + message));
304+
tileRespRecv.setError();
305+
tileRespRecv.setErrorMessage(msg);
306+
log.warning(msg);
295307
}
296-
String msg = "MimeType mismatch, expected "
297-
+ requestMimeType
298-
+ " but got "
299-
+ responseMime
300-
+ " from "
301-
+ wmsBackendUrl.toString()
302-
+ (message == null ? "" : (":\n" + message));
303-
tileRespRecv.setError();
304-
tileRespRecv.setErrorMessage(msg);
305-
log.warning(msg);
306-
}
307-
308-
// Everything looks okay, try to save expiration
309-
if (tileRespRecv.getExpiresHeader() == GWCVars.CACHE_USE_WMS_BACKEND_VALUE) {
310-
String expireValue = method.getFirstHeader("Expires").getValue();
311-
long expire = ServletUtils.parseExpiresHeader(expireValue);
312-
if (expire != -1) {
313-
tileRespRecv.setExpiresHeader(expire / 1000);
308+
309+
// Everything looks okay, try to save expiration
310+
if (tileRespRecv.getExpiresHeader() == GWCVars.CACHE_USE_WMS_BACKEND_VALUE) {
311+
String expireValue = method.getFirstHeader("Expires").getValue();
312+
long expire = ServletUtils.parseExpiresHeader(expireValue);
313+
if (expire != -1) {
314+
tileRespRecv.setExpiresHeader(expire / 1000);
315+
}
314316
}
315-
}
316-
317-
// Read the actual data
318-
if (responseCode != 204) {
319-
try (InputStream inStream = method.getEntity().getContent()) {
320-
if (inStream == null) {
321-
log.severe("No response for " + method);
322-
} else {
323-
try (ReadableByteChannel channel = Channels.newChannel(inStream)) {
324-
target.transferFrom(channel);
317+
318+
// Read the actual data
319+
if (responseCode != 204) {
320+
try (InputStream inStream = method.getEntity().getContent()) {
321+
if (inStream == null) {
322+
log.severe("No response for " + method);
323+
} else {
324+
try (ReadableByteChannel channel = Channels.newChannel(inStream)) {
325+
target.transferFrom(channel);
326+
}
325327
}
326-
}
327-
if (responseLength > 0) {
328-
int readAccu = (int) target.getSize();
329-
if (readAccu != responseLength) {
330-
tileRespRecv.setError();
331-
throw new GeoWebCacheException("Responseheader advertised "
332-
+ responseLength
333-
+ " bytes, but only received "
334-
+ readAccu
335-
+ " from "
336-
+ wmsBackendUrl.toString());
328+
if (responseLength > 0) {
329+
int readAccu = (int) target.getSize();
330+
if (readAccu != responseLength) {
331+
tileRespRecv.setError();
332+
throw new GeoWebCacheException("Responseheader advertised "
333+
+ responseLength
334+
+ " bytes, but only received "
335+
+ readAccu
336+
+ " from "
337+
+ wmsBackendUrl.toString());
338+
}
337339
}
340+
} catch (IOException ioe) {
341+
tileRespRecv.setError();
342+
log.severe("Caught IO exception, " + wmsBackendUrl.toString() + " " + ioe.getMessage());
343+
}
344+
}
345+
} finally {
346+
347+
// Guarantees that connections are released to the pool
348+
if (method != null && method instanceof CloseableHttpResponse) {
349+
try {
350+
((CloseableHttpResponse) method).close();
351+
} catch (IOException e) {
352+
e.printStackTrace();
338353
}
339-
} catch (IOException ioe) {
340-
tileRespRecv.setError();
341-
log.severe("Caught IO exception, " + wmsBackendUrl.toString() + " " + ioe.getMessage());
342354
}
343355
}
344356
}

0 commit comments

Comments
 (0)