actix_rewrite/
util.rs

1//! Utiliies Used for Actix ModRewrite
2
3use std::collections::HashMap;
4
5use actix_http::{Uri, uri::Scheme};
6use actix_web::{HttpRequest, web::Query};
7use mod_rewrite::context::RequestCtx;
8
9use super::error::Error;
10
11type QueryMap = Query<HashMap<String, String>>;
12
13/// Build [`mod_rewrite::context::RequestCtx`]
14/// using [`ServiceRequest`](actix_web::dev::ServiceRequest) data.
15pub fn request_ctx(req: &HttpRequest) -> RequestCtx {
16    RequestCtx::default()
17        .path_info(req.match_info().unprocessed())
18        .request_uri(req.uri().to_string())
19        .request_method(req.method().to_string())
20        .query_string(req.uri().query().unwrap_or(""))
21        .maybe_remote_addr(req.peer_addr())
22        .expect("invalid peer address")
23}
24
25#[inline]
26fn get_query(uri: &Uri) -> Result<QueryMap, Error> {
27    Ok(QueryMap::from_query(uri.query().unwrap_or(""))?)
28}
29
30/// Build new URI combining data from [`actix_web::HttpRequest`]
31/// and rewritten uri from [`Engine::rewrite`](crate::Engine::rewrite)
32#[inline]
33pub fn join_uri(before: &Uri, after: &Uri) -> Result<Uri, Error> {
34    let mut query = get_query(before)?;
35    query.extend(get_query(after)?.into_inner());
36    let query = serde_urlencoded::to_string(query.into_inner())?;
37
38    let mut builder = Uri::builder().scheme(
39        after
40            .scheme()
41            .or(before.scheme())
42            .cloned()
43            .unwrap_or(Scheme::HTTP),
44    );
45
46    if let Some(authority) = after.authority().or(before.authority()) {
47        builder = builder.authority(authority.clone());
48    }
49    let path = after.path();
50    Ok(builder.path_and_query(format!("{path}?{query}")).build()?)
51}