Skip to content

Commit

Permalink
src fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Az107 committed Sep 8, 2024
1 parent 3e733a1 commit f2700f9
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 271 deletions.
6 changes: 3 additions & 3 deletions config.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[HTEAPOT]
port = 8081
host = "0.0.0.0"
host = "0.0.0.0"
root = "public"
threads = 5
cache = true
cache_ttl = 3600
cache_ttl = 3600
[proxy]
"/test" = "http://example.com"
"/google" = "http://google.com"
# "/" = "http://ifconfig.co" # this will override all the proxys and local request
# "/" = "http://ifconfig.co" # this will override all the proxys and local request
121 changes: 63 additions & 58 deletions src/brew.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,74 @@
// Written by Alberto Ruiz 2024-04-08
// This is the HTTP client module, it will handle the requests and responses

use std::{io::{Read, Write}, net::TcpStream, vec};

use std::{
io::{Read, Write},
net::TcpStream,
};

struct Url {
scheme: String,
domain: String,
path: String,
port: String
scheme: String,
domain: String,
path: String,
port: String,
}

fn parse_url(url: &str) -> Result<Url, &str> {
let url_parts = url.split(":").collect::<Vec<&str>>();
let prefix = url_parts[0];
let domain_path = url_parts[1].trim_start_matches("//");
let port = if url_parts.len() == 3 {
url_parts[2]
} else {
match prefix {
"tea" => "1234",
"https" => "443",
"http" => "80",
_ => "80",
}
};
let (domain, path) = domain_path.split_once('/').unwrap();
Ok(Url {
scheme: prefix.to_string(),
domain: domain.to_string(),
path: path.to_string(),
port: port.to_string(),
})
}

