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, }
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 router!([get, post] => @hello)
106 .hoop(authorization::AuthGuard::new(|_e| html_err!("unauthorized"))),
107 router!([get] => /user/@login),
109 router!([get, post] => a/b/@ab::show),
111 router!([get, post, put] => /b/c/@ab::show/<**path>),
113 router!([get, post] => @text_json).hoop(build_cros("*")),
115 router!([get, post] => ...@ab::shop::show).hoop(build_cros("*")),
117 ] & [jwt, ]
118 };
119 Ok(())
120}