Invalid `Content-Length` of incoming request causes to java.util.concurrent.TimeoutException: Idle timeout expired
maistrovyi opened this issue · 1 comments
if you send Content-Length
header value longer than request body actually is - java.util.concurrent.TimeoutException: Idle timeout expired will be thrown.
Description
It is clear that this is initially the client's problem if they send an invalid Content-Length
and of course, it's clear that when we tell the server I'm sending you 10 bytes but send only 6, it expects 4 more until the end of the timeout, but the problem appears only if there is a Logbook dependency (which is logical due to buffering request), without it everything works fine.
So maybe the problem here is more conceptual, like we need to support new behavior for the new org.zalando.logbook.servlet.FormRequestMode
?
Expected Behavior
Request handled normally
Actual Behavior
java.io.IOException: java.util.concurrent.TimeoutException: Idle timeout expired: 30005/30000 ms
at org.eclipse.jetty.ee10.servlet.HttpInput.read(HttpInput.java:267)
at org.eclipse.jetty.ee10.servlet.HttpInput.read(HttpInput.java:225)
at java.base/java.io.InputStream.read(InputStream.java:220)
at org.zalando.logbook.servlet.ByteStreams.copy(ByteStreams.java:27)
at org.zalando.logbook.servlet.ByteStreams.toByteArray(ByteStreams.java:17)
at org.zalando.logbook.servlet.RemoteRequest$Offering.buffer(RemoteRequest.java:110)
at org.zalando.logbook.servlet.RemoteRequest.lambda$buffer$0(RemoteRequest.java:309)
at org.zalando.fauxpas.ThrowingFunction.apply(ThrowingFunction.java:19)
at java.base/java.util.concurrent.atomic.AtomicReference.updateAndGet(AtomicReference.java:210)
at org.zalando.logbook.servlet.RemoteRequest.buffer(RemoteRequest.java:308)
at org.zalando.logbook.servlet.RemoteRequest.getBody(RemoteRequest.java:286)
at org.zalando.logbook.HttpMessage.getBodyAsString(HttpMessage.java:44)
...
Possible Fix
Check content-length and compare with request.getInputStream().available()
?
Steps to Reproduce
- Create some servlet controller like:
@RestController
@RequestMapping(value = "/api/v1/test")
public class TestController {
@PostMapping
String echo(@RequestBody String body) {
return "echo";
}
}
- Make curl with invalid
Content-Length
header like:
curl --location 'http://localhost:8080/api/v1/test' --request POST \
--header 'Content-Type: application/json' \
--header 'Content-Length: 584' \
--data 'some-string'
Context
After Logbook introducing - the client's requests started to fall.
Your Environment
2.7.* spring boot and 2.16 logbook, Jetty/Tomcat
3.2.* spring boot and 3.9 logbook, Jetty/Tomcat