I'm using com.sun.net.httpserver.HttpServer in my project. However, it seems that the server leaks connections when it gets invalid data from the HTTP connection. The bug is this one:
http://bugs.sun.com/view_bug.do;jsessionid=dfe841c3152d878571573bafceb8?bug_id=6946825
Now, this is reported to be fixed in version "7(b94)" - however, we are still using Java 1.6 and it is unlikely that we would want switch Java versions at this point.
So, I am looking for ways to fix this situation. I don't have a lot of time, so I'd prefer quick solutions that work for now, over reimplementing a lot of things for later.
I have a few ideas on how to go about this:
- Update to a more recent Java - this is something I don't want to do.
- Find a jar which only contains a more recent version of com.sun.net.httpserver and make sure that jar loads before the system jars.
- Find a drop-in replacement for com.sun.net.httpserver - I'm open to pointers here.
- Modify code to work with another embedded HTTP server, hopefully one that isn't too different from the current one. I can rewrite the server setup code, somewhat, but most of the interfaces should stay the same.
- Decompile the com.sun.net.httpserver.ServerImpl class, fix the offending places, and recompile that single class to a jar of it's own
But, I'm open to good suggestions!
Thank you in advance.
Fix is now implemented and works. I will paste here the relevant bits if anyone else needs these:
final Field httpserverimpl_server = Class.forName("sun.net.httpserver.HttpServerImpl").getDeclaredField("server");
final Field httpsserverimpl_server = Class.forName("sun.net.httpserver.HttpsServerImpl").getDeclaredField("server");
final Field serverimpl_allconnections = Class.forName("sun.net.httpserver.ServerImpl").getDeclaredField("allConnections");
final Field httpconnection_closed = Class.forName("sun.net.httpserver.HttpConnection").getDeclaredField("closed");
httpserverimpl_server.setAccessible(true);
httpsserverimpl_server.setAccessible(true);
serverimpl_allconnections.setAccessible(true);
httpconnection_closed.setAccessible(true);
Object serverimpl = httpserverimpl_server.get(server);
Set allconnections = (Set)serverimpl_allconnections.get(serverimpl);
LinkedList<Object> toRemove = new LinkedList<Object>();
for (Object conn : allconnections) {
if (httpconnection_closed.getBoolean(conn)) {
toRemove.add(conn);
}
}
for (Object conn : toRemove) {
allconnections.remove(conn);
}