cloudflare / pingora

A library for building fast, reliable and evolvable network services.
Apache License 2.0
20.64k stars 1.12k forks source link

Read full body from downstream before proxying to upstream #67

Closed farico closed 2 months ago

farico commented 5 months ago

What is the problem your feature solves, or the need it fulfills?

When building a API gateway sometimes we need to modify the body - for example request to gateway is sent as JSON, but service accepts it as protobuf hence the need to fully read the body, deserialize json, build proto message and send it upstream.

Describe the solution you'd like

Provide an implementation that allows to fully read request from downstream and apply a body filter.

Describe alternatives you've considered

Using reqwest or hyper

Additional context

None

pathak1515 commented 5 months ago

For an API gateway, it is generally recommended to not read request body unless there is a peculiar requirement to support usecases. API Gateways are typically designed to handle routing, authentication, authorization, rate limiting, and other cross-cutting concerns at the entry point. Also modifying the request body at the gateway could introduce security risk.

farico commented 5 months ago

Thank you for the input - it makes a lot of sense! However this feature request was created in order to address such use case:

  1. receive request as JSON
  2. convert request to protobuf (and add some extra values if needed)
  3. send it to upstream

Hence the need to read the body fully.

github2023spring commented 2 months ago

seems like this issue can be closed with #246?

janbraunsdorff commented 2 months ago

Hey :) thank you for this awsome work. i tried a simmilar usecase. But I get an error based on Content Length.

My body from downstream ist for example 1024 bytes. The header contains "content-length: 1024". After body modification in request_body_filter is the length of the body 980 bytes. Obviously upstream throws an error, because of missing bytes. But when I update the header in connected_to_upstream to the new content-length, I get from down only 980 bytes and not all 1024. Where and when should I update the content length header?

eaufavor commented 2 months ago

If you know the body size ahead of the time (before you send the request header), you can change the content-length in the upstream_request_filter. If not, you should change the content-encoding to chunked and remove the content-length header.

See a similar example here https://github.com/cloudflare/pingora/blob/main/pingora-proxy/examples/modify_response.rs

janbraunsdorff commented 2 months ago

@eaufavor Thank you for your quick response. It works as aspected :) I only messed up a little bit too much.