reorganize module
This commit is contained in:
1563
server/Cargo.lock
generated
Normal file
1563
server/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
server/Cargo.toml
Normal file
17
server/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "server"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
hyper = { version = "0.14", features = ["full"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
http = "0.2"
|
||||
httparse = "1"
|
||||
rhai = { version = "1.21", features = ["serde"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tera = "1.0"
|
||||
once_cell = "1"
|
||||
rhai_tera = { path = "../rhai_tera" }
|
||||
calendar = { path = "../components/calendar" }
|
51
server/README.md
Normal file
51
server/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Calendar Server Example
|
||||
|
||||
A simple Rust web server using Hyper that exposes an `/all_calendars` endpoint.
|
||||
|
||||
## Running the server
|
||||
|
||||
```bash
|
||||
# Navigate to the examples directory
|
||||
cd /path/to/examples
|
||||
|
||||
# Build and run the server
|
||||
cargo run
|
||||
```
|
||||
|
||||
Once the server is running, you can access the endpoint at:
|
||||
- http://127.0.0.1:8080/all_calendars
|
||||
|
||||
## Features
|
||||
- Simple HTTP server using Hyper
|
||||
- Single endpoint that returns "Hello World"
|
||||
|
||||
|
||||
Sure thing! Here’s the Markdown version you can copy-paste directly into your README.md:
|
||||
|
||||
## 🔁 Live Reload (Hot Reload for Development)
|
||||
|
||||
To automatically recompile and restart your example server on file changes (e.g. Rust code, templates, Rhai scripts), you can use [`cargo-watch`](https://github.com/watchexec/cargo-watch):
|
||||
|
||||
### ✅ Step 1: Install `cargo-watch`
|
||||
|
||||
```bash
|
||||
cargo install cargo-watch
|
||||
```
|
||||
|
||||
### ✅ Step 2: Run the server with live reload
|
||||
|
||||
cargo watch -x 'run --example server'
|
||||
|
||||
This will:
|
||||
• Watch for file changes in your project
|
||||
• Rebuild and re-run examples/server.rs whenever you make a change
|
||||
|
||||
### 🧠 Bonus: Watch additional folders
|
||||
|
||||
To also reload when .tera templates or .rhai scripts change:
|
||||
|
||||
cargo watch -w src -w examples -w src/templates -w src/scripts -x 'run --example server'
|
||||
|
||||
### 💡 Optional: Clear terminal on each reload
|
||||
|
||||
cargo watch -c -x 'run --example server'
|
11
server/develop.sh
Executable file
11
server/develop.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# 🚀 Start dev server with file watching and browser reload
|
||||
reloadd \
|
||||
--watch src \
|
||||
--watch src/templates \
|
||||
--watch examples \
|
||||
--port 8080 \
|
||||
--run "cargo build" \
|
||||
--run "cargo run --example server"
|
80
server/src/main.rs
Normal file
80
server/src/main.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use hyper::{Body, Request, Response, Server};
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
use hyper::StatusCode;
|
||||
use std::convert::Infallible;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
extern crate calendar;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
|
||||
|
||||
let make_svc = make_service_fn(|_conn| async {
|
||||
Ok::<_, Infallible>(service_fn(|req| async {
|
||||
// Remove the /calendar prefix and pass the modified request to the calendar handler
|
||||
if req.uri().path().starts_with("/calendar/") {
|
||||
calendar::handle_request(remove_path_prefix(req, "/calendar")).await
|
||||
} else {
|
||||
let mut resp = Response::new(Body::from("Not Found"));
|
||||
*resp.status_mut() = StatusCode::NOT_FOUND;
|
||||
Ok(resp)
|
||||
}
|
||||
}))
|
||||
});
|
||||
|
||||
println!("Proxy server running at http://{}", addr);
|
||||
|
||||
if let Err(e) = Server::bind(&addr).serve(make_svc).await {
|
||||
eprintln!("server error: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes a specified prefix from the request's URI path
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `req` - The original request
|
||||
/// * `prefix` - The prefix to remove from the path (e.g., "/calendar")
|
||||
///
|
||||
/// # Returns
|
||||
/// A new request with the modified path
|
||||
fn remove_path_prefix(req: Request<Body>, prefix: &str) -> Request<Body> {
|
||||
let (parts, body) = req.into_parts();
|
||||
let mut new_parts = parts;
|
||||
|
||||
// Get the original path for prefix calculation
|
||||
let original_path = new_parts.uri.path();
|
||||
|
||||
// Calculate the prefix length (including the trailing slash if present)
|
||||
let prefix_len = if original_path.starts_with(&format!("{}/", prefix)) {
|
||||
prefix.len() + 1
|
||||
} else {
|
||||
prefix.len()
|
||||
};
|
||||
|
||||
// Build a new URI with the prefix removed
|
||||
let mut uri_builder = hyper::Uri::builder()
|
||||
.scheme(new_parts.uri.scheme_str().unwrap_or("http"));
|
||||
|
||||
// Only set authority if it exists
|
||||
if let Some(auth) = new_parts.uri.authority() {
|
||||
uri_builder = uri_builder.authority(auth.clone());
|
||||
}
|
||||
|
||||
// Create path and query string
|
||||
let mut path_query = original_path[prefix_len..].to_string();
|
||||
|
||||
// Add query parameters if they exist
|
||||
if let Some(q) = new_parts.uri.query() {
|
||||
path_query.push('?');
|
||||
path_query.push_str(q);
|
||||
}
|
||||
|
||||
let new_uri = uri_builder
|
||||
.path_and_query(path_query)
|
||||
.build()
|
||||
.unwrap_or(new_parts.uri.clone());
|
||||
|
||||
new_parts.uri = new_uri;
|
||||
Request::from_parts(new_parts, body)
|
||||
}
|
Reference in New Issue
Block a user