cloudflare / pingora

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

Response body modification #106

Closed bdolgov closed 3 months ago

bdolgov commented 4 months ago

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

Sometimes the response needs to be changed (for example, to rewrite HTML using cloudflare/lol-html). As far as I understand, the current implementation of pingora-proxy can't support it, because it sends the reponse headers before reading the response (so, for example, Content-Length can't be altered after response body modification). What is the suggested alternative?

Describe the solution you'd like

Have an alternative BufferingHttpProxy implementation which which buffers the whole response body, and uses a different BufferingProxyHttp trait that allows modifying the body.

Another, more flexible option: allow deciding whether a body should be buffered not for the whole proxy server, but per request when the downstream request, upstream request, or upstream response headers are known.

Describe alternatives you've considered

nginx with ngx_http_sub_module, or a custom axum server that proxies using reqwest, or implementing this BufferingHttpProxy myself in a separate crate.

Additional context

n/a

eaufavor commented 4 months ago

Usually in the header filter you remove the content-length header and add Transfer-Encoding: chunked, then you start the body modification. The framework will know to write the body in chunked format.

bdolgov commented 4 months ago

Thanks!

But I also can't really change the body with the existing callbacks: upstream_response_body_filter and response_body_filter both receive immutable reference to the body, and give no way to produce a new body or discard it (unless I am missing something else). Would it be fine to change these callbacks to accept &mut Option<Bytes>?

eaufavor commented 4 months ago

Oh right, I just realized that we have not opened up the body modification. Let me add body modification in the near future. This should be pretty straightforward as a few of our internal filters like (de)compression already works that way.

drcaramelsyrup commented 3 months ago

The body bytes are now mutable in the response filters as of cc32316980371ea5aacf7339d7421f3041c4c505.