Skip to content

Commit

Permalink
Allow clusterless redirections
Browse files Browse the repository at this point in the history
Signed-off-by: Eloi DEMOLIS <[email protected]>
  • Loading branch information
Wonshtrum committed Dec 13, 2024
1 parent 50008c3 commit 5d7e0f9
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 122 deletions.
8 changes: 4 additions & 4 deletions bin/src/ctl/request_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ impl CommandManager {
},
redirect: todo!(),
redirect_scheme: todo!(),

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression
host_rewrite: todo!(),
path_rewrite: todo!(),
rewrite_host: todo!(),
rewrite_path: todo!(),
})
.into(),
),
Expand Down Expand Up @@ -304,8 +304,8 @@ impl CommandManager {
},
redirect: todo!(),
redirect_scheme: todo!(),

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression

Check warning on line 306 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression
host_rewrite: todo!(),
path_rewrite: todo!(),
rewrite_host: todo!(),
rewrite_path: todo!(),
})
.into(),
),
Expand Down
4 changes: 2 additions & 2 deletions command/src/command.proto
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ message RequestHttpFrontend {
map<string, string> tags = 7;
optional RedirectPolicy redirect = 8;
optional RedirectScheme redirect_scheme = 9;
optional string host_rewrite = 10;
optional string path_rewrite = 11;
optional string rewrite_host = 10;
optional string rewrite_path = 11;
}

message RequestTcpFrontend {
Expand Down
20 changes: 10 additions & 10 deletions command/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,8 @@ pub struct FileClusterFrontendConfig {
pub tags: Option<BTreeMap<String, String>>,
pub redirect: Option<RedirectPolicy>,
pub redirect_scheme: Option<RedirectScheme>,
pub host_rewrite: Option<String>,
pub path_rewrite: Option<String>,
pub rewrite_host: Option<String>,
pub rewrite_path: Option<String>,
}

impl FileClusterFrontendConfig {
Expand Down Expand Up @@ -758,8 +758,8 @@ impl FileClusterFrontendConfig {
tags: self.tags.clone(),
redirect: self.redirect,
redirect_scheme: self.redirect_scheme,
host_rewrite: self.host_rewrite.clone(),
path_rewrite: self.path_rewrite.clone(),
rewrite_host: self.rewrite_host.clone(),
rewrite_path: self.rewrite_path.clone(),
})
}
}
Expand Down Expand Up @@ -912,8 +912,8 @@ pub struct HttpFrontendConfig {
pub tags: Option<BTreeMap<String, String>>,
pub redirect: Option<RedirectPolicy>,
pub redirect_scheme: Option<RedirectScheme>,
pub host_rewrite: Option<String>,
pub path_rewrite: Option<String>,
pub rewrite_host: Option<String>,
pub rewrite_path: Option<String>,
}

impl HttpFrontendConfig {
Expand Down Expand Up @@ -953,8 +953,8 @@ impl HttpFrontendConfig {
tags,
redirect: self.redirect.map(Into::into),
redirect_scheme: self.redirect_scheme.map(Into::into),
host_rewrite: self.host_rewrite.clone(),
path_rewrite: self.path_rewrite.clone(),
rewrite_host: self.rewrite_host.clone(),
rewrite_path: self.rewrite_path.clone(),
})
.into(),
);
Expand All @@ -971,8 +971,8 @@ impl HttpFrontendConfig {
tags,
redirect: self.redirect.map(Into::into),
redirect_scheme: self.redirect_scheme.map(Into::into),
host_rewrite: self.host_rewrite.clone(),
path_rewrite: self.path_rewrite.clone(),
rewrite_host: self.rewrite_host.clone(),
rewrite_path: self.rewrite_path.clone(),
})
.into(),
);
Expand Down
4 changes: 2 additions & 2 deletions command/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ impl RequestHttpFrontend {
path: self.path,
method: self.method,
tags: Some(self.tags),
host_rewrite: self.host_rewrite,
path_rewrite: self.path_rewrite,
rewrite_host: self.rewrite_host,
rewrite_path: self.rewrite_path,
})
}
}
Expand Down
12 changes: 7 additions & 5 deletions command/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::{cmp::Ordering, collections::BTreeMap, fmt, net::SocketAddr};

