Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • codecraft/webserver
  • sorcaMriete/webserver
  • opnonmicgo/webserver
  • loposuezo/webserver
  • diufeYmike/webserver
  • contbuspecmi/webserver
  • mogamuboun/webserver
  • glabalwelre/webserver
8 results
Show changes
Commits on Source (1)
pub fn add(left: usize, right: usize) -> usize { use std::{
left + right fs,
io::{BufRead, BufReader, Write},
net::{TcpListener, TcpStream},
thread::available_parallelism,
};
use threading::ThreadPool;
mod handlers;
mod routing;
mod threading;
pub struct Config {
address: TcpListener,
workers: usize,
threadpool: ThreadPool,
} }
#[cfg(test)] impl Config {
mod tests { pub fn mount(self, mountpoint: &str, routes: Vec<routing::Route>) {}
use super::*; pub fn launch(self) {
for stream in self.address.incoming() {
let stream = stream.unwrap();
self.threadpool.execute(|| handle_connection(stream))
}
}
}
fn handle_connection(mut stream: TcpStream) {
let buf_reader = BufReader::new(&mut stream);
let http_request: Vec<_> = buf_reader
.lines()
.map(|result| result.unwrap())
.take_while(|line| !line.is_empty())
.collect();
#[test] let status_line = "HTTP/1.1 200 OK";
fn it_works() { let contents = fs::read_to_string("hello.html").unwrap();
let result = add(2, 2); let length = contents.len();
assert_eq!(result, 4);
let response = format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
stream.write_all(response.as_bytes()).unwrap();
}
pub fn build(ip: &str) -> Config {
let listener = TcpListener::bind(ip).unwrap();
let ip = ip.splitn(2, ":").collect::<Vec<&str>>();
if ip.len() != 2 {
panic!("Invalid IP Address");
}
let port = ip[1];
let ip = ip[0];
let workers = available_parallelism().unwrap().get();
let threadpool = ThreadPool::new(workers);
println!(
"\x1b[34m⚙ Configuration\x1b[0m
>> \x1b[34mIp\x1b[0m: {ip}
>> \x1b[34mPort\x1b[0m: {port}
>> \x1b[34mWorkers\x1b[0m: {workers}
\n
Server has launched from {ip}:{port}.
"
);
Config {
address: listener,
workers,
threadpool,
} }
} }
#[cfg(test)]
mod tests {}
pub struct Route;
pub struct RoutInfo;
use std::{
sync::{mpsc, Arc, Mutex},
thread,
};
pub struct ThreadPool {
workers: Vec<Worker>,
sender: Option<mpsc::Sender<Job>>,
}
type Job = Box<dyn FnOnce() + Send + 'static>;
impl ThreadPool {
/// Create a new ThreadPool.
///
/// The size is the number of threads in the pool.
///
/// # Panics
///
/// The `new` function will panic if the size is zero.
pub fn new(size: usize) -> ThreadPool {
assert!(size > 0);
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
let mut workers = Vec::with_capacity(size);
for id in 0..size {
workers.push(Worker::new(id, Arc::clone(&receiver)));
}
ThreadPool {
workers,
sender: Some(sender),
}
}
pub fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
let job = Box::new(f);
self.sender.as_ref().unwrap().send(job).unwrap();
}
}
impl Drop for ThreadPool {
fn drop(&mut self) {
drop(self.sender.take());
for worker in &mut self.workers {
println!("Shutting down worker {}", worker.id);
if let Some(thread) = worker.thread.take() {
thread.join().unwrap();
}
}
}
}
struct Worker {
id: usize,
thread: Option<thread::JoinHandle<()>>,
}
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(move || loop {
let message = receiver.lock().unwrap().recv();
match message {
Ok(job) => {
println!("Worker {id} got a job; executing.");
job();
}
Err(_) => {
println!("Worker {id} disconnected; shutting down.");
break;
}
}
});
Worker {
id,
thread: Some(thread),
}
}
}
...@@ -2,6 +2,13 @@ ...@@ -2,6 +2,13 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "http"
version = "0.1.0"
[[package]] [[package]]
name = "site" name = "site"
version = "0.1.0" version = "0.1.0"
dependencies = [
"http",
]
...@@ -6,3 +6,4 @@ edition = "2021" ...@@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
http = { path = "../core/http" }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello!</title>
</head>
<body>
<h1>Hello!</h1>
<p>Hi from Rust</p>
</body>
</html>
fn main() { fn main() {
println!("Hello, world!"); http::build("192.168.179.2:8000").launch();
} }