-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f270386
commit fbd77fb
Showing
13 changed files
with
362 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"rust-analyzer.linkedProjects": [ | ||
".\\examples\\basic\\Cargo.toml" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "basic" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
afire = { path = "../..", features = ["extensions"] } | ||
rand = "0.8.5" | ||
serde = { version = "1.0.188", features = ["derive"] } | ||
serde_json = "1.0.107" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
use std::{ | ||
collections::HashMap, | ||
error, | ||
sync::{Arc, RwLock}, | ||
}; | ||
|
||
use afire::{ | ||
extensions::{Logger, RealIp, ServeStatic}, | ||
middleware::Middleware, | ||
trace::{set_log_level, Level}, | ||
Content, Method, Request, Response, Server, | ||
}; | ||
use rand::Rng; | ||
use serde::Deserialize; | ||
use serde_json::json; | ||
|
||
// The App struct will be used as the state for our server. | ||
// A reference to the state is passed to middleware and route handlers. | ||
struct App { | ||
// Records the number of times each page has been visited. | ||
analytics: RwLock<HashMap<String, u64>>, | ||
} | ||
|
||
fn main() -> Result<(), Box<dyn error::Error>> { | ||
// Show some helpful information during startup. | ||
set_log_level(Level::Trace); | ||
|
||
// Create a new afire server on localhost:8080 with 4 worker threads and the App state. | ||
let mut server = Server::<App>::new("localhost", 8080) | ||
.workers(4) | ||
.state(App::new()); | ||
|
||
// Add extension to serve static files from the ./static directory. | ||
ServeStatic::new("./static").attach(&mut server); | ||
|
||
// Add middleware to log requests to the console. | ||
Logger::new().attach(&mut server); | ||
|
||
// Add our analytics middleware. | ||
Analytics::new(server.app()).attach(&mut server); | ||
|
||
// Add a route at GET /greet/{name} that will greet the user. | ||
server.route(Method::GET, "/greet/{name}", |ctx| { | ||
let name = ctx.param("name"); | ||
ctx.text(format!("Hello, {}!", name)).send()?; | ||
Ok(()) | ||
}); | ||
|
||
// Add a route to respond with the client's IP address. | ||
server.route(Method::GET, "/ip", |ctx| { | ||
// Get the client's IP address, even if they are behind a reverse proxy. | ||
let ip = ctx.real_ip(); | ||
ctx.text(format!("Your IP is: {}", ip)).send()?; | ||
Ok(()) | ||
}); | ||
|
||
// Add an api route to pick a random number. | ||
server.route(Method::GET, "/random", |ctx| { | ||
#[derive(Deserialize)] | ||
struct Request { | ||
min: u32, | ||
max: u32, | ||
} | ||
|
||
let data = serde_json::from_slice::<Request>(&ctx.req.body)?; | ||
let num = rand::thread_rng().gen_range(data.min..=data.max); | ||
|
||
ctx.text(json!({ "number": num })) | ||
.content(Content::JSON) | ||
.send()?; | ||
Ok(()) | ||
}); | ||
|
||
server.route(Method::GET, "/analytics", |ctx| { | ||
let res = json!(*ctx.app().analytics.read().unwrap()); | ||
ctx.text(res).content(Content::JSON).send()?; | ||
Ok(()) | ||
}); | ||
|
||
server.run()?; | ||
Ok(()) | ||
} | ||
|
||
struct Analytics { | ||
// Store a reference to the app state so we can access it in the middleware. | ||
app: Arc<App>, | ||
} | ||
|
||
impl Middleware for Analytics { | ||
// Pre middleware is run before the route handler. | ||
// You can modify the request, return a response or continue to the next middleware or route handler. | ||
fn end(&self, req: Arc<Request>, res: &Response) { | ||
// Only record successful requests. | ||
if !res.status.is_success() { | ||
return; | ||
} | ||
|
||
// Update the analytics with the path of the request. | ||
let mut analytics = self.app.analytics.write().unwrap(); | ||
analytics | ||
.entry(req.path.to_owned()) | ||
.and_modify(|x| *x += 1) | ||
.or_insert(1); | ||
} | ||
} | ||
|
||
impl App { | ||
fn new() -> Self { | ||
Self { | ||
analytics: RwLock::new(HashMap::new()), | ||
} | ||
} | ||
} | ||
|
||
impl Analytics { | ||
fn new(app: Arc<App>) -> Self { | ||
Self { app } | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>👋 Hello World</title> | ||
</head> | ||
<body> | ||
<h1>👋 Hello World</h1> | ||
<p> | ||
Welcome to <a href="https://github.com/Basicprogrammer10/afire">afire</a>! | ||
</p> | ||
|
||
<h2>Routes</h2> | ||
<ul> | ||
<li><a href="/greet/World">Greet</a></li> | ||
<li><a href="/ip">Your Ip</a></li> | ||
<li><a href="/random">Random Number</a></li> | ||
<li><a href="/analytics">Analytics</a></li> | ||
</ul> | ||
</body> | ||
</html> |
Binary file not shown.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.