0.2.0: Add support to route requests with curl user-agent

Signed-off-by: Ivan Bushchik <ivabus@ivabus.dev>
This commit is contained in:
Ivan Bushchik 2023-09-10 12:31:19 +03:00
parent 26fa8d9aa4
commit fc1ebcbe60
No known key found for this signature in database
GPG key ID: 2F16FBF3262E090C
3 changed files with 56 additions and 13 deletions

View file

@ -1,10 +1,10 @@
[package] [package]
name = "urouter" name = "urouter"
version = "0.1.0" version = "0.2.0"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/ivabus/urouter" repository = "https://github.com/ivabus/urouter"
description = "Small router for (kinda) short domains (static fork of ivabus/aliurl)" description = "Small router for (kinda) short domains (fork of ivabus/aliurl for static routing)"
[dependencies] [dependencies]

View file

@ -23,10 +23,18 @@ Edit `alias.json` and `cargo run`
"uri": "uri2", "uri": "uri2",
"alias": "http://example.com", "alias": "http://example.com",
"is_url": true "is_url": true
},
{
"uri": "/",
"alias": "https://somecoolscript.sh",
"is_url": true,
"curl_only": true
} }
] ]
``` ```
`"curl_only"` thing for `curl https://url | sh` like scripts.
## License ## License
The project is licensed under the terms of the [MIT license](./LICENSE).% The project is licensed under the terms of the [MIT license](./LICENSE).%

View file

@ -29,11 +29,12 @@ use rocket::http::Status;
use std::cell::OnceCell; use std::cell::OnceCell;
use std::path::PathBuf; use std::path::PathBuf;
use rocket::request::{FromRequest, Outcome};
use rocket::response::content::RawText; use rocket::response::content::RawText;
use rocket::response::{Redirect, Responder}; use rocket::response::{Redirect, Responder};
use rocket::Request;
use serde::Deserialize; use serde::Deserialize;
const INDEX_REDIRECT: &'static str = "https://ivabus.dev";
const _ALIAS: &'static str = include_str!("../alias.json"); const _ALIAS: &'static str = include_str!("../alias.json");
static mut ALIAS: OnceCell<Vec<Alias>> = OnceCell::new(); static mut ALIAS: OnceCell<Vec<Alias>> = OnceCell::new();
@ -42,6 +43,7 @@ struct Alias {
uri: String, uri: String,
alias: String, alias: String,
is_url: Option<bool>, is_url: Option<bool>,
curl_only: Option<bool>,
} }
#[derive(Responder)] #[derive(Responder)]
@ -51,28 +53,61 @@ enum Response {
Status(Status), Status(Status),
} }
struct UserAgent(String);
#[derive(Debug)]
enum UserAgentError {}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for UserAgent {
type Error = UserAgentError;
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match req.headers().get_one("user-agent") {
Some(key) => Outcome::Success(UserAgent(key.to_string())),
_ => Outcome::Success(UserAgent("".to_string())),
}
}
}
fn get_return(alias: &Alias) -> Response {
return match alias.is_url {
Some(true) => Response::Redirect(Redirect::to(alias.alias.clone())),
_ => Response::Text(RawText(
smurf::io::read_file_to_str(&PathBuf::from(&alias.alias)).unwrap(),
)),
};
}
#[get("/<page>")] #[get("/<page>")]
async fn get_page(page: String) -> Response { fn get_page(page: String, user_agent: UserAgent) -> Response {
let mut decoded_page = String::new(); let mut decoded_page = String::new();
url_escape::decode_to_string(page, &mut decoded_page); url_escape::decode_to_string(page, &mut decoded_page);
let alias = unsafe { ALIAS.get().unwrap() }; let alias = unsafe { ALIAS.get().unwrap() };
let mut pages = Vec::new();
let curl_check = user_agent.0.contains("curl");
for i in alias { for i in alias {
if i.uri == decoded_page { if i.uri == decoded_page {
return match i.is_url { if (i.curl_only == Some(true) && curl_check.clone())
Some(true) => Response::Redirect(Redirect::to(i.alias.clone())), || (i.curl_only != Some(true) && !curl_check.clone())
_ => Response::Text(RawText( {
smurf::io::read_file_to_str(&PathBuf::from(&i.alias)).unwrap(), return get_return(i);
)),
}; };
pages.push(i);
}
}
// Returning normal page (if found) to curl users.
for i in pages {
if i.curl_only != Some(true) {
return get_return(i);
} }
} }
Response::Status(Status::NotFound) Response::Status(Status::NotFound)
} }
#[get("/")] #[get("/")]
async fn get_index() -> Redirect { async fn index(user_agent: UserAgent) -> Response {
Redirect::to(INDEX_REDIRECT) get_page("/".to_string(), user_agent)
} }
#[rocket::main] #[rocket::main]
@ -80,6 +115,6 @@ async fn main() -> Result<(), rocket::Error> {
unsafe { unsafe {
ALIAS.set(serde_json::from_str(_ALIAS).unwrap()).unwrap_unchecked(); ALIAS.set(serde_json::from_str(_ALIAS).unwrap()).unwrap_unchecked();
} }
let _rocket = rocket::build().mount("/", routes![get_page, get_index]).launch().await?; let _rocket = rocket::build().mount("/", routes![get_page, index]).launch().await?;
Ok(()) Ok(())
} }