Matthias Braun
Matthias Braun

Reputation: 34373

HttpsServer causes 100% CPU load with curl

I've created a minimal application around Java's HttpsServer.

I've installed an HttpHandler that replies to a request with a short text message:

return exchange -> {
    try {
        OutputStream responseBodyStream = exchange.getResponseBody();

        byte[] response = "Trouble with HTTPS and curl\n"
                .getBytes(StandardCharsets.UTF_8);

        exchange.getResponseHeaders().set("Content-Type", "text/plain");

        exchange.sendResponseHeaders(200, response.length);

        responseBodyStream.write(response);

        responseBodyStream.close();

        // Note that exchange.close() also closes the exchange's input stream
        // and output stream

    } catch (Exception e) {
        log.warn("Could not handle request", e);
    }
};

When connecting to the server with curl, the server responds but the Java process keeps using an entire core, thus rendering the server unresponsive.

It's this line that triggers the issue:

responseBodyStream.close();

If we remove the line, the server keeps on working.

From the docs:

In order to correctly terminate each exchange, the output stream must be closed, even if no response body is being sent.

I've created a project to reproduce the issue.

Some potential clues I've found up till now:

I'm on Arch Linux 5.1.7 using OpenJDK 12.0.1+12. The version of curl is 7.65.1.

Is this a bug in the JDK? Or am I using HttpsServer the wrong way?

Upvotes: 6

Views: 2860

Answers (1)

apangin
apangin

Reputation: 98505

I could also reproduce the problem.
There is an infinite loop in SSLStreams.doClosure - this is definitely a JDK bug.

HttpsServer worked fine in JDK 10, but starts looping in JDK 11. I guess the problem is that HttpsServer implementation has not been adapted to TLS v1.3 half-close policy appeared in JDK 11.

Fortunately, there is a workaround. Add -Djdk.tls.acknowledgeCloseNotify=true JVM option. With this option HttpsServer will work as expected. See JDK-8208526 for details.

Upvotes: 7

Related Questions