fn parse_url(url: &str) -> Result<Url,&str> {
let url_parts = url.split(":").collect::<Vec<&str>>();
let prefix = url_parts[0];
let domain_path = url_parts[1].trim_start_matches("//");
let port = if url_parts.len() == 3 {
url_parts[2]
} else {
match prefix {
"https" => "443",
"http" => "80",
_ => "80"
pub fn fetch(url: &str) -> Result<Vec<u8>, &str> {
let url = parse_url(url);
if url.is_err() {
return Err("Error parsing url");
}
let url = url.unwrap();
if url.scheme == "https" {
return Err("not supported yet");
}
};
let (domain,path) = domain_path.split_once('/').unwrap();
Ok(Url {
scheme: prefix.to_string(),
domain: domain.to_string(),
path: path.to_string(),
port: port.to_string()
})
}

pub fn fetch(url: &str) -> Result<Vec<u8>,&str> {
let url = parse_url(url);
if url.is_err() { return Err("Error parsing url")}
let url = url.unwrap();
if url.scheme == "https" {
return Err("not supported yet");
}

let client = TcpStream::connect(format!("{}:{}",url.domain,url.port));
if client.is_err() {
return Err("Error fetching");
}
let mut client = client.unwrap();
let http_request = format!("GET /{} HTTP/1.1\r\nHost: {}\r\n\r\n",url.path, url.domain);
client.write(http_request.as_bytes()).unwrap();
let mut response = String::new();
let mut full_buffer: Vec<u8> = Vec::new();
let mut buffer = [0; 1024];
loop {
match client.read(&mut buffer) {
Ok(0) => break,
Ok(n) => {
if n == 0 {break;}
full_buffer.extend(buffer.iter().cloned());
if buffer.last().unwrap() == &0 {break;}
},
Err(_) => break
}
}
Ok(full_buffer)
let client = TcpStream::connect(format!("{}:{}", url.domain, url.port));
if client.is_err() {
return Err("Error fetching");
}
let mut client = client.unwrap();
let http_request = format!("GET /{} HTTP/1.1\r\nHost: {}\r\n\r\n", url.path, url.domain);
client.write(http_request.as_bytes()).unwrap();
let mut full_buffer: Vec<u8> = Vec::new();
let mut buffer = [0; 1024];
loop {
match client.read(&mut buffer) {
Ok(0) => break,
Ok(n) => {
if n == 0 {
break;
}
full_buffer.extend(buffer.iter().cloned());
if buffer.last().unwrap() == &0 {
break;
}
}
Err(_) => break,
}
}
Ok(full_buffer)
}


112 changes: 56 additions & 56 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,44 @@

use std::{any::Any, collections::HashMap, fs};

#[derive(Clone)]
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum TOMLtype {
Text(String),
Number(u16),
Float(f64),
Boolean(bool),
}

type TOMLSchema = HashMap<String,TOMLtype>;
type TOMLSchema = HashMap<String, TOMLtype>;
trait Schema {
fn get2<T: 'static + Clone>(&self, key: &str) -> Option<T> ;
fn get2<T: 'static + Clone>(&self, key: &str) -> Option<T>;
}


impl Schema for TOMLSchema {
impl Schema for TOMLSchema {
fn get2<T: 'static + Clone>(&self, key: &str) -> Option<T> {
let value = self.get(key)?;
let value = value.clone();
let any_value: Box<dyn Any> = match value {
TOMLtype::Text(d) => Box::new(d),
TOMLtype::Number(d) => Box::new(d),
let any_value: Box<dyn Any> = match value {
TOMLtype::Text(d) => Box::new(d),
TOMLtype::Number(d) => Box::new(d),
TOMLtype::Float(d) => Box::new(d),
TOMLtype::Boolean(d) => Box::new(d)
TOMLtype::Boolean(d) => Box::new(d),
};
let r = any_value.downcast_ref::<T>().cloned();
if r.is_none() {println!("{} is none", key);}
if r.is_none() {
println!("{} is none", key);
}
r
}
}

pub fn toml_parser(content: &str) -> HashMap<String,TOMLSchema> {
pub fn toml_parser(content: &str) -> HashMap<String, TOMLSchema> {
let mut map = HashMap::new();
let mut submap = HashMap::new();
let mut title = "".to_string();
let lines = content.split("\n");
for line in lines {
if line.starts_with("#") || line.is_empty() {
if line.starts_with("#") || line.is_empty() {
continue;
}
let line = if line.contains('#') {
Expand All @@ -54,7 +54,7 @@ pub fn toml_parser(content: &str) -> HashMap<String,TOMLSchema> {
let key = line.trim_matches('[').trim_matches(']').trim();
if submap.len() != 0 && title.len() != 0 {
map.insert(title.clone(), submap.clone());
}
}
title = key.to_string();
submap = HashMap::new();
continue;
Expand All @@ -63,15 +63,18 @@ pub fn toml_parser(content: &str) -> HashMap<String,TOMLSchema> {
if parts.len() != 2 {
continue;
}
let key = parts[0].trim().trim_end_matches('"').trim_start_matches('"');
if key.is_empty(){
let key = parts[0]
.trim()
.trim_end_matches('"')
.trim_start_matches('"');
if key.is_empty() {
continue;
}
let value = parts[1].trim();
let value = if value.contains('\'') || value.contains('"') {
let value = value.trim_matches('"').trim();
TOMLtype::Text(value.to_string())
} else if value.to_lowercase() == "true" || value.to_lowercase() == "false" {
} else if value.to_lowercase() == "true" || value.to_lowercase() == "false" {
let value = value.to_lowercase() == "true";
TOMLtype::Boolean(value)
} else if value.contains('.') {
Expand All @@ -86,25 +89,23 @@ pub fn toml_parser(content: &str) -> HashMap<String,TOMLSchema> {
panic!("Error parsing toml");
}
TOMLtype::Number(value.unwrap())

};
submap.insert(key.to_string(), value);
}
map.insert(title, submap.clone());
map
}


pub struct Config {
pub port: u16, // Port number to listen
pub port: u16, // Port number to listen
pub host: String, // Host name or IP
pub root: String, // Root directory to serve files
pub cache: bool,
pub cache_ttl: u64,
pub threads: u16,
pub index: String, // Index file to serve by default
pub error: String, // Error file to serve when a file is not found
pub proxy_rules: HashMap<String, String>
//pub error: String, // Error file to serve when a file is not found
pub proxy_rules: HashMap<String, String>,
}

impl Config {
Expand All @@ -125,48 +126,47 @@ impl Config {
host: "localhost".to_string(),
root: "./".to_string(),
index: "index.html".to_string(),
error: "error.html".to_string(),
//error: "error.html".to_string(),
threads: 1,
cache: false,
cache_ttl: 0,
proxy_rules: HashMap::new()
proxy_rules: HashMap::new(),
}
}

pub fn load_config(path: &str) -> Config {
let content = fs::read_to_string(path);
if content.is_err() {
return Config::new_default();
}
let content = content.unwrap();
let map = toml_parser(&content);
let mut proxy_rules: HashMap<String, String> = HashMap::new();
let proxy_map = map.get("proxy");
if proxy_map.is_some() {
let proxy_map = proxy_map.unwrap();
for k in proxy_map.keys() {
let url = proxy_map.get2(k);
if url.is_none() {
println!();
continue;
let content = fs::read_to_string(path);
if content.is_err() {
return Config::new_default();
}
let content = content.unwrap();
let map = toml_parser(&content);
let mut proxy_rules: HashMap<String, String> = HashMap::new();
let proxy_map = map.get("proxy");
if proxy_map.is_some() {
let proxy_map = proxy_map.unwrap();
for k in proxy_map.keys() {
let url = proxy_map.get2(k);
if url.is_none() {
println!();
continue;
}
let url = url.unwrap();
proxy_rules.insert(k.clone(), url);
}
let url = url.unwrap();
proxy_rules.insert(k.clone(), url);
}
}

let map = map.get("HTEAPOT").unwrap();
Config {
port: map.get2("port").unwrap_or(8080),
host: map.get2("host").unwrap_or("".to_string()),
root: map.get2("root").unwrap_or("./".to_string()),
threads: map.get2("threads").unwrap_or(1),
cache: map.get2("cache").unwrap_or(false),
cache_ttl: map.get2("cache_ttl").unwrap_or(3600),
index: map.get2("index").unwrap_or("index.html".to_string()),
error: map.get2("error").unwrap_or("error.html".to_string()),
proxy_rules
}

let map = map.get("HTEAPOT").unwrap();
Config {
port: map.get2("port").unwrap_or(8080),
host: map.get2("host").unwrap_or("".to_string()),
root: map.get2("root").unwrap_or("./".to_string()),
threads: map.get2("threads").unwrap_or(1),
cache: map.get2("cache").unwrap_or(false),
cache_ttl: map.get2("cache_ttl").unwrap_or(3600),
index: map.get2("index").unwrap_or("index.html".to_string()),
//error: map.get2("error").unwrap_or("error.html".to_string()),
proxy_rules,
}
}
}

Loading

0 comments on commit f2700f9

Please sign in to comment.