Q:

Why does com.sun.net.httpserver.HttpServer hang?

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.

A:

Why different behaviour for proxy & no proxy?

more connections with no proxy
real-world browser users can do funny things, like start a request and then cancel/back button/new request.

You need to set a socket timeout.  Unfortunately, the API documentation suggests no way to do so programmatically.  
But you can set resquest & response timeouts via JVM system properties:
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
http://bugs.sun.com/bugdatabase/view_bug.do?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(); 

