Description
Cyril Bonté opened SPR-5338 and commented
Calling UrlResource.exists() on a URL that doesn't exist on the distant HTTP server leaves the connection in CLOSE_WAIT state, which can cause Deny of Service (Too many open files).
the issue is located in this code :
(part of AbstractResource.java)
public boolean exists() {
...
try {
InputStream is = getInputStream();
is.close();
return true;
}
catch (Throwable isEx) {
return false;
}
...
and UrlResource.getInputStream() contains :
public InputStream getInputStream() throws IOException {
URLConnection con = this.url.openConnection();
con.setUseCaches(false);
return con.getInputStream();
}
=> on 404 status (for example), con.getInputStream() throws a FileNotFoundException, so is.close() is not called.
A quick fix could be to override AbstractResource.exists() in UrlResource and not use UrlResource.getInputStream() :
public boolean exists() {
// Try file existence: can we find the file in the file system?
try {
return getFile().exists();
}
catch (IOException ex) {
// Fall back to stream existence: can we open the stream?
try {
URLConnection con = this.url.openConnection();
con.setUseCaches(false);
try {
InputStream is = con.getInputStream();
is.close();
}
catch (Throwable isEx) {
return false;
}
finally {
// Close the HTTP connection
if (con instanceof HttpURLConnection) {
((HttpURLConnection) con).disconnect();
}
}
return true;
}
catch (Throwable conEx) {
return false;
}
}
}
Affects: 2.0.8, 2.5.6
Referenced from: commits d8651a8