aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 01df3fbdfd06386dcf52df9b26c9388bf9600550 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::str;

enum StatusCode {
    // 2xx Success
    Ok,
    // Created = 201,
    // Accepted = 202,
    // NonAuthoritative = 203,
    // NoContent = 204,
    // ResetContent = 205,
    // PartialContent = 206,

    // 4xx Client Error
    BadRequest,
}

impl From<StatusCode> for String {
    fn from(val: StatusCode) -> Self {
        use StatusCode::*;
        match val {
            Ok => "200 OK".to_string(),
            BadRequest => "400 Bad Request".to_string(),
        }
    }
}

struct HTTPResponse {
    version: String,
    status: StatusCode,
    headers: Option<String>,
    body: Option<String>,
}

impl HTTPResponse {
    fn new(
        version: String,
        status: StatusCode,
        headers: Option<String>,
        body: Option<String>,
    ) -> Self {
        HTTPResponse {
            version,
            status,
            headers,
            body,
        }
    }
}

impl Into<String> for HTTPResponse {
    fn into(self) -> String {
        format!(
            "HTTP/{} {}\r\n{}\r\n{}",
            self.version,
            String::from(self.status),
            self.headers.unwrap_or("".to_string()),
            self.body.unwrap_or("".to_string())
        )
    }
}

fn handle_client(mut stream: TcpStream) {
    // Buffer to store the data received from the client
    let mut buffer = [0; 512];

    // Read data from the stream
    match stream.read(&mut buffer) {
        Ok(_) => {
            // Convert buffer to a string and print the received data
            if let Ok(request) = str::from_utf8(&buffer) {
                println!("Received request: {}", request);
            }

            // Prepare a response
            // let response = b"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello, world!";
            let response: String =
                HTTPResponse::new("1.1".to_string(), StatusCode::Ok, None, None).into();
            let response = response.as_bytes();

            // Write response to the stream
            match stream.write(response) {
                Ok(_) => println!("Response sent successfully"),
                Err(e) => eprintln!("Failed to send response: {}", e),
            }
        }
        Err(e) => {
            eprintln!("Failed to read from stream: {}", e);
        }
    }
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:4221").unwrap();

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                // println!("accepted new connection");
                handle_client(stream)
            }
            Err(e) => {
                eprintln!("error: {}", e);
            }
        }
    }
}