liftinstall/src/frontend/rest/server.rs
James 68109894f1 Update config files for v7 (#12)
* platform: fix build on Linux and update web-view

* deps: replace xz-decom with xz2 and update deps

* platform: fix regression...

... that prevents the build on Windows

* linux: implement platform-dependent functions

* travis: add macos and windows CI

* travis: use official Rust Docker image

* Update Cargo.lock for new version

* Break apart REST into separate services

This cleans up locking, ensures consistent futures for all endpoints
and enhances code re-use.

* Clean up codebase, fixing minor errors

* Update packages, use async client for downloading config

While this has a hell of a lot more boilerplate, this is quite
a bit cleaner.

* Add explicit 'dyn's as per Rust nightly requirements

* Migrate self updating functions to own module

* Migrate assets to server module

* Use patched web-view to fix dialogs, remove nfd

* Implement basic dark mode

* Revert window.close usage

* ui: split files and use Webpack

* frontend: ui: include prebuilt assets...

... and update rust side stuff

* build: integrate webpack building into build.rs

* Polish Vue UI split

* Add instructions for node + yarn

* native: fix uninstall self-destruction behavior...... by not showing the command prompt window and fork-spawning the cmd

* native: deal with Unicode issues in native APIs

* native: further improve Unicode support on Windows

* travis: add cache and fix issues

* ui: use Buefy components to...

... beautify the UI

* ui: makes error message selectable

* Make launcher mode behaviour more robust

* Fix error display on launcher pages

* Correctly handle exit on error

* Bump installer version
2019-07-04 21:23:16 -04:00

87 lines
2.4 KiB
Rust

//! frontend/rest/server.rs
//!
//! Contains the over-arching server object + methods to manipulate it.
use frontend::rest::services::WebService;
use installer::InstallerFramework;
use logging::LoggingErrors;
use hyper::server::Http;
use std::sync::{Arc, RwLock};
use std::net::{SocketAddr, TcpListener, ToSocketAddrs};
use std::thread;
use std::thread::JoinHandle;
/// Acts as a communication mechanism between the Hyper WebService and the rest of the
/// application.
pub struct WebServer {
_handle: JoinHandle<()>,
}
impl WebServer {
/// Creates a new web server with the specified address.
pub fn with_addr(
framework: Arc<RwLock<InstallerFramework>>,
addr: SocketAddr,
) -> Result<Self, hyper::Error> {
let handle = thread::spawn(move || {
let server = Http::new()
.bind(&addr, move || Ok(WebService::new(framework.clone())))
.log_expect("Failed to bind to port");
server.run().log_expect("Failed to run HTTP server");
});
Ok(WebServer { _handle: handle })
}
}
/// Spawns a server instance on all local interfaces.
///
/// Returns server instances + http address of service running.
pub fn spawn_servers(framework: Arc<RwLock<InstallerFramework>>) -> (Vec<WebServer>, String) {
// Firstly, allocate us an epidermal port
let target_port = {
let listener = TcpListener::bind("127.0.0.1:0")
.log_expect("At least one local address should be free");
listener
.local_addr()
.log_expect("Should be able to pull address from listener")
.port()
};
// Now, iterate over all ports
let addresses = "localhost:0"
.to_socket_addrs()
.log_expect("No localhost address found");
let mut instances = Vec::with_capacity(addresses.len());
let mut http_address = None;
// Startup HTTP server for handling the web view
for mut address in addresses {
address.set_port(target_port);
let server = WebServer::with_addr(framework.clone(), address)
.log_expect("Failed to bind to address");
info!("Spawning server instance @ {:?}", address);
http_address = Some(address);
instances.push(server);
}
let http_address = http_address.log_expect("No HTTP address found");
(
instances,
format!("http://localhost:{}", http_address.port()),
)
}