Merge pull request #1 from Leinnan/depsAndClap

Rework
This commit is contained in:
Piotr Siuszko 2023-08-29 20:18:39 +02:00 committed by GitHub
commit 417800fcad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 802 additions and 1176 deletions

21
.github/workflows/rust.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: build
on:
workflow_dispatch:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
env:
CARGO_TERM_COLOR: always
jobs:
build-unix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: rustup toolchain install stable --profile minimal
- uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --verbose

1775
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "lwa_simple_server" name = "lwa_simple_server"
version = "0.1.0" version = "0.2.0"
authors = ["Mev Lyshkin <mev_lyshkin@protonmail.com>"] authors = ["Mev Lyshkin <mev_lyshkin@protonmail.com>"]
edition = "2018" edition = "2018"
@ -15,11 +15,11 @@ lto = true
opt-level = 2 opt-level = 2
[dependencies] [dependencies]
actix-web = { version = "~3", features = ["openssl"] } actix-web = { version = "4.4", features = ["openssl"] }
openssl = { version = "0.10" } openssl = { version = "0.10" }
actix-files = "^0.5.0" actix-files = "^0.6"
actix-cors = "^0.5.4" actix-cors = "^0.6"
env_logger = "^0.8.3" env_logger = "^0.10"
confy = "^0.4.0"
serde = "^1.0" serde = "^1.0"
serde_derive = "^1.0" serde_derive = "^1.0"
clap = { version = "^4.4", features = ["derive"] }

View File

