Bug 68901 - Coyote is hardcoded to drop connections on 400|408|411|414|500|503|501 which should be configurable for application level errors to prevent expensive TLS handshake/resumption on reconnect
Summary: Coyote is hardcoded to drop connections on 400|408|411|414|500|503|501 which ...
Status: NEW
Alias: None
Product: Tomcat 10
Classification: Unclassified
Component: Connectors (show other bugs)
Version: unspecified
Hardware: All Linux
: P2 enhancement with 25 votes (vote)
Target Milestone: ------
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-04-16 09:25 UTC by Alessandro Vermeulen
Modified: 2024-04-16 10:17 UTC (History)
2 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alessandro Vermeulen 2024-04-16 09:25:52 UTC
Overview:

Currently Coyote is hardcoded to drop connections when a request generates a response with one of the following status codes:  400|408|411|414|500|503|501. This behaviour has been around for at least 15 years and has been copied from Apache HTTPd[1]. It makes sense in case the server itself is the origin of the error responses.

However, in our case we have plenty of scenarios we have applications returning generic 500 responses on generic errors, causing connections to drop and subsequent reconnects. Status codes 503 and 501 also seem to cases which should be handled just fine without needing to reset the connection.

We terminate TLS in the application where even session resumption is expensive and a full TLS handshake is even more expensive. 

Together with Tomcat dropping the connections on 500 errors this leads to cascade failures where spurious load-related errors cause a spike in CPU usage which can trigger further errors, further consuming CPU until most CPU is used to handle TLS connections instead of actual value.

We suggest to make the the behaviour to drop connections is configurable. Either to completely disable it, or to make the status codes configurable.

[1]: https://github.com/apache/tomcat/blame/bc900e0100de9879604b93af4722c272ab3d1a24/java/org/apache/coyote/http11/Http11Processor.java#L604-L617
```
    /**
     * Determine if we must drop the connection because of the HTTP status code. Use the same list of codes as
     * Apache/httpd.
     */
    private static boolean statusDropsConnection(int status) {
        return status == 400 /* SC_BAD_REQUEST */ || status == 408 /* SC_REQUEST_TIMEOUT */ ||
                status == 411 /* SC_LENGTH_REQUIRED */ || status == 413 /* SC_REQUEST_ENTITY_TOO_LARGE */ ||
                status == 414 /* SC_REQUEST_URI_TOO_LONG */ || status == 500 /* SC_INTERNAL_SERVER_ERROR */ ||
                status == 503 /* SC_SERVICE_UNAVAILABLE */ || status == 501 /* SC_NOT_IMPLEMENTED */;
    }
```
Comment 1 Michael Osipov 2024-04-16 10:17:34 UTC
I'd like to see this backed by the current RFC if it is a requirement or just the way Tomcat handles it. Also maybe it might be worth to raise the same issue with HTTPd as well.