commit
417800fcad
|
|
@ -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
|
||||||
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
|
|
@ -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"] }
|
||||||
|
|
|
||||||
36
README.md
36
README.md
|
|
@ -1,6 +1,27 @@
|
||||||
# lwa_simple_server
|
# lwa_simple_server
|
||||||
|
|
||||||
Simple server made with hosting locally webgl games in mind.
|
[](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'
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
61
src/main.rs
61
src/main.rs
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue