Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid Content-Length of incoming request causes to java.util.concurrent.TimeoutException: Idle timeout expired #1862

Open
maistrovyi opened this issue Jun 14, 2024 · 0 comments
Labels

Comments

@maistrovyi
Copy link

maistrovyi commented Jun 14, 2024

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

  1. Create some servlet controller like:
@RestController
@RequestMapping(value = "/api/v1/test")
public class TestController {

    @PostMapping
    String echo(@RequestBody String body) {
        return "echo";
    }
}
  1. 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

@maistrovyi maistrovyi added the Bug label Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant