spring-cloud / spring-cloud/spring-cloud-gateway
Use part of the request body for routing, but don't load the whole request into RAM
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
Is your feature request related to a problem? Please describe.
I have a case where I want to read the first X bytes from the request and route to a different host depending on the value read.
I know that you can accomplish what I'm doing by caching the request using ServerWebExchangeUtils.cacheRequestBody() and then reading the bytes from the cached DataBuffer.
But in my case, multiple HTTP clients could send requests with 250 MB of data or more. If I don't limit the DirectMemory, the process will be killed by my cgroup RAM limit. If I limit the DirectMemory, new requests will get HTTP 500 responses stating that there's not enough memory.
I tried to solve the problem by using DataBufferUtils.takeUntilByteCount() without caching, but then either the request is forwarded without a body since the Producer of the data already sent everything or an error is thrown that 2 subscribers can't listen to the same request Flux.
Describe the solution you'd like
This probably goes against the principles of reactive programming, but is there some way to stop the request producer midway and to produce a new Flux which repeats the first few DataBuffers which were read in the custom GatewayFilter and then adds the rest of the outstanding DataBuffers?
Additional context
I've read about ModifyRequestBodyGatewayFilterFactory and ReadBodyPredicateFactory and both of them rely on reading the whole request body into an Object.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ModifyRequestBodyGatewayFilterFactory and ReadBodyPredicateFactory, then compare them with the custom GatewayFilter and DataBufferUtils.takeUntilByteCount() described in the issue. Determine whether the first few request bytes can guide routing without buffering the full body, while preserving the remaining body for forwarding and avoiding multiple subscriptions. Done means large requests are not fully loaded into RAM and the forwarded request retains its body.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100