Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions crates/http-server/src/cli/command/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod start;

use clap::Parser;

use self::start::StartOpt;

#[derive(Debug, Parser)]
pub enum Command {
/// Start the HTTP server
Start(StartOpt),
}
51 changes: 51 additions & 0 deletions crates/http-server/src/cli/command/start.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::net::IpAddr;
use std::process::exit;
use std::sync::Arc;

use anyhow::Result;
use clap::Parser;
use tokio::runtime::Builder;
use tracing::{error, info};

use crate::config::Config;
use crate::server::Server;

const THREAD_NAME: &str = "http-server";

#[derive(Debug, Parser)]
pub struct StartOpt {
/// Host (IP) to bind the server
#[clap(long, default_value = "0.0.0.0")]
pub host: IpAddr,
/// Port to bind the server
#[clap(short = 'p', long, default_value = "7878")]
pub port: u16,
}

impl StartOpt {
pub fn exec(&self) -> Result<()> {
let rt = Builder::new_multi_thread()
.enable_all()
.thread_name(THREAD_NAME)
.build()?;
let rt = Arc::new(rt);
let config = Config {
host: self.host,
port: self.port,
};
let server = Server::new(config);

rt.block_on(async {
match server.run(Arc::clone(&rt)).await {
Ok(_) => {
info!("Server exited successfuly");
Ok(())
}
Err(error) => {
error!(%error, "Server exited with error");
exit(1);
}
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use std::net::IpAddr;
pub mod command;

use clap::Parser;

use self::command::Command;

#[derive(Debug, Parser)]
#[command(
name = "http-server",
author = "Esteban Borai <[email protected]>",
about = "Simple and configurable command-line HTTP server\nSource: https://github.com/EstebanBorai/http-server",
next_line_help = true
about = "Simple and configurable command-line HTTP server\nSource: https://github.com/http-server-rs/http-server"
)]
pub struct Cli {
pub host: IpAddr,
pub port: u16,
#[command(subcommand)]
pub command: Command,
}
2 changes: 2 additions & 0 deletions crates/http-server/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::net::IpAddr;

pub struct Config {
/// The IP address to bind to.
pub host: IpAddr,
/// The port to bind to.
pub port: u16,
}
31 changes: 9 additions & 22 deletions crates/http-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,21 @@ pub mod config;
pub mod plugin;
pub mod server;

use std::{process::exit, sync::Arc};

use anyhow::Result;
use tokio::runtime::Builder;
use clap::Parser;

use self::server::Server;
use self::cli::command::Command;
use self::cli::Cli;

fn main() -> Result<()> {
let rt = Builder::new_multi_thread()
.enable_all()
.thread_name("http-server")
.build()?;
let rt = Arc::new(rt);

tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.init();
let args = Cli::parse();

match args.command {
Command::Start(opt) => opt.exec()?,
}

rt.block_on(async {
match Server::run(Arc::clone(&rt)).await {
Ok(_) => {
println!("Server exited successfuly");
Ok(())
}
Err(error) => {
eprint!("{:?}", error);
exit(1);
}
}
})
Ok(())
}
27 changes: 16 additions & 11 deletions crates/http-server/src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{convert::Infallible, net::SocketAddr, path::PathBuf, str::FromStr, sync::Arc};
use std::convert::Infallible;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;

use anyhow::Result;
use http_body_util::{BodyExt, Full};
Expand All @@ -7,28 +11,32 @@ use hyper::{
server::conn::http1,
Method, Request, Response,
};
use hyper_util::{rt::TokioIo, service::TowerToHyperService};
use hyper_util::rt::TokioIo;
use hyper_util::service::TowerToHyperService;
use tokio::net::TcpListener;
use tokio::runtime::Runtime;
use tower::ServiceBuilder;
use tower_http::cors::{Any, CorsLayer};
use tracing::info;

use crate::config::Config;
use crate::plugin::ExternalFunctions;

pub struct Server {}
pub struct Server {
config: Config,
}

impl Server {
pub async fn run(rt: Arc<Runtime>) -> Result<()> {
info!("Initializing server");
pub fn new(config: Config) -> Self {
Server { config }
}

let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
pub async fn run(self, rt: Arc<Runtime>) -> Result<()> {
let addr = SocketAddr::from((self.config.host, self.config.port));
let listener = TcpListener::bind(addr).await?;
let functions = Arc::new(ExternalFunctions::new());
let plugin_library = PathBuf::from_str("./target/debug/libfile_explorer.dylib").unwrap();
let config = PathBuf::from_str("./config.toml").unwrap();
let handle = Arc::new(rt.handle().to_owned());
let local_ip = local_ip_address::local_ip();

unsafe {
functions
Expand All @@ -37,9 +45,6 @@ impl Server {
.expect("Function loading failed");
}

info!(%addr, "Server Listening");
info!(?local_ip, "Local Network");

loop {
let (stream, _) = listener.accept().await?;
let io = TokioIo::new(stream);
Expand Down
Loading