When my simple HTTPS server implemented using com.sun.net.httpserver.HttpServer
is called via this PHP proxy (which uses curl), it works fine. But as soon as I don't use the proxy but change my web form so that browsers directly send their requests to the server, the server becomes unstable and sometimes stops responding. The client will then wait for a response until it times out. The problem is difficult to reproduce and sometimes happens after hours in the live system. All of this is via HTTPS, on a non-standard port (currently 8081). My server returns XML.
The stacktrace I see when the server doesn't respond anymore (via "kill -QUIT [pid]
"):
"Thread-2" prio=10 tid=0x0000000017fc4800 nid=0x1c2b runnable
[0x00002ba5ec97c000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:218)
at sun.nio.ch.IOUtil.read(IOUtil.java:191)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:359)
- locked <0x00000000fd1e4b98> (a java.lang.Object)
at sun.net.httpserver.SSLStreams$EngineWrapper.recvAndUnwrap(SSLStreams.java:334)
- locked <0x00000000fd1e4c58> (a java.lang.Object)
at sun.net.httpserver.SSLStreams.recvData(SSLStreams.java:409)
at sun.net.httpserver.SSLStreams$InputStream.read(SSLStreams.java:524)
at sun.net.httpserver.SSLStreams$InputStream.read(SSLStreams.java:593)
at sun.net.httpserver.Request.readLine(Request.java:84)
at sun.net.httpserver.Request.<init>(Request.java:54)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:529)
at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:156)
at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:424)
at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:389)
at java.lang.Thread.run(Thread.java:722)
What I already tried: Sending a Connection: close
http header - didn't help. Writing a Java test case that uses multiple threads to query the server in parallel - works fine.
So the questions is: what do browsers do different than my proxy, and why does that make my server process hang?
Source: here's the source of the HttpHandler and here's the source of the Server that uses that handler
Background: I want anybody to be able to use my REST service from their web page, without installing a proxy (needed to circumvent the Javascript cross-origin policy). For that, the server sends an Access-Control-Allow-Origin: *
header. I'm using the classes provided by Java to have minimal overhead compared to Jetty or Tomcat Embedded.
You need to set a socket timeout. Unfortunately, the API documentation suggests no way to do so programmatically.
http://www.javaworld.com/community/node/8424
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/net/httpserver/ServerConfig.java
https://bugs.java.com/bugdatabase/view_bug?bug_id=6563368
Set these system properties:
sun.net.httpserver.clockTick
Default value = 10000 i.e. 10 sec
sun.net.httpserver.timerMillis
Default value = 1000 i.e. 1 sec
sun.net.httpserver.maxReqTime
Default value = -1 i.e. forever.
A default > 0 gives timeout = default * (either clockTick ot timerMillis) sec
sun.net.httpserver.maxRspTime
Default value = -1 i.e. forever.
A default > 0 gives timeout = default * (either clockTick ot timerMillis) sec
Obviously, in your HttpHandler.handle() method, make sure you set the response code in the response headers:
httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length());
final OutputStream os = httpExchange.getResponseBody();
os.write( response.getBytes() );
os.close();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With