servlet
servlet copied to clipboard
Provide a way to abort a response and close the underlying connection
In the context of writing a reverse proxy using the Servlet API, this situation may happen:
- The proxy proxies the request from client to server.
- The server replies with headers and partial content
- The proxy receives the headers and the partial content from the server, and relays both to the client; in doing so, the response from proxy to client is committed.
- The server stops sending data.
- The proxy times out the exchange with the server.
- At this point, the proxy must signal to the client that something went wrong with the server; however, the proxy-to-client response is already committed, so the proxy must just abruptly close the connection.
There is no standard Servlet API to perform this abrupt close.
Closing the ServletOutputStream would probably just finish to send buffered data (or the terminator chunk in case of chunked content), which is not good as the client may think to have received the whole content, so it's not a viable solution.
There is a real need to close the connection, but the proxy cannot add Connection:close since the response is already committed.
In case of synchronous handling, the proxy may throw an exception, which would be interpreted by the Servlet Container as an indication to close the connection, but this solution does not work in the asynchronous case, where an external thread is writing the failure to the client.
A new API for this functionality should be added, covering both the synchronous case and the asynchronous case, for example:
// Fail the response to the client. HttpServletResponse response = ...;
if (response.isCommitted())
{
response.abort(); // <-- new API
asyncContext.complete();
}
else
{
response.resetBuffer();
response.setStatus(503);
response.setHeader("Connection", "close");
asyncContext.complete();
}
- Issue Imported From: https://github.com/javaee/servlet-spec/issues/98
- Original Issue Raised By:@glassfishrobot
- Original Issue Assigned To: @glassfishrobot
@glassfishrobot Commented Reported by simonebordet
@glassfishrobot Commented gregwilkins said: This could potentially be achieved by specifying that abrupt close is the defined action if sendError is called on a committed response. The example code then just becomes:
// Fail the response to the client. HttpServletResponse response = ...; try
{response.sendError(503);}
finally
{asyncContext.complete();}
@glassfishrobot Commented markt_asf said: +1 to sendError() on a committed response triggering an abrupt close. This is what Tomcat does currently.
@glassfishrobot Commented This issue was imported from java.net JIRA SERVLET_SPEC-98
Is there any hope for a progress on this issue? Something like AsyncContext.fail(cause)?
I don't think Tomcat actually allows response.sendError on a committed response as mentioned above. The code looks like
public void sendError(int status, String message) throws IOException {
if (isCommitted()) {
throw new IllegalStateException
(sm.getString("coyoteResponse.sendError.ise"));
}