@ -1,6 +1,27 @@
# lwa_simple_server # lwa_simple_server
Simple server made with hosting locally webgl games in mind. [![build](https://github.com/Leinnan/lwa_simple_server/actions/workflows/rust.yml/badge.svg)](https://github.com/Leinnan/lwa_simple_server/actions/workflows/rust.yml)
```
Simple server made with hosting locally webgl games in mind
Usage: lwa_simple_server [OPTIONS] [FOLDER_TO_HOST]
Arguments:
[FOLDER_TO_HOST] Folder to host, current by default
Options:
--ssl
Should use SSL, false by default
-a, --address <ADDRESS>
Specifies hosting address, "localhost:8080" by default
-c, --certificates-folder <CERTIFICATES_FOLDER>
-h, --help
Print help
-V, --version
Print version
```
It makes testing Unity webgl games easy, even allows connecting with different domains(less CORS issues during tests). It makes testing Unity webgl games easy, even allows connecting with different domains(less CORS issues during tests).
@ -26,22 +47,13 @@ To start run it in folder that should be root folder of hosted site:
```bash ```bash
cd desired/folder cd desired/folder
lwa_simple_server lwa_simple_server "folder_to_host/current_by_default"
``` ```
After first start of the program in configs folder will be created `lwa_simple_server` directory with `lwa_simple_server.toml` in it with config values:
```toml
folder_to_host = '/example/path/TestProject'
bind_address = 'localhost:8000'
private_key_file = 'key.pem'
certificate_chain_file = 'cert.pem'
use_ssl = false
```
## SSL ## SSL
If you would like to use OpenSSL create key with command below and pass paths to generated files in config above in order to use it: If you would like to use OpenSSL create key with command below and pass paths to generated files as arguments in command in order to use it:
```bash ```bash
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost' openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'

51
src/app.rs Normal file
View File

@ -0,0 +1,51 @@
use clap::{command, Parser};
use std::path::PathBuf;
/// Simple server made with hosting locally webgl games in mind.
#[derive(Debug, Parser, Clone)]
#[command(name = "lwa_simple_server", version = "0.1.0", author = "Mev Lyshkin")]
pub struct SimpleServer {
/// Folder to host, current by default
pub folder_to_host: Option<PathBuf>,
/// Should use SSL, false by default
#[arg(long)]
pub ssl: bool,
/// Specifies hosting address, "localhost:8080" by default
#[arg(short, long)]
pub address: Option<String>,
// Specifies folder containing "key.pem" and "cert.pem" required for ssl hosting, defaults to current folder
#[arg(short, long)]
certificates_folder: Option<PathBuf>,
}
impl SimpleServer {
pub fn get_folder_to_host(&self) -> PathBuf {
if self.folder_to_host.is_some() {
self.folder_to_host.clone().unwrap()
} else {
PathBuf::from(".")
}
}
pub fn get_address(&self) -> String {
if self.address.is_some() {
return self.address.clone().unwrap();
}
"localhost:8080".to_string()
}
fn get_certificates_folder(&self) -> PathBuf {
if self.certificates_folder.is_some() {
self.certificates_folder.clone().unwrap()
} else {
PathBuf::from(".")
}
}
pub fn get_private_key_path(&self) -> PathBuf {
std::fs::canonicalize(self.get_certificates_folder().join("key.pem")).unwrap()
}
pub fn get_certificate_chain_file_path(&self) -> PathBuf {
std::fs::canonicalize(self.get_certificates_folder().join("cert.pem")).unwrap()
}
}

View File

@ -1,20 +0,0 @@
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ServerConfig {
pub folder_to_host: String,
pub bind_address: String,
pub private_key_file: String,
pub certificate_chain_file: String,
pub use_ssl: bool
}
impl Default for ServerConfig {
fn default() -> Self {
Self {
folder_to_host: String::from(std::env::current_dir().unwrap().to_str().unwrap()),
bind_address: "localhost:8000".to_string(),
private_key_file: "key.pem".to_string(),
certificate_chain_file: "cert.pem".to_string(),
use_ssl: false,
}
}
}

View File

@ -1,50 +1,69 @@
#[macro_use]
extern crate serde_derive;
extern crate confy;
use actix_cors::Cors; use actix_cors::Cors;
use actix_files as fs; use actix_files as fs;
use actix_web::{middleware, App, HttpServer}; use actix_web::{middleware, App, HttpServer};
use clap::Parser;
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use std::env; use std::env;
mod config; mod app;
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
let app_args = crate::app::SimpleServer::parse();
env::set_var("RUST_LOG", "actix_web=debug,actix_server=info"); env::set_var("RUST_LOG", "actix_web=debug,actix_server=info");
env_logger::init(); env_logger::init();
let cfg: config::ServerConfig = confy::load("lwa_simple_server").unwrap(); let path = app_args.get_folder_to_host();
{ {
println!("The configuration is:\n{:#?}", cfg);
// `openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'` // `openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'`
println!( println!(
"Starting server on address: {} with hosted folder: {} wit SSL: {}", "Starting server on address: {}://{} with hosted folder: {} [SSL={}]",
cfg.bind_address, cfg.folder_to_host, cfg.use_ssl if app_args.ssl{ "https" } else {"http"},
app_args.get_address(),
path.display(),
app_args.ssl
); );
} }
let server = HttpServer::new(move || { let server = HttpServer::new(move || {
let cfg: config::ServerConfig = confy::load("lwa_simple_server").unwrap();
App::new() App::new()
.wrap(middleware::Compress::default())
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())
.wrap(Cors::default()) .wrap(Cors::default())
.service(fs::Files::new("/", &cfg.folder_to_host).index_file("index.html")) .service(
fs::Files::new("/", &path)
.index_file("index.html")
.use_last_modified(true),
)
}); });
if cfg.use_ssl { if app_args.ssl {
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file(&cfg.private_key_file, SslFiletype::PEM)
.unwrap();
builder.set_certificate_chain_file(&cfg.certificate_chain_file).unwrap();
server.bind_openssl(&cfg.bind_address, builder)? if let Err(error) =
.run() builder.set_private_key_file(&app_args.get_private_key_path(), SslFiletype::PEM)
.await {
eprintln!(
"Could not read {}: {}",
app_args.get_private_key_path().display(),
error
)
}
if let Err(error) =
builder.set_certificate_chain_file(&app_args.get_certificate_chain_file_path())
{
eprintln!(
"Could not read {}: {}",
app_args.get_certificate_chain_file_path().display(),
error
)
}
server
.bind_openssl(&app_args.get_address(), builder)?
.run()
.await
} else { } else {
server.bind(&cfg.bind_address)? server.bind(&app_args.get_address())?.run().await
.run()
.await
} }
} }