You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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;
}
}
}
Well, I wrote the fix very quickly, a simpler solution can be :
public InputStream getInputStream() throws IOException {
URLConnection con = this.url.openConnection();
con.setUseCaches(false);
try {
return con.getInputStream();
}
catch (Throwable isEx) {
// Close the HTTP connection
if (con instanceof HttpURLConnection) {
((HttpURLConnection) con).disconnect();
}
throw isEx;
}
}
This should fix all portions of code using UrlResource.getInputStream()
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
The text was updated successfully, but these errors were encountered: