Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When I attempt to issue an HTTP Redirect from request_filter the connection hangs #498

Open
pszabop opened this issue Dec 28, 2024 · 2 comments
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed

Comments

@pszabop
Copy link

pszabop commented Dec 28, 2024

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", &current_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

@vicanso
Copy link
Contributor

vicanso commented Dec 28, 2024

Try to set content-length of response body.

response.insert_header(
    "Content-Length",
    "0".to_string(),
);

@pszabop
Copy link
Author

pszabop commented Dec 28, 2024

Yep, that did it. So this is a documentation request or a "pick suitable defaults for responses when request_filter returns Ok(true)"

@andrewhavck andrewhavck added documentation Improvements or additions to documentation help wanted Extra attention is needed labels Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants