Skip to content

ContentCachingResponseWrapper should NOT sendError() before write body [SPR-13004] #17596

@spring-projects-issues

Description

@spring-projects-issues

Victor Lyuboslavsky opened SPR-13004 and commented

The fix for #16327 does not work with Tomcat 8.0.21

public void sendError(int sc, String msg) throws IOException {
     copyBodyToResponse();
     super.sendError(sc, msg);
     this.statusCode = sc;
}

When copyBodyToResponse() is called, Tomcat considers the response committed. Then, when sendError is called, Tomcat throws

org.glassfish.jersey.server.ServerRuntime$Responder - Error while closing the output stream in order to commit response.
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
	at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:462)
	at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:120)
	at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:120)
	at org.springframework.web.util.ContentCachingResponseWrapper.sendError(ContentCachingResponseWrapper.java:83)

Tomcat considers the response committed because contentLength is more than 0, and it is the same as contentWritten. From org/apache/catalina/connector/Response.java:

public boolean isAppCommitted() {
    return (this.appCommitted || isCommitted() || isSuspended()
            || ((getContentLength() > 0)
                && (getContentWritten() >= getContentLength())));
}

I propose that whenever content length > 0, sendError should not be called.

My current workaround:

public class BackendContentCachingResponseWrapper extends ContentCachingResponseWrapper {

    public BackendContentCachingResponseWrapper(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void sendError(int sc, String msg) throws IOException {
        try {
            super.sendError(sc, msg);
        } catch (IllegalStateException e) {
            // ignore
        }
    }

}

Affects: 4.1.6

Issue Links:

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions