]> piware.de Git - learn-rust.git/blobdiff - tokio-tutorial-jbarszczewski/src/main.rs
tokio-tutorial-jbarszczewski: Add GET/POST parsing
[learn-rust.git] / tokio-tutorial-jbarszczewski / src / main.rs
index 6e69036614e531eea1354ea7eb8f5b6a83d7bd33..57af76b2c9c46435d30fadb3c85671a2d29249ca 100644 (file)
@@ -1,17 +1,54 @@
-use tokio::join;
+use std::str;
 
-async fn guten_tag() {
-    println!("Guten Tag!");
-}
+use tokio::io::{ AsyncReadExt, AsyncWriteExt };
+use tokio::net::{TcpListener, TcpStream};
 
 #[tokio::main]
 async fn main() {
-    let task1 = tokio::spawn(async {
-        println!("Hello, world!");
-    });
-    let task2 = tokio::spawn(guten_tag());
+    let listener = TcpListener::bind("127.0.0.1:8181").await.unwrap();
+
+    loop {
+        let (stream, _) = listener.accept().await.unwrap();
+        tokio::spawn(async move { handle_connection(stream).await });
+    }
+}
+
+async fn handle_connection(mut stream: TcpStream) {
+    // 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 " => {
+            // todo: return real balance
+            format!("{{\"balance\": {}}}", 0.0)
+        }
+        "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::<f32>().unwrap();
+            // todo: add balance update handling
+            format!("{{\"balance\": {}}}", balance_update)
+        }
+        _ => {
+            panic!("Invalid HTTP method!")
+        }
+    };
 
-    let (r1, r2) = join!(task1, task2);
-    r1.unwrap();
-    r2.unwrap()
+    let response = format!(
+        "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}",
+        contents.len(),
+        contents
+    );
+    assert!(stream.write(response.as_bytes()).await.unwrap() > 0);
+    stream.flush().await.unwrap();
 }