From 8dfae36f6224769f6bbf61acc8911ff54eba5887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=90=91=E5=A4=9C?= Date: Wed, 3 Jan 2024 14:43:54 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:arrow=5Fup:=20=E6=9B=B4=E6=96=B0Rust?= =?UTF-8?q?=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f6ab980..b6edc79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -571,18 +571,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -734,18 +734,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", @@ -754,9 +754,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.109" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" +checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" dependencies = [ "itoa", "ryu", @@ -842,9 +842,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.44" +version = "2.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" dependencies = [ "proc-macro2", "quote", @@ -853,18 +853,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", From e93e40d5702d18d2bf98ad1e7c3cec6838e3cffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=90=91=E5=A4=9C?= Date: Wed, 3 Jan 2024 14:48:35 +0800 Subject: [PATCH 2/4] =?UTF-8?q?:rocket:=20:memo:=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=BC=82=E5=B8=B8=E4=BC=A0=E9=80=92=20?= =?UTF-8?q?=E4=BF=AE=E8=AE=A2=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api.rs | 13 ++++++++----- src/exceptions.rs | 10 +++++++++- src/lib.rs | 36 +++++++++++++++++++----------------- src/models/client.rs | 5 +++-- src/models/packet.rs | 13 ++++++++----- src/sessions.rs | 5 ++--- src/utils/encryptor.rs | 42 ++++++++++++++++++++++++++---------------- src/utils/generator.rs | 24 +++++++++++++++++++----- src/utils/parser.rs | 13 +++++++------ 9 files changed, 101 insertions(+), 60 deletions(-) diff --git a/src/api.rs b/src/api.rs index 2944418..ed39b65 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,19 +1,22 @@ -//! # Oblivion API 接口 +//! # Oblivion API Interface //! -//! Oblivion 提供了直接进行 GET、POST、PUT 等请求的方法。 +//! Oblivion provides methods for making direct GET, POST, PUT, etc. requests. use serde_json::Value; use crate::{exceptions::OblivionException, models::client::Response}; use super::sessions::Session; -/// 裸 Oblivion 请求模式 +/// Naked Oblivion Request Mode /// /// ```rust /// use oblivion::api::request; +/// use oblivion::models::client::Response; +/// use oblivion::exceptions::OblivionException; /// -/// async fn run() { -/// request("get", "127.0.0.1:813/get", None, None, true).await.unwrap(); +/// #[tokio::test] +/// async fn run() -> Result { +/// request("get", "127.0.0.1:813/get", None, None, true).await /// } /// ``` pub async fn request( diff --git a/src/exceptions.rs b/src/exceptions.rs index 8633c64..6045737 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -1,5 +1,6 @@ //! # Oblivion 异常 //! 所有 Oblivion 函数的异常均返回`OblivionException`。 +use ring::error::Unspecified; use scrypt::errors::InvalidOutputLen; use thiserror::Error; @@ -44,5 +45,12 @@ pub enum OblivionException { error: elliptic_curve::Error, }, #[error("共享密钥生成时出现异常: {error:?}")] - InvalidOutputLen { error: InvalidOutputLen }, + InvalidOutputLen { + #[from] + error: InvalidOutputLen, + }, + #[error("加密时出现异常: {error:?}")] + EncryptError { error: Unspecified }, + #[error("解密时出现异常: {error:?}")] + DecryptError { error: Unspecified }, } diff --git a/src/lib.rs b/src/lib.rs index 13ba078..2a34f3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,18 +1,20 @@ //! # Oblivion //! -//! Oblivion 是浊莲为确保信息安全而开发的端到端加密协议,这是 Oblivion 的 Rust 实现。 -//! 它在 Python 实现的基础上大大提高了 Oblivion 的安全性、稳定性和并发性。 +//! Oblivion is a Rust implementation of Oblivion,an end-to-end encryption protocol developed by Turbolane to secure information. +//! It greatly improves the security, stability, and concurrency of Oblivion based on the Python implementation. //! -//! 由于 Oblivion 协议中要求的加密算法为 ECDHE 算法,它以高效安全密钥派生方法,使得它可以应用于信息派发和及时通讯。 +//! Since the encryption algorithm required in the Oblivion protocol is the ECDHE algorithm, +//! it is based on an efficient and secure key derivation method, +//! which makes it possible to apply it to message dispatching and just-in-time communication. pub extern crate oblivion_codegen; pub extern crate proc_macro; pub mod api; pub mod exceptions; pub mod sessions; -/// # Oblivion 工具类 +/// # Oblivion Utilities /// -/// Oblivion 的工具类提供了密钥创建,数据加密解密与请求解析处理方法。 +/// Oblivion utility classes provide key creation, data encryption and decryption, and request resolution processing methods. pub mod utils { pub mod decryptor; pub mod encryptor; @@ -21,9 +23,9 @@ pub mod utils { pub mod parser; } -/// # Oblivion 模型 +/// # Oblivion Models /// -/// Oblivion 提供了所有前后端模型,包括数据包构建以及客户端和服务端的构建。 +/// Oblivion provides all front- and back-end models, including packet building as well as client-side and server-side building. pub mod models { pub mod client; pub mod handler; @@ -33,9 +35,9 @@ pub mod models { pub mod server; } -/// 绝对路由宏 +/// Absolute Routing Macros /// -/// 使用路由宏可以简单的实现路由: +/// Routing can be simply implemented using routing macros: /// /// ```rust /// use futures::future::{BoxFuture, FutureExt}; @@ -57,7 +59,7 @@ pub mod models { /// path_route!(&mut router, "/welcome" => welcome); /// ``` /// -/// 上面的路由将会引导路径为`/welcome`或`/welcome/`的请求。 +/// The above route will direct requests with the path `/welcome` or `/welcome/`. #[macro_export] macro_rules! path_route { ($router:expr, $path:expr => $handler:ident) => {{ @@ -70,9 +72,9 @@ macro_rules! path_route { }}; } -/// 起始路由宏 +/// Startswith Routing Macros /// -/// 使用起始路由宏可以简单的实现起始路由: +/// Starting routes can be simply implemented using the start route macro: /// /// ```rust /// use futures::future::{BoxFuture, FutureExt}; @@ -94,7 +96,7 @@ macro_rules! path_route { /// startswith_route!(&mut router, "/welcome" => welcome); /// ``` /// -/// 上面的路由将会引导所有以`/welcome`起始的 Oblivion Location Path String。 +/// The above route will direct all Oblivion Location Path String starting with `/welcome`. #[macro_export] macro_rules! startswith_route { ($router:expr, $path:expr => $handler:ident) => {{ @@ -110,9 +112,9 @@ macro_rules! startswith_route { }}; } -/// 正则路由宏 +/// Regular routing macro /// -/// 使用正则路由宏可以简单的实现正则路由: +/// Regular routing can be simply implemented using regular routing macros: /// /// ```rust /// use futures::future::{BoxFuture, FutureExt}; @@ -134,9 +136,9 @@ macro_rules! startswith_route { /// regex_route!(&mut router, r"^/welcome/.*" => welcome); /// ``` /// -/// 上面的路由将会引导所有以`/welcome/`起始的 Oblivion Location Path String。 +/// The above route will direct all Oblivion Location Path String starting with `/welcome/`. /// -/// 你还可以使用`^/.*`来劫持所有路由。 +/// You can also use `^/. *` to hijack all routes. #[macro_export] macro_rules! regex_route { ($router:expr, $path:expr => $handler:ident) => {{ diff --git a/src/models/client.rs b/src/models/client.rs index ba26ac7..50effa4 100644 --- a/src/models/client.rs +++ b/src/models/client.rs @@ -113,8 +113,9 @@ impl Request { }; self.tcp = Some(Socket::new(tcp)); - if self.tfo {}; - // TODO 在这里启用TCP Fast Open + if self.tfo { + todo!() // 在这里启用TCP Fast Open + }; self.send_header().await?; diff --git a/src/models/packet.rs b/src/models/packet.rs index 7321469..39c3c24 100644 --- a/src/models/packet.rs +++ b/src/models/packet.rs @@ -3,7 +3,7 @@ use crate::utils::gear::Socket; use crate::exceptions::OblivionException; use super::super::utils::decryptor::decrypt_bytes; -use super::super::utils::encryptor::{encrypt_bytes, encrypt_message}; +use super::super::utils::encryptor::{encrypt_bytes, encrypt_plaintext}; use super::super::utils::generator::{generate_random_salt, generate_shared_key}; use super::super::utils::parser::length; @@ -230,9 +230,12 @@ impl OED { serialized_bytes } - pub fn from_json_or_string(&mut self, json_or_str: String) -> Result<&mut Self, ()> { + pub fn from_json_or_string( + &mut self, + json_or_str: String, + ) -> Result<&mut Self, OblivionException> { let (encrypted_data, tag, nonce) = - encrypt_message(json_or_str, &self.aes_key.as_ref().unwrap()); + encrypt_plaintext(json_or_str, &self.aes_key.as_ref().unwrap())?; (self.encrypted_data, self.tag, self.nonce) = (Some(encrypted_data), Some(tag), Some(nonce)); Ok(self) @@ -240,7 +243,7 @@ impl OED { pub fn from_dict(&mut self, dict: Value) -> Result<&mut Self, OblivionException> { let (encrypted_data, tag, nonce) = - encrypt_message(dict.to_string(), &self.aes_key.as_ref().unwrap()); + encrypt_plaintext(dict.to_string(), &self.aes_key.as_ref().unwrap())?; (self.encrypted_data, self.tag, self.nonce) = (Some(encrypted_data), Some(tag), Some(nonce)); Ok(self) @@ -252,7 +255,7 @@ impl OED { } pub fn from_bytes(&mut self, data: Vec) -> Result<&mut Self, OblivionException> { - let (encrypted_data, tag, nonce) = encrypt_bytes(data, &self.aes_key.as_ref().unwrap()); + let (encrypted_data, tag, nonce) = encrypt_bytes(data, &self.aes_key.as_ref().unwrap())?; (self.encrypted_data, self.tag, self.nonce) = (Some(encrypted_data), Some(tag), Some(nonce)); Ok(self) diff --git a/src/sessions.rs b/src/sessions.rs index 79ec84f..544e425 100644 --- a/src/sessions.rs +++ b/src/sessions.rs @@ -6,9 +6,9 @@ use crate::{ models::client::{Request, Response}, }; -/// ## Oblivion 窗口抽象类 +/// ## Oblivion Abstract Session /// -/// 用于连接模型创建请求窗口。 +/// Used to connect to the model and create a request session. pub struct Session; impl Session { @@ -34,7 +34,6 @@ impl Session { let _ = request.prepare(); } - // 发送请求 request.send().await?; request.recv().await } diff --git a/src/utils/encryptor.rs b/src/utils/encryptor.rs index a30fc39..7e20c23 100644 --- a/src/utils/encryptor.rs +++ b/src/utils/encryptor.rs @@ -9,34 +9,44 @@ use ring::aead::NONCE_LEN; use ring::rand::SecureRandom; use ring::rand::SystemRandom; +use crate::exceptions::OblivionException; + use super::gear::RandNonceSequence; -pub fn encrypt_message(message: String, aes_key: &[u8]) -> (Vec, Vec, Vec) { - // 使用 AES 加密数据 - let data = message.as_bytes().to_owned(); +/// Encrypt plaintext using AES +/// +/// `encrypt_messgae`是`encrypt_bytes` +pub fn encrypt_plaintext( + string: String, + aes_key: &[u8], +) -> Result<(Vec, Vec, Vec), OblivionException> { + let data = string.as_bytes().to_owned(); encrypt_bytes(data, aes_key) } -pub fn encrypt_bytes(bytes: Vec, aes_key: &[u8]) -> (Vec, Vec, Vec) { - // 使用 AES 加密数据 - let unbound_key = - UnboundKey::new(&AES_128_GCM, &aes_key).expect("Failed to generate an unboundkey"); +/// Encrypt binary data using AES +pub fn encrypt_bytes( + mut bytes: Vec, + aes_key: &[u8], +) -> Result<(Vec, Vec, Vec), OblivionException> { + let unbound_key = match UnboundKey::new(&AES_128_GCM, &aes_key) { + Ok(key) => key, + Err(error) => return Err(OblivionException::EncryptError { error }), + }; let mut nonce_bytes = vec![0; NONCE_LEN]; let rand = SystemRandom::new(); - match rand.fill(&mut nonce_bytes) { - Ok(_) => {} - Err(_) => {} - }; - let nonce_sequence = RandNonceSequence::new(nonce_bytes.clone()); // Nonce 生成方法 + rand.fill(&mut nonce_bytes).unwrap(); + + let nonce_sequence = RandNonceSequence::new(nonce_bytes.clone()); let mut sealing_key = SealingKey::new(unbound_key, nonce_sequence); let associated_data = Aad::empty(); - let mut in_out = bytes.clone(); - let tag = match sealing_key.seal_in_place_separate_tag(associated_data, &mut in_out) { + + let tag = match sealing_key.seal_in_place_separate_tag(associated_data, &mut bytes) { Ok(result) => result, - Err(_) => return (Vec::new(), Vec::new(), nonce_bytes), + Err(error) => return Err(OblivionException::EncryptError { error }), }; - (in_out, tag.as_ref().to_owned(), nonce_bytes) + Ok((bytes, tag.as_ref().to_owned(), nonce_bytes)) } diff --git a/src/utils/generator.rs b/src/utils/generator.rs index ac4d4c0..ba9110f 100644 --- a/src/utils/generator.rs +++ b/src/utils/generator.rs @@ -9,14 +9,14 @@ use scrypt::{scrypt, Params}; use crate::exceptions::OblivionException; -/// 创建 ECC 密钥 +/// Create an ECC key /// -/// `generate_key_pair`将创建一个`ECC`密钥。 +/// `generate_key_pair` will create an ECC key and return a (private key, public key) pair of `(EphemeralSecret, PublicKey)`. /// /// ```rust /// use oblivion::utils::generator::generate_key_pair; /// -/// let (private_key, public_key) = generate_key_pair(); +/// let (private_key, public_key) = generate_key_pair().unwrap(); /// ``` pub fn generate_key_pair() -> Result<(EphemeralSecret, PublicKey), OblivionException> { let private_key = EphemeralSecret::random(&mut OsRng); @@ -27,7 +27,16 @@ pub fn generate_key_pair() -> Result<(EphemeralSecret, PublicKey), OblivionExcep } } -/// 创建 ECDH 共享密钥 +/// Create an ECDH Shared Key +/// +/// ```rust +/// use oblivion::utils::generator::{generate_key_pair, generate_shared_key, generate_random_salt}; +/// +/// let salt = generate_random_salt(); +/// let (private_key, public_key) = generate_key_pair().unwrap(); +/// +/// let shared_key = generate_shared_key(&private_key, &public_key, &salt).unwrap(); +/// ``` pub fn generate_shared_key( private_key: &EphemeralSecret, public_key: &PublicKey, @@ -46,7 +55,12 @@ pub fn generate_shared_key( } } -/// 生成随机的盐值 +/// Generate a Randomized Salt +/// ```rust +/// use oblivion::utils::generator::generate_random_salt; +/// +/// let salt = generate_random_salt(); +/// ``` pub fn generate_random_salt() -> Vec { let rand = SystemRandom::new(); let mut key_bytes = vec![0; AES_128_GCM.key_len()]; diff --git a/src/utils/parser.rs b/src/utils/parser.rs index 2104cb3..7ccf28a 100644 --- a/src/utils/parser.rs +++ b/src/utils/parser.rs @@ -1,6 +1,6 @@ -//! # Oblivion 解析器 +//! # Oblivion Parser //! -//! 用于对数据进行解析重构并存储。 +//! Used to parse and reconstruct data and store it. use std::collections::HashMap; use std::net::SocketAddr; @@ -8,11 +8,12 @@ use crate::exceptions::OblivionException; use regex::Regex; use serde_json::Value; -/// 数据包大小分析函数 +/// Packet size analysis function /// -/// `length`接受一个`Vec`的字节流,得到其不多于四位数的数据大小,如果数据超出预计范围,它将抛出一个异常。 +/// `length` accepts a `Vec` byte stream, gets its data size in no more than four digits, +/// and throws an exception if the data is out of the expected range. /// -/// 它最终返回的值是一个`Vec`,它由一个四位数以字符串转换而来。 +/// The final value it returns is a `Vec`, which consists of a four-digit number converted to a string. /// /// ```rust /// use oblivion::utils::parser::length; @@ -22,7 +23,7 @@ use serde_json::Value; /// assert_eq!(b"0039".to_vec(), length(&vec).unwrap()); /// ``` /// -/// 以上示例中的`vec`是一个长度为 39 的`Vec`,`length(&vec)`得到了`b"0039".to_vec()`。 +/// The `vec` in the above example is a `Vec` of length 39, and `length(&vec)` gets `b "0039".to_vec()`. pub fn length(bytes: &Vec) -> Result, OblivionException> { let str_num = bytes.len().to_string(); if str_num.len() == 4 { From 8fe0e812ca150b2c1039f50790558a8a89e5f6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=90=91=E5=A4=9C?= Date: Wed, 3 Jan 2024 15:03:51 +0800 Subject: [PATCH 3/4] =?UTF-8?q?:rocket:=20=E4=BF=AE=E8=AE=A2method?= =?UTF-8?q?=E6=89=80=E6=9C=89=E6=9D=83=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/models/server.rs | 12 ++++++------ src/utils/parser.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/models/server.rs b/src/models/server.rs index f7ad45b..ec6059a 100644 --- a/src/models/server.rs +++ b/src/models/server.rs @@ -27,8 +27,8 @@ impl ServerConnection { let (private_key, public_key) = generate_key_pair()?; Ok(Self { - private_key: private_key, - public_key: public_key, + private_key, + public_key, aes_key: None, }) } @@ -48,12 +48,12 @@ impl ServerConnection { oke.from_stream(stream).await?; self.aes_key = Some(oke.get_aes_key()); - if request.get_method() == "POST" { + if request.method == "POST" { let mut oed = OED::new(self.aes_key.clone()); oed.from_stream(stream, 5).await?; request.set_post(from_slice(&oed.get_data()).unwrap()); - } else if request.get_method() == "GET" { - } else if request.get_method() == "PUT" { + } else if request.method == "GET" { + } else if request.method == "PUT" { let mut oed = OED::new(self.aes_key.clone()); oed.from_stream(stream, 5).await?; request.set_post(from_slice(&oed.get_data()).unwrap()); @@ -63,7 +63,7 @@ impl ServerConnection { request.set_put(oed.get_data()); } else { return Err(OblivionException::UnsupportedMethod { - method: request.get_method(), + method: request.method, }); }; Ok(request) diff --git a/src/utils/parser.rs b/src/utils/parser.rs index 7ccf28a..eef7404 100644 --- a/src/utils/parser.rs +++ b/src/utils/parser.rs @@ -141,7 +141,7 @@ impl Oblivion { #[derive(Clone, Debug, PartialEq)] pub struct OblivionRequest { - method: String, + pub(crate) method: String, olps: String, protocol: String, version: String, From 1d90d8276382b42aad46b85437cad88fbcf19fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=90=91=E5=A4=9C?= Date: Wed, 3 Jan 2024 15:26:45 +0800 Subject: [PATCH 4/4] =?UTF-8?q?:memo:=20=E4=BF=AE=E8=AE=A2=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E8=A7=A3=E6=9E=90=E5=B9=B6=E6=96=B0=E5=A2=9E=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E6=96=87=E6=A1=A3=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/models/client.rs | 6 ++-- src/models/packet.rs | 6 +--- src/utils/parser.rs | 72 +++++++++++++++++++++++++++----------------- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/models/client.rs b/src/models/client.rs index 50effa4..ad73515 100644 --- a/src/models/client.rs +++ b/src/models/client.rs @@ -79,7 +79,7 @@ impl Request { let method = method.to_uppercase(); let path = OblivionPath::new(&olps)?; let olps = path.get_olps(); - let oblivion = Oblivion::new(&method, &olps)?; + let oblivion = Oblivion::new(&method, &olps); let plain_text = oblivion.plain_text(); Ok(Self { method, @@ -188,13 +188,13 @@ impl Request { let mut oed = OED::new(self.aes_key.clone()); oed.from_stream(tcp, 5).await?; - let mut osc = OSC::from_stream(tcp).await?; + let osc = OSC::from_stream(tcp).await?; let response = Response::new( self.plain_text.clone(), oed.get_data(), self.olps.clone(), - osc.get_status_code(), + osc.status_code, ); Ok(response) } diff --git a/src/models/packet.rs b/src/models/packet.rs index 39c3c24..96d3b92 100644 --- a/src/models/packet.rs +++ b/src/models/packet.rs @@ -46,7 +46,7 @@ impl ACK { } pub struct OSC { - status_code: i32, + pub status_code: i32, } impl OSC { @@ -72,10 +72,6 @@ impl OSC { let status_code = format!("{}", self.status_code); status_code.into_bytes() } - - pub fn get_status_code(&mut self) -> i32 { - self.status_code - } } pub struct OKE<'a> { diff --git a/src/utils/parser.rs b/src/utils/parser.rs index eef7404..404d87c 100644 --- a/src/utils/parser.rs +++ b/src/utils/parser.rs @@ -40,6 +40,18 @@ pub fn length(bytes: &Vec) -> Result, OblivionException> { Ok(list_num.into_iter().collect::().into_bytes()) } +/// Oblivion Location Path String Parser +/// +/// ```rust +/// use oblivion::utils::parser::OblivionPath; +/// +/// let olps = OblivionPath::new("oblivion://127.0.0.1:813/test").unwrap(); +/// +/// assert_eq!("oblivion".to_string(), olps.get_protocol()); +/// assert_eq!("127.0.0.1".to_string(), olps.get_host()); +/// assert_eq!("813".to_string(), olps.get_port()); +/// assert_eq!("/test".to_string(), olps.get_olps()); +/// ``` pub struct OblivionPath { protocol: String, host: String, @@ -50,7 +62,7 @@ pub struct OblivionPath { impl OblivionPath { pub fn new(obl_str: &str) -> Result { let re = Regex::new( - r"^(?Poblivion)?(?:://)?(?P[^:/]+)(:(?P\d+))?(?P.+)?$", + r"^(?Poblivion)?(?:://)?(?P[^:/]+)(:(?P\d+))?(?P.+)?$", ) .unwrap(); @@ -64,31 +76,27 @@ impl OblivionPath { } } - let protocol = extracted_values - .get("protocol") - .unwrap_or(&None) - .unwrap_or_default() - .to_string(); - let host = extracted_values - .get("host") - .unwrap_or(&None) - .unwrap_or_default() - .to_string(); - let port = extracted_values - .get("port") - .unwrap_or(&Some("80")) - .unwrap_or_default() - .to_string(); - let url = extracted_values - .get("url") - .unwrap_or(&Some("/")) - .unwrap_or_default() - .to_string(); + let protocol = match extracted_values.get("protocol").unwrap() { + Some(result) => result.to_string(), + None => "oblivion".to_string(), + }; + let host = match extracted_values.get("host").unwrap() { + Some(result) => result.to_string(), + None => "oblivion".to_string(), + }; + let port = match extracted_values.get("port").unwrap() { + Some(result) => result.to_string(), + None => "80".to_string(), + }; + let olps = match extracted_values.get("olps").unwrap() { + Some(result) => result.to_string(), + None => "/".to_string(), + }; Ok(Self { - protocol: protocol, - host: host, - port: port, - olps: url, + protocol, + host, + port, + olps, }) } else { Err(OblivionException::InvalidOblivion { @@ -114,6 +122,13 @@ impl OblivionPath { } } +/// Oblivion Request Header Generator +/// +/// ```rust +/// use oblivion::utils::parser::Oblivion; +/// +/// assert_eq!(Oblivion::new("GET", "/test").plain_text().as_str(), "GET /test Oblivion/1.1"); +/// ``` pub struct Oblivion { method: String, olps: String, @@ -121,12 +136,12 @@ pub struct Oblivion { } impl Oblivion { - pub fn new(method: &str, olps: &str) -> Result { - Ok(Self { + pub fn new(method: &str, olps: &str) -> Self { + Self { method: method.to_string(), olps: olps.to_string(), version: "1.1".to_string(), - }) + } } pub fn plain_text(&self) -> String { @@ -139,6 +154,7 @@ impl Oblivion { } } +/// Oblivion Request Header Parser #[derive(Clone, Debug, PartialEq)] pub struct OblivionRequest { pub(crate) method: String,