hello/
hello.rs

1use salvo::jwt_auth::HeaderFinder;
2use salvo::prelude::*;
3use serde::{Deserialize, Serialize};
4use serde_json::json;
5use tokio::io::AsyncReadExt;
6use webserver_rs::prelude::*;
7use webserver_rs::{
8    authorization, build_cros, config::Config, expire_time, html_err, json_err, router,
9    FromConfigFile, HttpResult, MemoryStream,
10};
11
12use webserver_rs::web_core::authorization::gen_token;
13
14#[derive(Debug, Serialize, Deserialize)]
15#[serde(crate = "serde")]
16struct JwtClaim {
17    username: String,
18    exp: i64, // required
19}
20
21#[handler]
22pub fn hello(req: &mut Request, res: &mut Response) -> HttpResult<()> {
23    let c = req.query::<String>("id");
24    println!("{c:?}");
25    let p = req.query::<String>("id").ok_or(html_err!(
26        400,
27        json!({
28            "status":"fail",
29            "msg":"id not found"
30        })
31        .to_string()
32    ))?;
33    res.render(Text::Plain(format!("hello, {p}")));
34    Ok(())
35}
36
37#[handler]
38pub fn login(depot: &mut Depot, res: &mut Response) -> HttpResult<()> {
39    let config = depot.obtain::<Config>().map_err(|_e| {
40        crate::json_err!(400,{
41            "status":"fail",
42            "msg":"config not found"
43        })
44    })?;
45    let token = gen_token(
46        config.secret_key.clone(),
47        JwtClaim {
48            exp: crate::expire_time!(Days(1)),
49            username: "a".to_string(),
50        },
51    )
52    .map_err(|e| crate::json_err!(400, {"err":e.to_string()}))?;
53    res.render(Text::Plain(token));
54    Ok(())
55}
56
57#[handler]
58pub async fn image(res: &mut Response) -> HttpResult<()> {
59    let mut file = tokio::fs::File::open("./test.png")
60        .await
61        .map_err(|_| crate::html_err!(404, ""))?;
62    let mut s = Vec::new();
63    file.read_to_end(&mut s).await.unwrap();
64    res.stream(MemoryStream::new(s, 200));
65    Ok(())
66}
67#[handler]
68pub async fn text_json(res: &mut Response) -> HttpResult<()> {
69    res.render(Text::Json(
70        json!({
71            "title":1
72        })
73        .to_string(),
74    ));
75    Ok(())
76}
77
78mod ab {
79    use salvo::handler;
80
81    #[handler]
82    pub fn show() -> &'static str {
83        "abc"
84    }
85
86    pub mod shop {
87        #[super::handler]
88        pub fn show() -> &'static str {
89            "show"
90        }
91    }
92}
93
94#[tokio::main]
95async fn main() -> anyhow::Result<()> {
96    let config = Config::from_config_file("./config.toml").expect("config file not found");
97    let jwt = authorization::gen_jwt_auth::<JwtClaim>(
98        config.secret_key.clone(),
99        vec![Box::new(HeaderFinder::new())],
100    );
101
102    webserver_rs::serve_routes! {
103        config => [
104        // http://localhost:8080/hello
105        router!([get, post] => @hello)
106            .hoop(authorization::AuthGuard::new(|_e| html_err!("unauthorized"))),
107        // http://localhost:8080/user/login
108        router!([get] => /user/@login),
109        // http://localhost:8080/a/b/show
110        router!([get, post] => a/b/@ab::show),
111        // http://localhost:8080/b/c/show/*
112        router!([get, post, put] => /b/c/@ab::show/<**path>),
113        // http://localhost:8080/test_json
114        router!([get, post] => @text_json).hoop(build_cros("*")),
115        // http://localhost:8080/ab/shop/show
116        router!([get, post] => ...@ab::shop::show).hoop(build_cros("*")),
117        ] & [jwt, /*Middlewares*/]
118    };
119    Ok(())
120}