actix_rewrite/
util.rs

1//! Utiliies Used for Actix ModRewrite
2
3use std::{collections::HashMap, str::FromStr};
4
5use actix_http::Uri;
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#[inline]
14pub(crate) fn recode(uri: String) -> Result<Uri, Error> {
15    Ok(Uri::from_str(&uri)?)
16}
17
18/// Build [`mod_rewrite::context::RequestCtx`]
19/// using [`ServiceRequest`](actix_web::dev::ServiceRequest) data.
20pub fn request_ctx(req: &HttpRequest) -> RequestCtx {
21    RequestCtx::default()
22        .path_info(req.match_info().unprocessed())
23        .request_uri(req.uri().to_string())
24        .request_method(req.method().to_string())
25        .query_string(req.uri().query().unwrap_or(""))
26        .maybe_remote_addr(req.peer_addr())
27        .expect("invalid peer address")
28}
29
30#[inline]
31fn get_query(uri: &Uri) -> Result<QueryMap, Error> {
32    Ok(QueryMap::from_query(uri.query().unwrap_or(""))?)
33}
34
35/// Build new URI combining data from [`actix_web::HttpRequest`]
36/// and rewritten uri from [`Engine::rewrite`](crate::Engine::rewrite)
37#[inline]
38pub fn join_uri(before: &Uri, after: &Uri) -> Result<Uri, Error> {
39    let mut query = get_query(before)?;
40    query.extend(get_query(after)?.into_inner());
41    let query = serde_urlencoded::to_string(query.into_inner())?;
42
43    let scheme = after
44        .scheme()
45        .or(before.scheme())
46        .map(|scheme| format!("{}://", scheme.as_str()))
47        .unwrap_or_default();
48    let authority = after
49        .authority()
50        .or(before.authority())
51        .map(|authority| authority.as_str())
52        .unwrap_or_default();
53    let path = after.path();
54
55    let uri = &format!("{scheme}{authority}{path}?{query}");
56    Ok(Uri::from_str(&uri)?)
57}