Samuel Shuert | 2ecef06 | 2024-01-10 16:31:55 -0500 | [diff] [blame^] | 1 | use std::{io::Result, collections::HashMap}; |
| 2 | use tokio::{net::{TcpListener, TcpStream}, io::{AsyncReadExt, AsyncWriteExt}}; |
| 3 | |
codecrafters-bot | 6706158 | 2024-01-10 17:35:39 +0000 | [diff] [blame] | 4 | |
Samuel Shuert | 62c526f | 2024-01-10 15:30:45 -0500 | [diff] [blame] | 5 | use itertools::Itertools; |
Samuel Shuert | f2efffb | 2024-01-10 16:14:01 -0500 | [diff] [blame] | 6 | use nom::AsChar; |
Samuel Shuert | 62c526f | 2024-01-10 15:30:45 -0500 | [diff] [blame] | 7 | |
Samuel Shuert | 2ecef06 | 2024-01-10 16:31:55 -0500 | [diff] [blame^] | 8 | async fn process_socket(mut stream: TcpStream) { |
| 9 | println!("accepted new connection"); |
Samuel Shuert | 3d880f7 | 2024-01-10 14:48:08 -0500 | [diff] [blame] | 10 | |
Samuel Shuert | 2ecef06 | 2024-01-10 16:31:55 -0500 | [diff] [blame^] | 11 | let mut request: HashMap<String, String> = HashMap::new(); |
| 12 | let mut line_num: usize = 0; |
| 13 | loop { |
| 14 | let mut line = String::default(); |
Samuel Shuert | e4ee873 | 2024-01-10 14:42:09 -0500 | [diff] [blame] | 15 | |
Samuel Shuert | 2ecef06 | 2024-01-10 16:31:55 -0500 | [diff] [blame^] | 16 | loop { |
| 17 | let mut buf: [u8; 1] = [0; 1]; |
| 18 | stream.read_exact(&mut buf).await.unwrap(); |
Samuel Shuert | 3d880f7 | 2024-01-10 14:48:08 -0500 | [diff] [blame] | 19 | |
Samuel Shuert | 2ecef06 | 2024-01-10 16:31:55 -0500 | [diff] [blame^] | 20 | let character = buf[0].as_char(); |
| 21 | if character == '\n' { |
| 22 | break |
| 23 | } else if character != '\r' { |
| 24 | line.push(character); |
Samuel Shuert | f10dce9 | 2024-01-10 14:31:46 -0500 | [diff] [blame] | 25 | } |
| 26 | } |
Samuel Shuert | 2ecef06 | 2024-01-10 16:31:55 -0500 | [diff] [blame^] | 27 | |
| 28 | if line_num == 0 { |
| 29 | let mut splits = line.split(' '); |
| 30 | request.insert("method".to_owned(), splits.next().unwrap().to_owned()); |
| 31 | request.insert("path".to_owned(), splits.next().unwrap().to_owned()); |
| 32 | } else { |
| 33 | let mut splits = line.split(": "); |
| 34 | let key = splits.next().unwrap(); |
| 35 | let value = splits.next().unwrap(); |
| 36 | request.insert(key.to_owned(), value.to_owned()); |
| 37 | } |
| 38 | |
| 39 | if request.contains_key("User-Agent") { break }; |
| 40 | line_num += 1; |
| 41 | } |
| 42 | |
| 43 | println!("{:?}", request); |
| 44 | |
| 45 | let mut path = request.get("path").unwrap().split("/"); |
| 46 | |
| 47 | let response_status: String; |
| 48 | let mut response_headers: Vec<String> = vec![]; |
| 49 | let response_body: String; |
| 50 | |
| 51 | // println!("{:?}", path); |
| 52 | |
| 53 | path.next().unwrap(); |
| 54 | |
| 55 | match path.next().unwrap() { |
| 56 | "" => { |
| 57 | response_status = "200 OK".into(); |
| 58 | response_body = "".into(); |
| 59 | }, |
| 60 | "echo" => { |
| 61 | response_status = "200 OK".into(); |
| 62 | response_body = path.join("/"); |
| 63 | response_headers.push("Content-Type: text/plain".into()); |
| 64 | }, |
| 65 | "user-agent" => { |
| 66 | response_status = "200 OK".into(); |
| 67 | response_body = request.get("User-Agent").unwrap().into(); |
| 68 | response_headers.push("Content-Type: text/plain".into()); |
| 69 | }, |
| 70 | _ => { |
| 71 | response_status = "404 Not Found".into(); |
| 72 | response_body = "".into(); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | if response_body.len() > 0 { |
| 77 | response_headers.push(format!("Content-Length: {}", response_body.len())); |
| 78 | } |
| 79 | |
| 80 | stream.write(format!("HTTP/1.1 {response_status}\r\n{}\r\n\r\n{response_body}", response_headers.join("\r\n")).as_bytes()).await.unwrap(); |
| 81 | |
| 82 | } |
| 83 | |
| 84 | #[tokio::main] |
| 85 | async fn main() -> Result<()> { |
| 86 | let listener = TcpListener::bind("127.0.0.1:4221").await?; |
| 87 | let mut futures = vec![]; |
| 88 | |
| 89 | loop { |
| 90 | let (socket, _) = listener.accept().await?; |
| 91 | futures.push(process_socket(socket)); |
Samuel Shuert | f10dce9 | 2024-01-10 14:31:46 -0500 | [diff] [blame] | 92 | } |
codecrafters-bot | 6706158 | 2024-01-10 17:35:39 +0000 | [diff] [blame] | 93 | } |