Addition of the gemini feature as well as Url, wrap_url and unwrap_url.
This commit is contained in:
parent
7d5530370f
commit
6c4028e48c
3 changed files with 124 additions and 1 deletions
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "packeteer"
|
||||
description = "An attempt at a Rust library that can be used to assist in programmatically analysing, serving and handling received protocol packets."
|
||||
version = "0.1.4"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
authors = ["Celeste <colean@colean.cc>"]
|
||||
license = "LGPL-3.0-or-later"
|
||||
|
@ -16,5 +16,6 @@ all-features = true
|
|||
|
||||
[features]
|
||||
http1 = []
|
||||
gemini = []
|
||||
|
||||
[dependencies]
|
||||
|
|
85
src/gemini.rs
Normal file
85
src/gemini.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
//! A module for handling Gemini operations.
|
||||
//! It contains structures for Gemini requests and responses as well as functions for generating, unpacking and constructing them.
|
||||
use super::{Url, wrap_url, unwrap_url};
|
||||
use std::str::FromStr;
|
||||
|
||||
// A structure for Gemini requests.
|
||||
// Generated with packeteer::gemini::generate_request
|
||||
#[derive(Debug)]
|
||||
pub struct GeminiRequest {
|
||||
pub url: Url,
|
||||
}
|
||||
|
||||
// A structure for Gemini responses.
|
||||
// Generated with packeteer::gemini::generate_response
|
||||
#[derive(Debug)]
|
||||
pub struct GeminiResponse {
|
||||
pub code: i32,
|
||||
pub meta: String,
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
// A function for generating GeminiRequest structures.
|
||||
pub fn generate_request(url: &str) -> GeminiRequest {
|
||||
let wurl = wrap_url(url);
|
||||
let gem = GeminiRequest { url: wurl };
|
||||
return gem
|
||||
}
|
||||
|
||||
// A function for generating GeminiResponse structures.
|
||||
// Any invalid status code (valid status codes are 69 > x >= 10) will automatically be switched to 40 (Temporary failure).
|
||||
pub fn generate_response(code: i32, body: &str) -> GeminiResponse {
|
||||
let mut xcode = code;
|
||||
if code < 10 { xcode = 40 };
|
||||
if code > 69 { xcode = 40 };
|
||||
let res = GeminiResponse { code: xcode, meta: "".to_string(), body: body.to_string() };
|
||||
return res
|
||||
}
|
||||
|
||||
// A function for converting GeminiRequest structures into a Gemini request string.
|
||||
// This is extremely simple since GeminiRequest is basically storing a Url.
|
||||
// Unpacking functions are simply taking the data stored in the structure and concatenating it into a string so nothing changes apart from the conversion.
|
||||
pub fn unpack_request(req: GeminiRequest) -> String {
|
||||
let url = unwrap_url(req.url);
|
||||
let string = format!("{}\r\n", url);
|
||||
return string.to_string()
|
||||
}
|
||||
|
||||
// A function for converting GeminiResponse structures into split header and body strings.
|
||||
// The header and body are split as the Gemini specification seperates them.
|
||||
// Unpacking functions are simply taking the data stored in the structure and concatenating it into a string so nothing changes apart from the conversion.
|
||||
pub fn unpack_response(res: GeminiResponse) -> (String, String) {
|
||||
let string = format!("{} {}\r\n", res.code, res.meta);
|
||||
return (string.to_string(), res.body)
|
||||
}
|
||||
|
||||
// A function for converting Gemini request strings into GeminiRequest.
|
||||
// This is essentially equivalent to packeteer::gemini::generate_request apart from the fact it automatically removes the character return and line feed after the URL to allow for conversion from raw Gemini requests.
|
||||
// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the request stays relatively unchanged.
|
||||
pub fn construct_request(req: &str) -> GeminiRequest {
|
||||
let url: Vec<&str> = req.split("\r\n").collect();
|
||||
let wurl = wrap_url(url[0]);
|
||||
let gem = GeminiRequest { url: wurl };
|
||||
return gem
|
||||
}
|
||||
|
||||
// A function for converting Gemini header and body strings into GeminiResponse.
|
||||
// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the response stays relatively unchanged.
|
||||
pub fn construct_response(res: &str, body: &str) -> GeminiResponse {
|
||||
let split1: Vec<&str> = res.split("\r\n").collect();
|
||||
let split2: Vec<&str> = split1[0].split(" ").collect();
|
||||
let mut meta = "".to_string();
|
||||
for v in &split2 {
|
||||
if v != &split2[0] {
|
||||
if meta == "" {
|
||||
meta = v.to_string();
|
||||
} else {
|
||||
meta = format!("{} {}", meta, v.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let n: i32 = FromStr::from_str(split2[0]).unwrap();
|
||||
let resp = GeminiResponse { code: n, meta: meta.to_string(), body: body.to_string() };
|
||||
return resp
|
||||
}
|
37
src/lib.rs
37
src/lib.rs
|
@ -43,5 +43,42 @@ pub fn generate_kvheader(key: &str, value: &str) -> KVHeader {
|
|||
return result
|
||||
}
|
||||
|
||||
/// A global structure for integrating URLs within the structural system of packeteer.
|
||||
/// Can be automatically generated with the function packeteer::wrap_url.
|
||||
#[derive(Debug)]
|
||||
pub struct Url {
|
||||
pub protocol: String,
|
||||
pub domain: String,
|
||||
pub segments: Vec<String>,
|
||||
}
|
||||
|
||||
/// A public function for wrapping a string reference as a Url structure.
|
||||
pub fn wrap_url(input: &str) -> Url {
|
||||
let split1: Vec<&str> = input.split("://").collect();
|
||||
let split2: Vec<&str> = split1[1].split("/").collect();
|
||||
let protocol = split1[0];
|
||||
let domain = split2[0];
|
||||
let mut segments: Vec<String> = vec![];
|
||||
for v in split2 {
|
||||
if v != "" && v != domain {
|
||||
segments.push(v.to_string());
|
||||
}
|
||||
}
|
||||
let url = Url { protocol: protocol.to_string(), domain: domain.to_string(), segments: segments };
|
||||
return url
|
||||
}
|
||||
|
||||
/// A public function for unwrapping a Url structure into a String.
|
||||
pub fn unwrap_url(input: Url) -> String {
|
||||
let mut string = format!("{}://{}", input.protocol, input.domain);
|
||||
for v in input.segments {
|
||||
string = format!("{}/{}", string, v);
|
||||
}
|
||||
return string.to_string();
|
||||
}
|
||||
|
||||
#[cfg(feature = "http1")]
|
||||
pub mod http1;
|
||||
|
||||
#[cfg(feature = "gemini")]
|
||||
pub mod gemini;
|
||||
|
|
Loading…
Reference in a new issue