use crate::{
proto::command::{
AddBackend, FilteredTimeSerie, LoadBalancingParams, PathRule, PathRuleKind, RedirectPolicy, RedirectScheme, RequestHttpFrontend, RequestTcpFrontend, Response, ResponseContent, ResponseStatus, RulePosition, RunState, WorkerResponse
AddBackend, FilteredTimeSerie, LoadBalancingParams, PathRule, PathRuleKind, RedirectPolicy,
RedirectScheme, RequestHttpFrontend, RequestTcpFrontend, Response, ResponseContent,
ResponseStatus, RulePosition, RunState, WorkerResponse,
},
state::ClusterId,
};
Expand Down Expand Up @@ -39,9 +41,9 @@ pub struct HttpFrontend {
pub redirect: RedirectPolicy,
pub redirect_scheme: RedirectScheme,
#[serde(skip_serializing_if = "Option::is_none")]
pub host_rewrite: Option<String>,
pub rewrite_host: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path_rewrite: Option<String>,
pub rewrite_path: Option<String>,
pub tags: Option<BTreeMap<String, String>>,
}

Expand All @@ -57,8 +59,8 @@ impl From<HttpFrontend> for RequestHttpFrontend {
tags: val.tags.unwrap_or_default(),
redirect: Some(val.redirect.into()),
redirect_scheme: Some(val.redirect_scheme.into()),
host_rewrite: val.host_rewrite,
path_rewrite: val.path_rewrite,
rewrite_host: val.rewrite_host,
rewrite_path: val.rewrite_path,
}
}
}
Expand Down
28 changes: 17 additions & 11 deletions lib/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::{
proxy_protocol::expect::ExpectProxyProtocol,
Http, Pipe, SessionState,
},
router::{Route, RouteResult, Router},
router::{RouteDirection, RouteResult, Router},
server::{ListenToken, SessionManager},
socket::server_bind,
timer::TimeoutContainer,
Expand Down Expand Up @@ -472,7 +472,11 @@ impl L7ListenerHandler for HttpListener {

let now = Instant::now();

if let RouteResult::Cluster { cluster_id, .. } = &route {
if let RouteResult::Flow {
direction: RouteDirection::Forward(cluster_id),
..
} = &route
{
time!(
"frontend_matching_time",
cluster_id,
Expand Down Expand Up @@ -1056,7 +1060,9 @@ mod tests {

use super::testing::start_http_worker;
use super::*;
use sozu_command::proto::command::{CustomHttpAnswers, RedirectPolicy, RedirectScheme, SocketAddress};
use sozu_command::proto::command::{
CustomHttpAnswers, RedirectPolicy, RedirectScheme, SocketAddress,
};

use crate::sozu_command::{
channel::Channel,
Expand Down Expand Up @@ -1331,8 +1337,8 @@ mod tests {
cluster_id: Some(cluster_id1),
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
host_rewrite: None,
path_rewrite: None,
rewrite_host: None,
rewrite_path: None,
tags: None,
})
.expect("Could not add http frontend");
Expand All @@ -1346,8 +1352,8 @@ mod tests {
cluster_id: Some(cluster_id2),
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
host_rewrite: None,
path_rewrite: None,
rewrite_host: None,
rewrite_path: None,
tags: None,
})
.expect("Could not add http frontend");
Expand All @@ -1361,8 +1367,8 @@ mod tests {
cluster_id: Some(cluster_id3),
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
host_rewrite: None,
path_rewrite: None,
rewrite_host: None,
rewrite_path: None,
tags: None,
})
.expect("Could not add http frontend");
Expand All @@ -1376,8 +1382,8 @@ mod tests {
cluster_id: Some("cluster_1".to_owned()),
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
host_rewrite: None,
path_rewrite: None,
rewrite_host: None,
rewrite_path: None,
tags: None,
})
.expect("Could not add http frontend");
Expand Down
8 changes: 6 additions & 2 deletions lib/src/https.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use crate::{
rustls::TlsHandshake,
Http, Pipe, SessionState,
},
router::{Route, RouteResult, Router},
router::{RouteDirection, RouteResult, Router},
server::{ListenToken, SessionManager},
socket::{server_bind, FrontRustls},
timer::TimeoutContainer,
Expand Down Expand Up @@ -600,7 +600,11 @@ impl L7ListenerHandler for HttpsListener {

let now = Instant::now();

if let RouteResult::Cluster { cluster_id, .. } = &route {
if let RouteResult::Flow {
direction: RouteDirection::Forward(cluster_id),
..
} = &route
{
time!(
"frontend_matching_time",
cluster_id,
Expand Down
8 changes: 4 additions & 4 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,13 @@ use tls::CertificateResolverError;

use sozu_command::{
logging::{CachedTags, LogContext},
proto::command::{Cluster, ListenerType, RedirectPolicy, RequestHttpFrontend, WorkerRequest, WorkerResponse},
proto::command::{Cluster, ListenerType, RequestHttpFrontend, WorkerRequest, WorkerResponse},
ready::Ready,
state::ClusterId,
AsStr, ObjectKind,
};

use crate::{backends::BackendMap, router::Route};
use crate::backends::BackendMap;

/// Anything that can be registered in mio (subscribe to kernel events)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -602,8 +602,8 @@ pub enum RetrieveClusterError {
NoPath,
#[error("unauthorized route")]
UnauthorizedRoute,
#[error("redirected {0:?}")]
Redirected(RedirectPolicy),
#[error("redirected")]
Redirected,
#[error("{0}")]
RetrieveFrontend(FrontendFromRequestError),
}
Expand Down
37 changes: 11 additions & 26 deletions lib/src/protocol/kawa_h1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rusty_ulid::Ulid;
use sozu_command::{
config::MAX_LOOP_ITERATIONS,
logging::EndpointRecord,
proto::command::{Event, EventKind, ListenerType, RedirectPolicy, RedirectScheme},
proto::command::{Event, EventKind, ListenerType, RedirectScheme},
};
// use time::{Duration, Instant};

Expand All @@ -34,7 +34,7 @@ use crate::{
SessionState,
},
retry::RetryPolicy,
router::{Route, RouteResult},
router::{RouteDirection, RouteResult},
server::{push_event, CONN_RETRIES},
socket::{stats::socket_rtt, SocketHandler, SocketResult, TransportProtocol},
sozu_command::{logging::LogContext, ready::Ready},
Expand Down Expand Up @@ -1280,35 +1280,21 @@ impl<Front: SocketHandler, L: ListenerHandler + L7ListenerHandler> Http<Front, L
};

match route {
RouteResult::Deny
| RouteResult::Cluster {
redirect: RedirectPolicy::Unauthorized,
..
} => {
RouteResult::Deny => {
self.set_answer(DefaultAnswer::Answer401 {});
Err(RetrieveClusterError::UnauthorizedRoute)
}
RouteResult::Cluster {
cluster_id,
redirect,
redirect_scheme,
RouteResult::Flow {
direction: flow,
rewritten_host,
rewritten_path,
} => {
let host = rewritten_host.as_deref().unwrap_or(host);
let path = rewritten_path.as_deref().unwrap_or(uri);
let is_https = matches!(proxy.borrow().kind(), ListenerType::Https);
match (redirect, is_https) {
(RedirectPolicy::Forward, _) | (RedirectPolicy::ForceHttps, true) => {
Ok(cluster_id)
}
(RedirectPolicy::ForceHttps, false) => {
self.set_answer(DefaultAnswer::Answer301 {
location: format!("https://{host}{path}"),
});
Err(RetrieveClusterError::Redirected(redirect))
}
(RedirectPolicy::Permanent, _) => {
match flow {
RouteDirection::Forward(cluster_id) => Ok(cluster_id),
RouteDirection::Permanent(redirect_scheme) => {
let proto = match (redirect_scheme, is_https) {
(RedirectScheme::UseHttp, _) | (RedirectScheme::UseSame, false) => {
"http"
Expand All @@ -1320,10 +1306,9 @@ impl<Front: SocketHandler, L: ListenerHandler + L7ListenerHandler> Http<Front, L
self.set_answer(DefaultAnswer::Answer301 {
location: format!("{proto}://{host}{path}"),
});
Err(RetrieveClusterError::Redirected(redirect))
Err(RetrieveClusterError::Redirected)
}
(RedirectPolicy::Temporary, _) => todo!(),
(RedirectPolicy::Unauthorized, _) => unreachable!(),
RouteDirection::Temporary(_) => todo!(),
}
}
}
Expand Down Expand Up @@ -1615,7 +1600,7 @@ impl<Front: SocketHandler, L: ListenerHandler + L7ListenerHandler> Http<Front, L
}
}

pub fn backend_hup(&mut self, metrics: &mut SessionMetrics) -> StateResult {
pub fn backend_hup(&mut self, _metrics: &mut SessionMetrics) -> StateResult {
let response_stream = match &mut self.response_stream {
ResponseStream::BackendAnswer(response_stream) => response_stream,
_ => return StateResult::CloseBackend,
Expand Down
Loading

0 comments on commit 5d7e0f9

Please sign in to comment.