work done in school
This commit is contained in:
parent
320a93118f
commit
860ddc7cf4
37 changed files with 146 additions and 18 deletions
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "multiplayer-game"
|
||||
version = "0.1.0"
|
||||
119
src/request.rs
119
src/request.rs
|
|
@ -1,11 +1,13 @@
|
|||
use crate::shared_enums::ContentType;
|
||||
use std::{
|
||||
io::{self, BufRead, BufReader, Read},
|
||||
io::{self, BufRead, BufReader, Read, Take},
|
||||
net::TcpStream,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
const MAX_LINE_WIDTH: u64 = 4096; // 4 KiB
|
||||
const MAX_BODY_LENGTH: u64 = 8388608; // 5 MiB
|
||||
const MAX_HEADER_COUNT: u64 = 512;
|
||||
|
||||
pub struct Request {
|
||||
method: Method,
|
||||
|
|
@ -23,37 +25,96 @@ pub enum RequestHeader {
|
|||
Other(String, String),
|
||||
}
|
||||
|
||||
impl FromStr for RequestHeader {
|
||||
type Err = io::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let
|
||||
}
|
||||
}
|
||||
|
||||
impl Request {
|
||||
pub fn from_bufreader(buffer: BufReader<&TcpStream>) -> io::Result<Self> {
|
||||
let mut first_line = Vec::<u8>::new();
|
||||
|
||||
let mut limited_buffer = buffer.take(MAX_LINE_WIDTH);
|
||||
limited_buffer.read_until(b'\n', &mut first_line)?;
|
||||
|
||||
println!("{}", String::from_utf8_lossy(&first_line));
|
||||
first_line.clear();
|
||||
|
||||
limited_buffer.set_limit(MAX_LINE_WIDTH);
|
||||
limited_buffer.read_until(b'\n', &mut first_line)?;
|
||||
|
||||
println!("{}", String::from_utf8_lossy(&first_line));
|
||||
let first_line = Self::read_line(&mut limited_buffer)?;
|
||||
let parsed_first_line = Self::parse_first_line(first_line)?;
|
||||
|
||||
Ok(Self {
|
||||
method: Method::Get,
|
||||
http_version: "HTTP/1.1".to_string(),
|
||||
path: ServerPath {
|
||||
path: vec![],
|
||||
options: vec![],
|
||||
},
|
||||
method: parsed_first_line.0,
|
||||
path: parsed_first_line.1,
|
||||
http_version: parsed_first_line.2,
|
||||
headers: vec![],
|
||||
data: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
fn read_line(buffer: &mut Take<BufReader<&TcpStream>>) -> io::Result<String> {
|
||||
let mut read_buffer = vec![];
|
||||
buffer.set_limit(MAX_LINE_WIDTH);
|
||||
buffer.read_until(b'\n', &mut read_buffer)?;
|
||||
|
||||
Ok(String::from_utf8_lossy(&read_buffer).to_string())
|
||||
}
|
||||
|
||||
fn parse_first_line(line: String) -> io::Result<(Method, ServerPath, String)> {
|
||||
let splitted_line: Vec<&str> = line.split_whitespace().collect();
|
||||
|
||||
match splitted_line.as_slice() {
|
||||
[method, path, "HTTP/1.1"] => Ok((
|
||||
Method::from_str(method)?,
|
||||
ServerPath::from_str(path)?,
|
||||
"HTTP/1.1".to_string(),
|
||||
)),
|
||||
_ => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Incorrect HTTP first line",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ServerPath {
|
||||
path: Vec<String>,
|
||||
options: Vec<(String, String)>,
|
||||
query: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
impl FromStr for ServerPath {
|
||||
type Err = io::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.split("?").collect::<Vec<&str>>().as_slice() {
|
||||
[path, query] => {
|
||||
let mut query_hashset: std::collections::hash_set::HashSet<String> =
|
||||
std::collections::hash_set::HashSet::new();
|
||||
|
||||
let query_parsed = query
|
||||
.split('&')
|
||||
.filter_map(|s| match s.split('=').collect::<Vec<&str>>().as_slice() {
|
||||
[parameter, value] => {
|
||||
if query_hashset.contains(*parameter) {
|
||||
None
|
||||
} else {
|
||||
query_hashset.insert(parameter.to_string());
|
||||
Some((parameter.to_string(), value.to_string()))
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Self {
|
||||
path: path
|
||||
.split('/')
|
||||
.filter(|s| !s.is_empty() && !s.starts_with('.'))
|
||||
.map(|s| s.to_string())
|
||||
.collect(),
|
||||
query: query_parsed,
|
||||
})
|
||||
}
|
||||
_ => Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid path")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Method {
|
||||
|
|
@ -67,3 +128,25 @@ pub enum Method {
|
|||
Put,
|
||||
Trace,
|
||||
}
|
||||
|
||||
impl FromStr for Method {
|
||||
type Err = io::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"GET" => Ok(Self::Get),
|
||||
"POST" => Ok(Self::Post),
|
||||
"CONNECT" => Ok(Self::Connect),
|
||||
"DELETE" => Ok(Self::Delete),
|
||||
"HEAD" => Ok(Self::Head),
|
||||
"OPTIONS" => Ok(Self::Options),
|
||||
"PATCH" => Ok(Self::Patch),
|
||||
"PUT" => Ok(Self::Put),
|
||||
"TRACE" => Ok(Self::Trace),
|
||||
_ => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Invalid HTTP method",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
target/.rustc_info.json
Normal file
1
target/.rustc_info.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"rustc_fingerprint":12116297598588159345,"outputs":{"12016735552878863467":{"success":true,"status":"","code":0,"stdout":"rustc 1.90.0 (1159e78c4 2025-09-14)\nbinary: rustc\ncommit-hash: 1159e78c4747b02ef996e55082b704c09b970588\ncommit-date: 2025-09-14\nhost: x86_64-unknown-linux-gnu\nrelease: 1.90.0\nLLVM version: 20.1.8\n","stderr":""},"13822592305234237280":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/nix/store/ahixbqp1sm5vwzc19hz30vxvbkh7scxd-rust-default-1.90.0\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
|
||||
3
target/CACHEDIR.TAG
Normal file
3
target/CACHEDIR.TAG
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Signature: 8a477f597d28d172789f06886806bc55
|
||||
# This file is a cache directory tag created by cargo.
|
||||
# For information about cache directory tags see https://bford.info/cachedir/
|
||||
0
target/debug/.cargo-lock
Normal file
0
target/debug/.cargo-lock
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"rustc":16285725380928457773,"features":"[]","declared_features":"[]","target":6229377420918840853,"profile":17672942494452627365,"path":4942398508502643691,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/multiplayer-game-1e29189d72d8e29f/dep-bin-multiplayer-game","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
This file has an mtime of when this was started.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{"$message_type":"diagnostic","message":"expected pattern, found `}`","code":null,"level":"error","spans":[{"file_name":"src/request.rs","byte_start":696,"byte_end":697,"line_start":33,"line_end":33,"column_start":5,"column_end":6,"is_primary":true,"text":[{"text":" }","highlight_start":5,"highlight_end":6}],"label":"expected pattern","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: expected pattern, found `}`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/request.rs:33:5\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m33\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m }\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mexpected pattern\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused variable: `req`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/main.rs","byte_start":351,"byte_end":354,"line_start":17,"line_end":17,"column_start":13,"column_end":16,"is_primary":true,"text":[{"text":" let req = request::Request::from_bufreader(reader)?;","highlight_start":13,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/main.rs","byte_start":351,"byte_end":354,"line_start":17,"line_end":17,"column_start":13,"column_end":16,"is_primary":true,"text":[{"text":" let req = request::Request::from_bufreader(reader)?;","highlight_start":13,"highlight_end":16}],"label":null,"suggested_replacement":"_req","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `req`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/main.rs:17:13\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m17\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let req = request::Request::from_bufreader(reader)?;\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_req`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_variables)]` on by default\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"aborting due to 1 previous error; 1 warning emitted","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to 1 previous error; 1 warning emitted\u001b[0m\n\n"}
|
||||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
This file has an mtime of when this was started.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{"$message_type":"diagnostic","message":"expected pattern, found `}`","code":null,"level":"error","spans":[{"file_name":"src/request.rs","byte_start":696,"byte_end":697,"line_start":33,"line_end":33,"column_start":5,"column_end":6,"is_primary":true,"text":[{"text":" }","highlight_start":5,"highlight_end":6}],"label":"expected pattern","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: expected pattern, found `}`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/request.rs:33:5\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m33\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m }\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mexpected pattern\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused variable: `req`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/main.rs","byte_start":351,"byte_end":354,"line_start":17,"line_end":17,"column_start":13,"column_end":16,"is_primary":true,"text":[{"text":" let req = request::Request::from_bufreader(reader)?;","highlight_start":13,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/main.rs","byte_start":351,"byte_end":354,"line_start":17,"line_end":17,"column_start":13,"column_end":16,"is_primary":true,"text":[{"text":" let req = request::Request::from_bufreader(reader)?;","highlight_start":13,"highlight_end":16}],"label":null,"suggested_replacement":"_req","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `req`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/main.rs:17:13\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m17\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let req = request::Request::from_bufreader(reader)?;\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_req`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_variables)]` on by default\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"aborting due to 1 previous error; 1 warning emitted","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to 1 previous error; 1 warning emitted\u001b[0m\n\n"}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"rustc":16285725380928457773,"features":"[]","declared_features":"[]","target":6229377420918840853,"profile":3316208278650011218,"path":4942398508502643691,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/multiplayer-game-32d5f81cae032a2c/dep-test-bin-multiplayer-game","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
12
target/debug/deps/multiplayer_game-1e29189d72d8e29f.d
Normal file
12
target/debug/deps/multiplayer_game-1e29189d72d8e29f.d
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/home/maxag/Projects/Rust/multiplayer-game/target/debug/deps/multiplayer_game-1e29189d72d8e29f.d: src/main.rs src/request.rs src/response.rs src/shared_enums.rs Cargo.toml
|
||||
|
||||
/home/maxag/Projects/Rust/multiplayer-game/target/debug/deps/libmultiplayer_game-1e29189d72d8e29f.rmeta: src/main.rs src/request.rs src/response.rs src/shared_enums.rs Cargo.toml
|
||||
|
||||
src/main.rs:
|
||||
src/request.rs:
|
||||
src/response.rs:
|
||||
src/shared_enums.rs:
|
||||
Cargo.toml:
|
||||
|
||||
# env-dep:CLIPPY_ARGS=--no-deps__CLIPPY_HACKERY__
|
||||
# env-dep:CLIPPY_CONF_DIR
|
||||
12
target/debug/deps/multiplayer_game-32d5f81cae032a2c.d
Normal file
12
target/debug/deps/multiplayer_game-32d5f81cae032a2c.d
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/home/maxag/Projects/Rust/multiplayer-game/target/debug/deps/multiplayer_game-32d5f81cae032a2c.d: src/main.rs src/request.rs src/response.rs src/shared_enums.rs Cargo.toml
|
||||
|
||||
/home/maxag/Projects/Rust/multiplayer-game/target/debug/deps/libmultiplayer_game-32d5f81cae032a2c.rmeta: src/main.rs src/request.rs src/response.rs src/shared_enums.rs Cargo.toml
|
||||
|
||||
src/main.rs:
|
||||
src/request.rs:
|
||||
src/response.rs:
|
||||
src/shared_enums.rs:
|
||||
Cargo.toml:
|
||||
|
||||
# env-dep:CLIPPY_ARGS=--no-deps__CLIPPY_HACKERY__
|
||||
# env-dep:CLIPPY_CONF_DIR
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue