Created
March 24, 2022 04:34
-
-
Save alexpts/64e6d0d7c10771b7b758133ac44d4392 to your computer and use it in GitHub Desktop.
rust-http-parser.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashMap; | |
struct Message; | |
#[derive(Debug)] | |
struct Request<'a> { | |
body: &'a str, | |
method: &'a str, | |
uri: &'a str, | |
protocol: &'a str, | |
headers: HashMap<&'a str, Vec<&'a str>> | |
} | |
const HEADER_DELIMITER: &'static str = "\r\n"; | |
const BODY_DELIMITER: &'static str = "\r\n\r\n"; | |
impl Message { | |
pub fn parse_blocks(message: &str) -> (&str, &str, &str) { | |
let mut parts: Vec<&str> = message.split(BODY_DELIMITER).collect(); | |
let body: &str = parts.pop().unwrap(); | |
let (start_line, raw_headers) = parts[0].split_once("\r\n").unwrap(); | |
(start_line, raw_headers, body) | |
} | |
pub fn parse_headers(headers: &str) -> HashMap<&str, Vec<&str>> { | |
let mut map: HashMap<&str, Vec<&str>> = HashMap::new(); | |
for header_line in headers.split(HEADER_DELIMITER) { | |
let (name, value) = header_line.split_once(":").unwrap(); | |
let header_values = map.entry(name) | |
.or_insert(Vec::with_capacity(1)); | |
header_values.push(value.trim()); | |
} | |
println!("!!!map: {:#?}", map); | |
map | |
} | |
pub fn parse_start_line_request(start_line: &str) -> (&str, &str, &str) { | |
let mut parts = start_line.split(" "); | |
let method = parts.next().unwrap(); | |
let uri = parts.next().unwrap(); | |
let protocol: &str = &parts.next().unwrap()[5..]; | |
(method, uri, protocol) | |
} | |
} | |
fn main() { | |
let message_raw = "GET / HTTP/1.0\r\nconnection:keep-alive\r\nh1: v1 \r\nuser: 1\r\nuser:2\r\n\r\nHello"; | |
let (start_line, raw_headers, body) = Message::parse_blocks(message_raw); | |
let headers= Message::parse_headers(raw_headers); | |
let (method, uri, protocol) = Message::parse_start_line_request(start_line); | |
let req = Request{ | |
body, | |
headers, | |
method, | |
uri, | |
protocol | |
}; | |
println!("req: {:#?}", req); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment