I'd like to limit the allowed length of the bodies of incoming HTTP POST requests in my Spring-based Java server application.
Most of these requests contain payloads with content type application/json. However, some of them have other content types, e.g. some controllers receive application/octet-stream from a messaging service.
So far, I had been working with a javax.servlet.Filter, that inspects the content length and rejects any overlong requests:
@Component
@WebFilter(urlPatterns = "my-path/*")
public class Limiter implements Filter {
private static final int MAX_CONTENT_LENGTH_IN_BYTES = 5000;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
int length = servletRequest.getContentLength();
if (length > MAX_CONTENT_LENGTH_IN_BYTES) {
// reject request with HTTP 400 Bad Request
} else {
// let the request pass
}
}
While this works fine for JSON-based contents, it fails for some of the others, esp. the octet-streams. For these cases, getContentLength()
consistently returns -1
. From the Java documentation, I gather that this indicates that the length is unavailable from the input stream.
What's a more reliable way to inspect the content length? Clone the stream, then retrieve it as a string and check the string's length?
Similar questions like Increase HTTP Post maxPostSize in Spring Boot were answered by pointing at settings like spring.servlet.multipart.max-request-size
. We tried all of these and they do not work in our case. These settings are designed for multipart data transfer, where the payload is distributed over multiple requests that are then reassembled by the recipient; they do not apply to single requests. Note also that in the existing questions, users would like to increase the allowed request size. Increasing means they already have a size limit in place that works. In our case, we do not have a working configuration, but want to create one.