-
Hey folks! 👋 I'm building a container registry in Rust using Actix Web and ran into an issue with routing that I could use some help with. According to the OCI distribution spec, the API endpoints look like this:
The tricky part is that To work around this, I wrote a middleware that intercepts requests, extracts
Here's the code for the middleware: const KEYWORDS: [&str; 4] = ["blobs", "manifests", "tags", "referrers"];
pub async fn preprocess_request(
mut req: ServiceRequest,
next: Next<impl MessageBody>,
) -> Result<ServiceResponse<impl MessageBody>, actix_web::Error> {
let head = req.head_mut();
let query = head.uri.query();
let path = head.uri.path();
let new_uri = parse_uri(path, query);
head.uri = new_uri;
req.match_info_mut().reset();
println!("{}", req.uri());
next.call(req).await
}
fn parse_uri(path: &str, query: Option<&str>) -> Uri {
let path = path.strip_prefix("/v2/").unwrap();
let mut parts = path.split('/').peekable();
let mut name_parts = Vec::new();
while let Some(part) = parts.peek() {
if KEYWORDS.contains(part) {
break;
}
name_parts.push(parts.next().unwrap());
}
let name = name_parts.join("/");
let new_path = format!("/v2/{}", parts.collect::<Vec<_>>().join("/"));
let new_query = match query {
Some(q) if !q.is_empty() => format!("{}&name={}", q, name),
_ => format!("name={}", name),
};
format!("{}?{}", new_path, new_query)
.parse::<Uri>()
.unwrap()
} Then in my app config: HttpServer::new(move || {
App::new()
.wrap(from_fn(preprocess_request))
.service(web::scope("/v2")
.route("/manifests/{reference}", web::get().to(pull))
)
.route("/health_check", web::get().to(health_check))
}) The idea is that when I hit:
…it should get rewritten to:
However, every time I I assumed middleware runs before routing, but I’m now wondering if Actix has already resolved the routing scope by the time the middleware runs — and so my rewrite comes too late. Any advice on how to make this approach work? Or is there a better way to handle dynamic paths where parts of the path (like PS: pretty new to rust so kindly put me down lightly Thanks! 🙏 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Modifying the route processing logic resolved this issue req.match_info_mut().get_mut().update(&new_uri);
req.head_mut().uri = new_uri; Referenced the NormalizePath middleware implementation for this. actix-web/actix-web/src/middleware/normalize.rs Lines 196 to 197 in c284426 |
Beta Was this translation helpful? Give feedback.
Modifying the route processing logic resolved this issue
Referenced the NormalizePath middleware implementation for this.
Ref:
actix-web/actix-web/src/middleware/normalize.rs
Lines 196 to 197 in c284426