Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AbstractResource.exists() doesn't close connection correctly on a not found http url [SPR-5338] #10011

Closed
spring-projects-issues opened this issue Dec 3, 2008 · 2 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

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

@spring-projects-issues
Copy link
Collaborator Author

Cyril Bonté commented

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()

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Thanks for pointing this out! Fixed as of 3.0 M2.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants