60 lines
1.5 KiB
Rust
60 lines
1.5 KiB
Rust
use std::io::Read;
|
|
use std::net::TcpStream;
|
|
|
|
pub struct Request {
|
|
pub method: String,
|
|
pub path: String,
|
|
pub version: String,
|
|
pub headers: Vec<String>,
|
|
pub body: String,
|
|
}
|
|
|
|
impl Request {
|
|
pub fn from(mut stream: &TcpStream) -> Option<Self> {
|
|
let mut buffer = [0; 16384];
|
|
let _ = stream.read(&mut buffer).ok()?;
|
|
|
|
let mut buffer_v: Vec<_> = buffer.to_vec();
|
|
|
|
buffer_v.pop();
|
|
let raw_req = std::str::from_utf8(&buffer_v).ok()?.to_string();
|
|
let mut request_lines: Vec<&str> = raw_req.split("\r\n").collect();
|
|
|
|
let mut initial_line = request_lines[0].split(' ');
|
|
|
|
let method = initial_line.next().unwrap_or_default().to_string();
|
|
let path = initial_line.next().unwrap_or_default().to_string();
|
|
|
|
let version = if let Some(version) = initial_line.next() {
|
|
version
|
|
.split_once('/')
|
|
.map_or("1.1", |(_, version)| version)
|
|
} else {
|
|
"1.1"
|
|
}
|
|
.to_string();
|
|
|
|
let body = request_lines
|
|
.pop()
|
|
.unwrap_or_default()
|
|
.split_once('\0')
|
|
.map(|(body, _)| body)
|
|
.unwrap_or_default()
|
|
.to_string();
|
|
|
|
request_lines.pop();
|
|
|
|
let mut request_lines = request_lines.into_iter();
|
|
request_lines.next();
|
|
let headers: Vec<String> = request_lines.map(str::to_string).collect();
|
|
|
|
Some(Self {
|
|
method,
|
|
path,
|
|
version,
|
|
headers,
|
|
body,
|
|
})
|
|
}
|
|
}
|