Compare commits
No commits in common. "e2d9789f9a7e2b0d827508bece5a55f35a582b50" and "a8bc61f40ce9061cd63a43a2fe07c9a4bb899a64" have entirely different histories.
e2d9789f9a
...
a8bc61f40c
11 changed files with 96 additions and 192 deletions
57
Cargo.lock
generated
57
Cargo.lock
generated
|
@ -26,15 +26,6 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ansi_colours"
|
|
||||||
version = "1.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "14eec43e0298190790f41679fe69ef7a829d2a2ddd78c8c00339e84710e435fe"
|
|
||||||
dependencies = [
|
|
||||||
"rgb",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.98"
|
version = "1.0.98"
|
||||||
|
@ -127,11 +118,9 @@ dependencies = [
|
||||||
name = "boxy"
|
name = "boxy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_colours",
|
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"colour",
|
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
|
@ -154,12 +143,6 @@ version = "3.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bytemuck"
|
|
||||||
version = "1.23.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -197,15 +180,6 @@ dependencies = [
|
||||||
"inout",
|
"inout",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colour"
|
|
||||||
version = "2.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b536eebcabe54980476d120a182f7da2268fe02d22575cca99cee5fdda178280"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -856,15 +830,6 @@ version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rgb"
|
|
||||||
version = "0.8.52"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.14"
|
version = "0.17.14"
|
||||||
|
@ -1321,22 +1286,6 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -1346,12 +1295,6 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
|
|
@ -21,6 +21,4 @@ serde = "1.0.219"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
string-builder = "0.2.0"
|
string-builder = "0.2.0"
|
||||||
json = "0.12.4"
|
json = "0.12.4"
|
||||||
ansi_colours = "1.2.3"
|
|
||||||
colour = "2.1.0"
|
|
||||||
|
|
||||||
|
|
11
config.yaml
11
config.yaml
|
@ -1,4 +1,7 @@
|
||||||
database: 'postgresql://postgres:trust@127.0.0.1'
|
db:
|
||||||
|
host: '127.0.0.1'
|
||||||
|
user: 'postgres'
|
||||||
|
password: 'trust'
|
||||||
|
|
||||||
proxy:
|
proxy:
|
||||||
listen: 127.0.0.1
|
listen: 127.0.0.1
|
||||||
|
@ -8,6 +11,10 @@ api:
|
||||||
listen: 127.0.0.1
|
listen: 127.0.0.1
|
||||||
port: 8006
|
port: 8006
|
||||||
|
|
||||||
|
hosts: # ignore this it doesn't function
|
||||||
|
- hostname: localhost:8005
|
||||||
|
address: localhost:8000
|
||||||
|
|
||||||
clients:
|
clients:
|
||||||
- name: 'eu-central-1' # Example Client right here (the client in this case would be for example the stereo.cat backend)
|
- name: 'eu-central-1' # Example Client right here (the client in this case would be for example the stereo.cat backend)
|
||||||
hashed_secret: '$2b$12$5wH/0p702PPqVp7fCpVS4.1GA2/wAbk89w2nMjwuS8439OhjCUGbK' # password123
|
secret: '$2b$12$5wH/0p702PPqVp7fCpVS4.1GA2/wAbk89w2nMjwuS8439OhjCUGbK' # password123
|
||||||
|
|
|
@ -27,34 +27,44 @@ pub struct Api {
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub hashed_secret: String,
|
pub secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||||
pub async fn verify(us: String, config: Config) -> bool {
|
pub struct Host {
|
||||||
// us stands for user:secret btw
|
pub hostname: String,
|
||||||
let us_split: Vec<&str> = us.split(':').collect();
|
pub address: String,
|
||||||
|
|
||||||
let name = us_split.first().unwrap();
|
|
||||||
let secret = us_split.last().unwrap();
|
|
||||||
|
|
||||||
let client: Client = config
|
|
||||||
.clients
|
|
||||||
.into_iter()
|
|
||||||
.filter(|x| x.name.eq(name))
|
|
||||||
.nth(0)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
bcrypt::verify(secret, client.hashed_secret.as_str()).unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub database: String,
|
pub db: Db,
|
||||||
pub proxy: Proxy,
|
pub proxy: Proxy,
|
||||||
pub api: Api,
|
pub api: Api,
|
||||||
pub clients: Vec<Client>,
|
pub clients: Vec<Client>,
|
||||||
|
pub hosts: Vec<Host>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Db {
|
||||||
|
pub async fn to_string(&self) -> String {
|
||||||
|
let mut builder = String::new();
|
||||||
|
|
||||||
|
builder += format!(
|
||||||
|
"host={} port={} user={} dbname={}",
|
||||||
|
self.host,
|
||||||
|
self.port.unwrap_or(5432),
|
||||||
|
self.user,
|
||||||
|
self.database.clone().unwrap_or(self.user.clone()),
|
||||||
|
)
|
||||||
|
.as_str();
|
||||||
|
|
||||||
|
match &self.password {
|
||||||
|
Some(x) => builder += format!(" password={}", x).as_str(),
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use std::{
|
use std::{error::Error, net::{IpAddr, SocketAddr}};
|
||||||
error::Error,
|
|
||||||
net::IpAddr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use tokio_postgres::Client;
|
use tokio_postgres::{Client, Socket, tls::MakeTlsConnect};
|
||||||
|
|
||||||
const ENDPOINT_TABLE: &str = "endpoints";
|
const ENDPOINT_TABLE: &str = "endpoints";
|
||||||
const HOSTS_RELATION_TABLE: &str = "hosts";
|
const HOSTS_RELATION_TABLE: &str = "hosts";
|
||||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -1,28 +1,26 @@
|
||||||
mod config;
|
mod config;
|
||||||
mod db;
|
mod db;
|
||||||
mod server;
|
|
||||||
mod services;
|
mod services;
|
||||||
|
mod types;
|
||||||
|
|
||||||
use std::{env, process::exit, sync::Arc};
|
use std::{env, sync::Arc};
|
||||||
|
|
||||||
use bcrypt::DEFAULT_COST;
|
use bcrypt::{DEFAULT_COST, bcrypt};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use db::BoxyDatabase;
|
use db::BoxyDatabase;
|
||||||
use log::{debug, error, info};
|
use log::{error, info};
|
||||||
use server::Server;
|
use nanoid::nanoid;
|
||||||
|
use ring::rand::SystemRandom;
|
||||||
use services::{api::ApiService, controller::ControllerService};
|
use services::{api::ApiService, controller::ControllerService};
|
||||||
use tokio::sync::Mutex;
|
use tokio::{fs::File, io::AsyncReadExt, sync::Mutex};
|
||||||
use tokio_postgres::NoTls;
|
use tokio_postgres::{NoTls, tls::NoTlsError};
|
||||||
|
use types::Server;
|
||||||
const VERSION: &str = "v0.1a";
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
if env::var("RUST_LOG").is_err() {
|
pretty_env_logger::formatted_builder()
|
||||||
unsafe { env::set_var("RUST_LOG", "info") };
|
.filter(None, log::LevelFilter::Info)
|
||||||
}
|
.init();
|
||||||
|
|
||||||
pretty_env_logger::init();
|
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
@ -39,31 +37,26 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
"version" => {
|
|
||||||
info!("Version: {}", VERSION);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = Config::get().await.unwrap();
|
let config = Config::get().await.unwrap();
|
||||||
|
|
||||||
debug!("Database URI: {}", config.database);
|
let db_string = config.db.to_string().await;
|
||||||
|
|
||||||
let (client, conn) = tokio_postgres::connect(config.database.as_str(), NoTls)
|
info!("Database string: {}", db_string);
|
||||||
|
|
||||||
|
let (client, conn) = tokio_postgres::connect(db_string.as_str(), NoTls)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Err(e) = conn.await {
|
if let Err(e) = conn.await {
|
||||||
error!("Error while connecting to database: {}", e);
|
error!("Error while connecting to database: {}", e);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
info!("Connected to database.");
|
|
||||||
|
|
||||||
let database = Box::new(BoxyDatabase::new(client).await.unwrap());
|
let database = Box::new(BoxyDatabase::new(client).await.unwrap());
|
||||||
|
|
||||||
let database_shared = Arc::new(Mutex::new(Box::leak(database)));
|
let database_shared = Arc::new(Mutex::new(Box::leak(database)));
|
||||||
|
@ -71,7 +64,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let api_svc = ApiService {
|
let api_svc = ApiService {
|
||||||
database: database_shared.clone(),
|
database: database_shared.clone(),
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
_address: None,
|
_address: None
|
||||||
};
|
};
|
||||||
|
|
||||||
let svc = ControllerService {
|
let svc = ControllerService {
|
||||||
|
@ -87,12 +80,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
tokio::task::spawn(async move {
|
tokio::task::spawn(async move {
|
||||||
info!("Starting API server...");
|
|
||||||
api_server.handle().await;
|
api_server.handle().await;
|
||||||
});
|
});
|
||||||
|
|
||||||
// We don't put this on a separate thread because we'd be wasting the main thread.
|
// We don't put this on a separate thread because we'd be wasting the main thread.
|
||||||
info!("Starting proxy server...");
|
|
||||||
proxy_server.handle().await;
|
proxy_server.handle().await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
pub mod api;
|
|
||||||
pub mod controller;
|
|
||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
|
pub mod controller;
|
||||||
|
pub mod api;
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
use std::{net::IpAddr, pin::Pin, sync::Arc};
|
use std::{hash, net::{IpAddr, SocketAddr}, pin::Pin, sync::Arc};
|
||||||
|
|
||||||
use base64::{Engine, prelude::BASE64_STANDARD};
|
use base64::{Engine, prelude::BASE64_STANDARD};
|
||||||
|
use bcrypt::DEFAULT_COST;
|
||||||
use http_body_util::{BodyExt, Full};
|
use http_body_util::{BodyExt, Full};
|
||||||
use hyper::{
|
use hyper::{
|
||||||
Method, Request, Response, StatusCode,
|
body::{Bytes, Incoming}, service::Service, Method, Request, Response, StatusCode, Uri
|
||||||
body::{Bytes, Incoming},
|
|
||||||
service::Service,
|
|
||||||
};
|
};
|
||||||
use log::{debug, warn};
|
use log::{info, trace};
|
||||||
use tokio::{net::TcpStream, sync::Mutex};
|
use tokio::{net::TcpStream, sync::Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Client, Config},
|
config::{Client, Config}, db::{BoxyDatabase, Endpoint}, types::{GeneralBody, GeneralResponse, TcpIntercept}
|
||||||
db::{BoxyDatabase, Endpoint},
|
|
||||||
server::{GeneralBody, GeneralResponse, TcpIntercept},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -23,7 +20,7 @@ pub struct ApiService {
|
||||||
pub _address: Option<IpAddr>,
|
pub _address: Option<IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn default_response() -> GeneralResponse {
|
async fn default_response() -> Response<http_body_util::Either<Incoming, Full<Bytes>>> {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(404)
|
.status(404)
|
||||||
.body(GeneralBody::Right(Full::from(Bytes::from(
|
.body(GeneralBody::Right(Full::from(Bytes::from(
|
||||||
|
@ -32,7 +29,7 @@ async fn default_response() -> GeneralResponse {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn custom_resp(e: StatusCode, m: &'static str) -> GeneralResponse {
|
async fn custom_resp(e: StatusCode, m: String) -> Response<http_body_util::Either<Incoming, Full<Bytes>>> {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(e)
|
.status(e)
|
||||||
.body(GeneralBody::Right(Full::from(Bytes::from(m))))
|
.body(GeneralBody::Right(Full::from(Bytes::from(m))))
|
||||||
|
@ -40,7 +37,7 @@ async fn custom_resp(e: StatusCode, m: &'static str) -> GeneralResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TcpIntercept for ApiService {
|
impl TcpIntercept for ApiService {
|
||||||
fn stream(&mut self, stream: &TcpStream) {
|
fn handle(&mut self, stream: &TcpStream) {
|
||||||
self._address = Some(stream.peer_addr().unwrap().ip());
|
self._address = Some(stream.peer_addr().unwrap().ip());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,73 +51,37 @@ impl Service<Request<Incoming>> for ApiService {
|
||||||
let database = self.database.clone();
|
let database = self.database.clone();
|
||||||
let config = self.config.clone();
|
let config = self.config.clone();
|
||||||
let address = self._address.clone().unwrap();
|
let address = self._address.clone().unwrap();
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
match *req.method() {
|
match *req.method() {
|
||||||
Method::POST => match req.uri().path() {
|
Method::POST => match req.uri().path() {
|
||||||
"/register" => {
|
"/register" => {
|
||||||
debug!("new api register request from {}", address);
|
let encoded_header = req.headers().get(hyper::header::AUTHORIZATION).unwrap().to_str().unwrap();
|
||||||
|
|
||||||
let encoded_header = req
|
let auth_string = String::from_utf8(BASE64_STANDARD.decode(&encoded_header[6..]).unwrap()).unwrap();
|
||||||
.headers()
|
|
||||||
.get(hyper::header::AUTHORIZATION)
|
|
||||||
.unwrap()
|
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
debug!("authorization header: {}", encoded_header);
|
let auth_string_split: Vec<&str> = auth_string.split(':').collect();
|
||||||
|
|
||||||
let auth_string = String::from_utf8(
|
let name = auth_string_split.first().unwrap();
|
||||||
BASE64_STANDARD.decode(&encoded_header[6..]).unwrap(),
|
let secret = auth_string_split.get(1).unwrap();
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
debug!("decoded auth string: {}", auth_string);
|
let matched_clients: Vec<&Client> = config.clients.iter().filter(|x| x.name.eq(name)).collect();
|
||||||
|
|
||||||
if !Client::verify(auth_string.clone(), config).await {
|
let client = matched_clients.first().unwrap();
|
||||||
warn!(
|
|
||||||
"Authentication for string {} from {} failed.",
|
|
||||||
auth_string, address
|
|
||||||
);
|
|
||||||
|
|
||||||
return Ok(custom_resp(
|
if !bcrypt::verify(secret, client.secret.as_str()).unwrap() {
|
||||||
StatusCode::UNAUTHORIZED,
|
return Ok(custom_resp(StatusCode::UNAUTHORIZED, "Invalid credentials.".to_string()).await);
|
||||||
"Invalid credentials.",
|
|
||||||
)
|
|
||||||
.await);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = String::from_utf8(
|
let body = String::from_utf8(req.collect().await.unwrap().to_bytes().iter().cloned().collect::<Vec<u8>>()).unwrap();
|
||||||
req.collect()
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.to_bytes()
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect::<Vec<u8>>(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let json = json::parse(body.as_str()).unwrap();
|
let json = json::parse(body.as_str()).unwrap();
|
||||||
|
|
||||||
debug!("body: {}", body);
|
info!("body: {}", body);
|
||||||
|
|
||||||
let mut endpoint = Endpoint::new(
|
let mut endpoint = Endpoint::new(None, address, json["port"].as_u16().unwrap(), json["callback"].as_str().unwrap_or("/").to_string()).await;
|
||||||
None,
|
|
||||||
address,
|
|
||||||
json["port"].as_u16().unwrap(),
|
|
||||||
json["callback"].as_str().unwrap_or("/").to_string(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
endpoint
|
endpoint.register(*database.lock().await, json["hostname"].as_str().unwrap().to_string()).await.unwrap();
|
||||||
.register(
|
|
||||||
*database.lock().await,
|
|
||||||
json["hostname"].as_str().unwrap().to_string(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Ok(custom_resp(StatusCode::OK, "").await)
|
Ok(custom_resp(StatusCode::OK, "yay".to_string()).await)
|
||||||
}
|
}
|
||||||
_ => Ok(default_response().await),
|
_ => Ok(default_response().await),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
use std::{pin::Pin, sync::Arc};
|
use std::{pin::Pin, sync::Arc};
|
||||||
|
|
||||||
|
use http_body_util::Full;
|
||||||
use hyper::{
|
use hyper::{
|
||||||
Request,
|
Request, Response,
|
||||||
body::Incoming,
|
body::{Bytes, Incoming},
|
||||||
service::Service,
|
service::Service,
|
||||||
};
|
};
|
||||||
|
use log::error;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
config::{self, Client, Config, Host},
|
||||||
db::{BoxyDatabase, Endpoint},
|
db::{BoxyDatabase, Endpoint},
|
||||||
server::{GeneralResponse, TcpIntercept},
|
types::{GeneralBody, GeneralResponse, TcpIntercept},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::proxy::ProxyService;
|
use super::proxy::ProxyService;
|
||||||
|
@ -20,7 +23,8 @@ pub struct ControllerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TcpIntercept for ControllerService {
|
impl TcpIntercept for ControllerService {
|
||||||
fn stream(&mut self, _: &tokio::net::TcpStream) {}
|
fn handle(&mut self, stream: &tokio::net::TcpStream) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Service<Request<Incoming>> for ControllerService {
|
impl Service<Request<Incoming>> for ControllerService {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use hyper_util::rt::TokioIo;
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
use crate::server::{GeneralResponse, to_general_response};
|
use crate::types::{GeneralResponse, to_general_response};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ProxyService {
|
pub struct ProxyService {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{any::type_name_of_val, error::Error};
|
use std::error::Error;
|
||||||
|
|
||||||
use http_body_util::{Either, Full};
|
use http_body_util::{Either, Full};
|
||||||
use hyper::{
|
use hyper::{
|
||||||
|
@ -8,7 +8,7 @@ use hyper::{
|
||||||
service::{HttpService, Service},
|
service::{HttpService, Service},
|
||||||
};
|
};
|
||||||
use hyper_util::rt::TokioIo;
|
use hyper_util::rt::TokioIo;
|
||||||
use log::{error, info};
|
use log::error;
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
|
||||||
pub type GeneralResponse = Response<GeneralBody>;
|
pub type GeneralResponse = Response<GeneralBody>;
|
||||||
|
@ -25,7 +25,7 @@ pub struct Server<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TcpIntercept {
|
pub trait TcpIntercept {
|
||||||
fn stream(&mut self, stream: &TcpStream);
|
fn handle(&mut self, stream: &TcpStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Server<S>
|
impl<S> Server<S>
|
||||||
|
@ -39,20 +39,13 @@ where
|
||||||
<S as HttpService<Incoming>>::Future: Send,
|
<S as HttpService<Incoming>>::Future: Send,
|
||||||
{
|
{
|
||||||
pub async fn handle(&self) {
|
pub async fn handle(&self) {
|
||||||
info!(
|
|
||||||
"Server started at http://{} for service: {}",
|
|
||||||
self.listener.local_addr().unwrap(),
|
|
||||||
type_name_of_val(&self.service)
|
|
||||||
);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (stream, _) = self.listener.accept().await.unwrap();
|
let (stream, _) = self.listener.accept().await.unwrap();
|
||||||
|
|
||||||
let mut svc_clone = self.service.clone();
|
let mut svc_clone = self.service.clone();
|
||||||
svc_clone.stream(&stream);
|
svc_clone.handle(&stream);
|
||||||
|
|
||||||
let io = TokioIo::new(stream);
|
let io = TokioIo::new(stream);
|
||||||
|
|
||||||
tokio::task::spawn(async move {
|
tokio::task::spawn(async move {
|
||||||
if let Err(err) = http1::Builder::new()
|
if let Err(err) = http1::Builder::new()
|
||||||
.writev(false)
|
.writev(false)
|
Loading…
Add table
Add a link
Reference in a new issue