Introduce FTP support, modify http1 documentation and bump version number
This commit is contained in:
parent
f3279b6188
commit
f407dec4f8
6 changed files with 117 additions and 1 deletions
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "packeteer"
|
name = "packeteer"
|
||||||
description = "An attempt at a Rust library that can be used to assist in programmatically analysing, serving and handling received protocol packets."
|
description = "An attempt at a Rust library that can be used to assist in programmatically analysing, serving and handling received protocol packets."
|
||||||
version = "0.2.2"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Celeste <colean@colean.cc>"]
|
authors = ["Celeste <colean@colean.cc>"]
|
||||||
license = "LGPL-3.0-or-later"
|
license = "LGPL-3.0-or-later"
|
||||||
|
@ -17,5 +17,6 @@ all-features = true
|
||||||
[features]
|
[features]
|
||||||
http1 = []
|
http1 = []
|
||||||
gemini = []
|
gemini = []
|
||||||
|
ftp = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
2
README
2
README
|
@ -5,6 +5,8 @@ Packeteer is a library that can handle structurally organising protocol packets
|
||||||
Supported protocols
|
Supported protocols
|
||||||
-----------------------
|
-----------------------
|
||||||
* HTTP/1.x
|
* HTTP/1.x
|
||||||
|
* Gemini
|
||||||
|
* FTP
|
||||||
|
|
||||||
What Packeteer is not
|
What Packeteer is not
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<h2>Supported protocols</h2>
|
<h2>Supported protocols</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>HTTP/1.x</li>
|
<li>HTTP/1.x</li>
|
||||||
|
<li>Gemini</li>
|
||||||
|
<li>FTP</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>What Packeteer is not</h2>
|
<h2>What Packeteer is not</h2>
|
||||||
|
|
106
src/ftp.rs
Normal file
106
src/ftp.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
//! A module for handling FTP operations.
|
||||||
|
//! It contains structures for FTP requests and responses as well as functions for generating, unpacking and constructing them.
|
||||||
|
|
||||||
|
// unwrap_url not required as we aren't unwrapping Url structures.
|
||||||
|
use super::{Url, wrap_url};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
/// A structure for FTP requests.
|
||||||
|
/// Generated with packeteer::ftp::generate_request
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FTPRequest {
|
||||||
|
pub url: Url,
|
||||||
|
pub command: String,
|
||||||
|
pub arguments: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A structure for FTP responses.
|
||||||
|
/// Generated with packeteer::ftp::generate_response
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FTPResponse {
|
||||||
|
pub code: i32,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function for generating FTPRequest structures.
|
||||||
|
/// The command and arguments are split for convenience.
|
||||||
|
/// There is also a URL element. FTP doesn't have any place to put a URL however it is here to make thing easier for clients handling multiple servers simulatenously and/or proxies.
|
||||||
|
pub fn generate_request(url: &str, cmd: &str) -> FTPRequest {
|
||||||
|
let wurl = wrap_url(url);
|
||||||
|
let split: Vec<&str> = cmd.split(" ").collect();
|
||||||
|
let mut args: Vec<String> = vec![];
|
||||||
|
for v in &split {
|
||||||
|
if v != &split[0] {
|
||||||
|
args.push(v.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let req = FTPRequest { url: wurl, command: split[0].to_string(), arguments: args };
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function for generating FTPResponse structures.
|
||||||
|
/// Messages associated to status codes are not provided by the module, unlike http1, and must be provided by the program using it.
|
||||||
|
/// Also unlike http1, ftp doesn't automatically check status code for integrity.
|
||||||
|
pub fn generate_response(code: i32, message: &str) -> FTPResponse {
|
||||||
|
let res = FTPResponse { code: code, message: message.to_string() };
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function for converting FTPRequest structures into an FTP request string.
|
||||||
|
/// 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: FTPRequest) -> String {
|
||||||
|
let mut string = format!("{}", req.command);
|
||||||
|
let empty: Vec<String> = vec![];
|
||||||
|
if req.arguments != empty {
|
||||||
|
for v in req.arguments {
|
||||||
|
string = format!("{} {}", string, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string = format!("{}\r\n", string);
|
||||||
|
return string.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function for converting FTPResponse structures into FTP response strings.
|
||||||
|
/// 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: FTPResponse) -> String {
|
||||||
|
let string = format!("{} {}\r\n", res.code, res.message);
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A fucntion for converting FTP request strings into FTPRequest.
|
||||||
|
/// The arguments are split, similarly to generate_request.
|
||||||
|
/// Since FTPRequest features a Url field, it will be set to an invalid address.
|
||||||
|
/// 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) -> FTPRequest {
|
||||||
|
let split: Vec<&str> = req.split("\r\n").collect();
|
||||||
|
let split1: Vec<&str> = split[0].split(" ").collect();
|
||||||
|
let string = split1[0];
|
||||||
|
let mut args: Vec<String> = vec![];
|
||||||
|
for v in &split1 {
|
||||||
|
if v != &split1[0] {
|
||||||
|
args.push(v.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let freq = FTPRequest { url: wrap_url("ftp://packeteer.invalid/dont-process-me"), command: string.to_string(), arguments: args };
|
||||||
|
return freq
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function for converting FTP response strings into FTPResponse.
|
||||||
|
/// 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_response(res: &str) -> FTPResponse {
|
||||||
|
let split: Vec<&str> = res.split("\r\n").collect();
|
||||||
|
let split1: Vec<&str> = split[0].split(" ").collect();
|
||||||
|
let n: i32 = FromStr::from_str(split1[0]).unwrap();
|
||||||
|
let mut message = "".to_string();
|
||||||
|
for v in &split1 {
|
||||||
|
if v != &split1[0] {
|
||||||
|
if message == "".to_string() {
|
||||||
|
message = v.to_string();
|
||||||
|
} else {
|
||||||
|
message = format!("{} {}", message, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let resp = FTPResponse { code: n, message: message.to_string() };
|
||||||
|
return resp
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ pub fn generate_request(method: &str, host: &str, location: &str, body: &str) ->
|
||||||
}
|
}
|
||||||
/// A function for generating Http1Response structures.
|
/// A function for generating Http1Response structures.
|
||||||
/// By default, packeteer generates HTTP/1.1 responses.
|
/// By default, packeteer generates HTTP/1.1 responses.
|
||||||
|
/// Invalid status codes will automatically be turned into code 500 (Internal Server Error)
|
||||||
pub fn generate_response(code: i32, body: &str) -> Http1Response {
|
pub fn generate_response(code: i32, body: &str) -> Http1Response {
|
||||||
let mut xcode = code;
|
let mut xcode = code;
|
||||||
if code_to_string(xcode) == "500 Internal Server Error" {
|
if code_to_string(xcode) == "500 Internal Server Error" {
|
||||||
|
@ -75,6 +76,7 @@ pub fn construct_request(request: &str) -> Http1Request {
|
||||||
}
|
}
|
||||||
/// A function for converting HTTP/1.x response strings into Http1Response.
|
/// A function for converting HTTP/1.x response strings into Http1Response.
|
||||||
/// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the response stays relatively unchanged.
|
/// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the response stays relatively unchanged.
|
||||||
|
/// Responses passed here with invalid status codes will keep their invalid status code.
|
||||||
pub fn construct_response(response: &str) -> Http1Response {
|
pub fn construct_response(response: &str) -> Http1Response {
|
||||||
let split = response.split("\r\n");
|
let split = response.split("\r\n");
|
||||||
let mut response = Http1Response { version: "".to_string(), status: "".to_string(), headers: vec![], body: "".to_string(), code: 0 };
|
let mut response = Http1Response { version: "".to_string(), status: "".to_string(), headers: vec![], body: "".to_string(), code: 0 };
|
||||||
|
|
|
@ -82,3 +82,6 @@ pub mod http1;
|
||||||
|
|
||||||
#[cfg(feature = "gemini")]
|
#[cfg(feature = "gemini")]
|
||||||
pub mod gemini;
|
pub mod gemini;
|
||||||
|
|
||||||
|
#[cfg(feature = "ftp")]
|
||||||
|
pub mod ftp;
|
||||||
|
|
Loading…
Reference in a new issue