cloudflare / cloudflare/pingora

response_body_filter not called after overriding 204/304 status in response_filter

Open
#852 5 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
27.4k
Forks
1.7k
Avg merge
6h 22m
Merged PRs (30d)
3

Description

## Describe the bug

When a proxy overrides a 204 or 304 status code to 200 in `response_filter`, `response_body_filter` is never called, making it impossible to inject a synthesized body.

The root cause has two parts:

1. **Protocol layer**: The H1 client initializes `body_reader` to 0 for 204/304 responses, so the header task is emitted with `end=true` and no `HttpTask::Body` is ever produced.

2. **Proxy layer**: In the H1 path, `no_body` is computed *before* `response_filter` is called, so even if the user changes the status code, chunked encoding is not added. The H2 path already has the correct ordering.

Since no `HttpTask::Body` task is generated, `response_body_filter` has no opportunity to run.

## Pingora info

**Pingora version**: 0.8.0 (commit 1d93711)
**Rust version**: rustc 1.94.1
**Operating system version**: macOS 26

## Steps to reproduce

```rust
async fn response_filter(&self, _session: &mut Session, response: &mut ResponseHeader, ctx: &mut Self::CTX) -> Result<()> {
if response.status.as_u16() == 204 {
response.set_status(200)?;
ctx.patch = true;
}
Ok(())
}

fn response_body_filter(&self, _session: &mut Session, body: &mut Option, end_of_stream: bool, ctx: &mut Self::CTX) -> Result> {
if end_of_stream && ctx.patch {
*body = Some(Bytes::from(""));
}
Ok(None)
}
```

## Expected results

After changing the status from 204/304 to 200 in `response_filter`, `response_body_filter` should be called with `end_of_stream=true`, allowing the user to inject body content.

## Observed results

`response_body_filter` is never called. The downstream client receives a 200 response with no body.

## Additional context

The H2 path (`proxy_h2.rs`) already calls `response_filter` before computing `no_body`, but still has the same issue because the upstream `eos=true` flag prevents any `HttpTask::Body` from being generated.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.