use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::time::{Duration, Instant};
use thread_share::{enhanced_share, spawn_workers};
#[derive(Clone, Debug)]
struct HttpServer {
port: u16,
is_running: bool,
requests_handled: u32,
start_time: Option<Instant>,
active_connections: u32,
}
impl HttpServer {
fn new(port: u16) -> Self {
Self {
port,
is_running: false,
requests_handled: 0,
start_time: None,
active_connections: 0,
}
}
fn start(&mut self) -> Result<(), String> {
self.is_running = true;
self.start_time = Some(Instant::now());
println!("๐ HTTP Server started on port {}", self.port);
Ok(())
}
fn stop(&mut self) {
self.is_running = false;
println!("๐ HTTP Server stopped");
}
fn handle_request(&mut self, stream: &mut TcpStream) -> Result<bool, String> {
let mut buffer = [0; 1024];
let bytes_read = stream.read(&mut buffer).map_err(|e| e.to_string())?;
if bytes_read == 0 {
return Ok(false);
}
let request = String::from_utf8_lossy(&buffer[..bytes_read]);
let lines: Vec<&str> = request.lines().collect();
if lines.is_empty() {
return Ok(false);
}
let first_line = lines[0];
let parts: Vec<&str> = first_line.split_whitespace().collect();
if parts.len() >= 2 {
let method = parts[0];
let path = parts[1];
println!("๐ฅ {} {}", method, path);
let response = self.process_request(method, path);
stream
.write_all(response.as_bytes())
.map_err(|e| e.to_string())?;
stream.flush().map_err(|e| e.to_string())?;
std::thread::sleep(Duration::from_millis(100));
let is_main_page = matches!(path, "/" | "/status" | "/health");
if is_main_page {
self.requests_handled += 1;
}
return Ok(is_main_page);
}
Ok(false)
}
fn process_request(&self, method: &str, path: &str) -> String {
match (method, path) {
("GET", "/") => {
format!(
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: {}\r\nConnection: close\r\n\r\n\
<html><body><h1>Hello from Rust HTTP Server!</h1>\
<p>Server running on port {}</p>\
<p>Requests handled: {}</p>\
<p>Uptime: {}</p>\
</body></html>",
self.get_home_page_length(),
self.port,
self.requests_handled,
self.get_uptime()
)
}
("GET", "/status") => {
let status = format!(
"{{\"status\": \"running\", \"port\": {}, \"requests\": {}, \"uptime\": \"{}\"}}",
self.port,
self.requests_handled,
self.get_uptime()
);
format!(
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
status.len(),
status
)
}
("GET", "/health") => {
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 2\r\nConnection: close\r\n\r\nOK".to_string()
}
_ => {
"HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 21\r\nConnection: close\r\n\r\n404 - Page not found".to_string()
}
}
}
fn get_uptime(&self) -> String {
if let Some(start_time) = self.start_time {
let elapsed = start_time.elapsed();
let secs = elapsed.as_secs();
let mins = secs / 60;
let secs = secs % 60;
format!("{}m {}s", mins, secs)
} else {
"0s".to_string()
}
}
fn increment_connections(&mut self) {
self.active_connections += 1;
}
fn decrement_connections(&mut self) {
if self.active_connections > 0 {
self.active_connections -= 1;
}
}
fn get_home_page_length(&self) -> usize {
let content = format!(
"<html><body><h1>Hello from Rust HTTP Server!</h1>\
<p>Server running on port {}</p>\
<p>Requests handled: {}</p>\
<p>Uptime: {}</p>\
</body></html>",
self.port,
self.requests_handled,
self.get_uptime()
);
content.len()
}
}
fn main() {
println!("=== Simple HTTP Server with ThreadShare ===");
let port = 8445;
println!("๐ Using port: {}", port);
let server = enhanced_share!(HttpServer::new(port));
let visits = enhanced_share!(0);
let visits_clone = visits.clone();
spawn_workers!(server, {
server_main: move |server: thread_share::ThreadShare<HttpServer>| {
println!("๐ Server main thread started");
server.update(|s| s.start().expect("Failed to start server"));
let port = server.get().port;
let listener =
TcpListener::bind(format!("127.0.0.1:{}", port)).expect("Failed to bind");
println!("๐ Listening on http://127.0.0.1:{}", port);
println!("๐ Server URLs:");
println!(" โข Main page: http://127.0.0.1:{}/", port);
println!(" โข Status: http://127.0.0.1:{}/status", port);
println!(" โข Health: http://127.0.0.1:{}/health", port);
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
server.update(|s| s.increment_connections());
let is_main_page = server.write(|s| s.handle_request(&mut stream)).unwrap_or_else(|e| {
eprintln!("โ Error handling request: {}", e);
false
});
if is_main_page {
visits_clone.update(|v| *v += 1);
println!("๐ Main page visit - visits: {}", visits_clone.get());
}
server.update(|s| s.decrement_connections());
std::thread::sleep(Duration::from_millis(200));
}
Err(e) => {
eprintln!("โ Connection failed: {}", e);
}
}
if !server.get().is_running {
break;
}
}
println!("๐ Server main thread finished");
},
monitor: |server: thread_share::ThreadShare<HttpServer>| {
println!("๐ Monitor thread started");
for _ in 1..=30 {
let current_server = server.get();
if current_server.is_running {
println!("๐ Server Status: Running | Port: {} | Requests: {} | Connections: {} | Uptime: {}",
current_server.port,
current_server.requests_handled,
current_server.active_connections,
current_server.get_uptime()
);
}
std::thread::sleep(Duration::from_secs(2));
}
println!("โฐ Stopping server after 1 minute...");
server.update(|s| s.stop());
println!("๐ Monitor thread finished");
}
});
println!("๐ HTTP Server Example Started");
println!("๐ Server will run for 1 minute");
println!("๐งต Active threads: {}", server.active_threads());
server.join_all().expect("Failed to join threads");
let final_server = server.get();
let final_visits = visits.get();
println!("\n=== ๐ Final Results ===");
println!(
"๐ Server status: {}",
if final_server.is_running {
"Running"
} else {
"Stopped"
}
);
println!(
"๐ Total requests handled: {}",
final_server.requests_handled
);
println!("โฑ๏ธ Total uptime: {}", final_server.get_uptime());
println!("๐๏ธ Total visits: {}", final_visits);
println!("\nโ
Example completed successfully!");
println!("๐ฏ This example demonstrates:");
println!(" โข Using thread_setup! macro for simplified server setup");
println!(" โข Simple HTTP server implementation");
println!(" โข Multi-threaded server with monitoring");
println!(" โข Real-time server statistics");
println!(" โข Graceful server shutdown");
}