Skip to content

Commit

Permalink
add proxy option no_redirect
Browse files Browse the repository at this point in the history
When serving responses with the Trunk proxy, redirects are automatically
followed by default. This can be undesirable, e.g. when serving a login page
that response with a redirect and a set-cookie header like

```
HTTP/1.1 303 See Other
location: /
set-cookie: session=...; ...;
```

This PR adds a proxy option `no_redirect` that when set will instruct the proxy
to not automatically follow redirects. The default behavior is unchanged.
  • Loading branch information
rksm authored and ctron committed Aug 28, 2024
1 parent bea4eeb commit 121235c
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 1 deletion.
1 change: 1 addition & 0 deletions site/content/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ ws = false # Use WebSocket for this proxy
insecure = false # Disable certificate validation
no_system_proxy = false # Disable system proxy
rewrite = "" # Strip the given prefix off paths
no_redirect = false # Disable following redirects of proxy responses
```

## Hooks section
Expand Down
9 changes: 9 additions & 0 deletions src/cmd/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ pub struct ProxyArgs {
requires = "proxy_backend"
)]
pub proxy_no_system_proxy: bool,
/// Configure the proxy to not automatically follow redirects if a backend responds with a redirect
#[arg(
long,
env = "TRUNK_SERVE_PROXY_NO_REDIRECT",
requires = "proxy_backend"
)]
pub proxy_no_redirect: bool,
}

impl Serve {
Expand All @@ -107,6 +114,7 @@ impl Serve {
proxy_ws,
proxy_insecure,
proxy_no_system_proxy,
proxy_no_redirect,
},
no_autoreload,
no_error_reporting,
Expand Down Expand Up @@ -148,6 +156,7 @@ impl Serve {
ws: proxy_ws,
insecure: proxy_insecure,
no_system_proxy: proxy_no_system_proxy,
no_redirect: proxy_no_redirect,
});
}

Expand Down
1 change: 1 addition & 0 deletions src/config/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ impl ConfigModel for Configuration {
ws: self.serve.proxy_ws.unwrap_or_default(),
insecure: self.serve.proxy_insecure.unwrap_or_default(),
no_system_proxy: self.serve.proxy_no_system_proxy.unwrap_or_default(),
no_redirect: self.serve.proxy_no_redirect.unwrap_or_default(),
})
}

Expand Down
4 changes: 4 additions & 0 deletions src/config/models/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ pub struct Proxy {
#[serde(alias = "no-system-proxy")]
#[serde(default)]
pub no_system_proxy: bool,
/// Automatically redirect proxy requests? `no_redirect` Defaults to
/// `false`, i.e. yes, follow redirects automatically.
#[serde(default)]
pub no_redirect: bool,
}

#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, JsonSchema)]
Expand Down
4 changes: 4 additions & 0 deletions src/config/models/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ pub struct Serve {
/// A base path to serve the application from
#[serde(default)]
pub serve_base: Option<String>,
/// Configure the proxy to not follow redirects
#[serde(default)]
pub proxy_no_redirect: Option<bool>,

/// A URL to which requests will be proxied [default: None]
#[deprecated]
Expand Down Expand Up @@ -98,6 +101,7 @@ impl Default for Serve {
proxy_ws: None,
proxy_insecure: None,
proxy_no_system_proxy: None,
proxy_no_redirect: None,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/config/rt/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ impl RtcServe {
proxy_ws: _,
proxy_insecure: _,
proxy_no_system_proxy: _,
proxy_no_redirect: _,
} = config.serve;

let tls = tls_config(
Expand Down
1 change: 1 addition & 0 deletions src/serve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ fn router(state: Arc<State>, cfg: Arc<RtcServe>) -> Result<Router> {
ProxyClientOptions {
insecure: proxy.insecure,
no_system_proxy: proxy.no_system_proxy,
redirect: !proxy.no_redirect,
},
)?;
}
Expand Down
10 changes: 9 additions & 1 deletion src/serve/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use axum::http::Uri;
use axum::Router;
use console::Emoji;
use http::HeaderMap;
use reqwest::redirect::Policy;
use reqwest::Client;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
Expand Down Expand Up @@ -86,6 +87,7 @@ impl ProxyBuilder {
pub(crate) struct ProxyClientOptions {
pub insecure: bool,
pub no_system_proxy: bool,
pub redirect: bool,
}

#[derive(Default)]
Expand All @@ -107,7 +109,13 @@ impl ProxyClients {

/// Create a new client for proxying
fn create_client(opts: ProxyClientOptions) -> anyhow::Result<Client> {
let mut builder = reqwest::ClientBuilder::new().http1_only();
let mut builder = reqwest::ClientBuilder::new()
.http1_only()
.redirect(if opts.redirect {
Policy::default()
} else {
Policy::none()
});

#[cfg(any(feature = "native-tls", feature = "rustls"))]
if opts.insecure {
Expand Down

0 comments on commit 121235c

Please sign in to comment.