X-Git-Url: https://piware.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=tokio-tutorial-jbarszczewski%2Fsrc%2Fmain.rs;h=f998acc288997a887307ef57b4eb129b85e7b540;hb=acfe8f5f123d63623559446d08a01bf29987e5b1;hp=5d49be551efef52c54ac9d9e2a12fc52029e249e;hpb=3999f76777dd4654553d944fb9e309150df8582f;p=learn-rust.git diff --git a/tokio-tutorial-jbarszczewski/src/main.rs b/tokio-tutorial-jbarszczewski/src/main.rs index 5d49be5..f998acc 100644 --- a/tokio-tutorial-jbarszczewski/src/main.rs +++ b/tokio-tutorial-jbarszczewski/src/main.rs @@ -1,18 +1,52 @@ -use tokio::io::AsyncWriteExt; -use tokio::net::{TcpListener, TcpStream}; +use std::str; +use std::sync::{ Arc, Mutex }; + +use tokio::io::{ AsyncReadExt, AsyncWriteExt }; +use tokio::net::{ TcpListener, TcpStream }; #[tokio::main] async fn main() { + let balance = Arc::new(Mutex::new(0.0f64)); let listener = TcpListener::bind("127.0.0.1:8181").await.unwrap(); loop { let (stream, _) = listener.accept().await.unwrap(); - handle_connection(stream).await; + let balance_ref = balance.clone(); + tokio::spawn(async move { handle_connection(stream, balance_ref).await }); } } -async fn handle_connection(mut stream: TcpStream) { - let contents = "{\"balance\": 0.00}"; +async fn handle_connection(mut stream: TcpStream, balance: Arc>) { + // Read the first 16 characters from the incoming stream + let mut buffer = [0; 16]; + assert!(stream.read(&mut buffer).await.unwrap() >= 16); + // First 4 characters are used to detect HTTP method + let method_type = match str::from_utf8(&buffer[0..4]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; + + let contents = match method_type { + "GET " => { + format!("{{\"balance\": {}}}", balance.lock().unwrap()) + } + "POST" => { + // Take characters after 'POST /' until whitespace is detected. + let input: String = buffer[6..16] + .iter() + .take_while(|x| **x != 32u8) + .map(|x| *x as char) + .collect(); + let balance_update = input.parse::().unwrap(); + println!("got POST request to update by {}", balance_update); + let mut locked_balance = balance.lock().unwrap(); + *locked_balance += balance_update; + format!("{{\"balance\": {}}}", locked_balance) + } + _ => { + panic!("Invalid HTTP method!") + } + }; let response = format!( "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}",