When I attempt to issue an HTTP Redirect from request_filter the connection hangs
Describe the bug
I'm attempting to issue an HTTP redirect from request_filter()
With the code shown below the connection hangs.
There needs to be a way to issue something besides errors from the filters. Perhaps the docs are missing a working example, or perhaps this a feature request, I cannot tell.
Pingora info
Pingora version: 0.3 (from crate) Rust version: cargo 1.83.0 (5ffbef321 2024-10-29) Operating system version: Docker for OSX, 20.10.17
Steps to reproduce
Using example Proxy HTTP for LB, the following code for request_filter
use url::Url;
use pingora::proxy::{ProxyHttp, Session};
use pingora_http::{ResponseHeader, StatusCode};
async fn request_filter(&self, session: &mut Session, ctx: &mut Self::CTX) -> Result<bool> {
// Construct the redirect URL with the return_url parameter
let request = session.req_header();
let current_url = request.uri.to_string();
let scheme = request.uri.scheme_str().unwrap_or("http");
let host = request.uri.host().unwrap_or("localhost");
let port = session.req_header().uri.port_u16().unwrap_or(80);
let mut redirect_url = Url::parse(&format!("{}://{}:{}/redirect_test_path", scheme, host, port)).unwrap();
redirect_url.query_pairs_mut().append_pair("return_url", ¤t_url);
// Create the response with the Location header
let mut response = ResponseHeader::build(StatusCode::FOUND, None).unwrap();
response.insert_header("Location", redirect_url.as_str());
// Write the response header
session.write_response_header(Box::new(response), true).await?;
session.write_response_body(None, true).await?;
return Ok(true);
}
Expected results
a curl -v should show the redirect and should exit.
Observed results
$ curl -v --max-redirs 0 localhost:6190
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 6190 (#0)
> GET / HTTP/1.1
> Host: localhost:6190
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 302 Found
< Location: http://localhost/redirect_test_path?return_url=%2F
< Date: Sat, 28 Dec 2024 02:27:44 GMT
< Connection: keep-alive
* no chunk, no close, no size. Assume close to signal end
Additional context
Try to set content-length of response body.
response.insert_header(
"Content-Length",
"0".to_string(),
);
Yep, that did it. So this is a documentation request or a "pick suitable defaults for responses when request_filter returns Ok(true)"
Updated documentation for this trait method here https://github.com/cloudflare/pingora/pull/613.
@kumarlokesh thank you! I ran into this same issue when trying to filter a request with Ok(true) this led to a seemingly infinite hanging request. Setting
if condition {
session.set_keepalive(None);
return Ok(true);
}
was the fix as you noted is in #613 I think the documentation can be improved on this. That using request_filter() alone is likely not enough. Particularly, I was looking at the phase chart for what to do after filtering a request