//! rest.rs //! //! Provides a HTTP/REST server for both frontend<->backend communication, as well //! as talking to external applications. use serde_json; use futures::future; use futures::Future; use futures::Sink; use futures::Stream; use hyper::header::{ContentLength, ContentType}; use hyper::server::{Http, Request, Response, Service}; use hyper::{self, Error as HyperError, Get, Post, StatusCode}; use url::form_urlencoded; use std::collections::HashMap; use std::net::SocketAddr; use std::process::exit; use std::sync::mpsc::channel; use std::sync::Arc; use std::sync::RwLock; use std::thread::{self, JoinHandle}; use assets; use installer::InstallMessage; use installer::InstallerFramework; #[derive(Serialize)] struct FileSelection { path: Option, } /// Acts as a communication mechanism between the Hyper WebService and the rest of the /// application. pub struct WebServer { _handle: JoinHandle<()>, addr: SocketAddr, } impl WebServer { /// Returns the bound address that the server is running from. pub fn get_addr(&self) -> SocketAddr { self.addr.clone() } /// Creates a new web server with the specified address. pub fn with_addr( framework: Arc>, addr: SocketAddr, ) -> Result { let (sender, receiver) = channel(); let handle = thread::spawn(move || { let server = Http::new() .bind(&addr, move || { Ok(WebService { framework: framework.clone(), }) }) .unwrap(); sender.send(server.local_addr().unwrap()).unwrap(); server.run().unwrap(); }); let addr = receiver.recv().unwrap(); Ok(WebServer { _handle: handle, addr, }) } } /// Holds internal state for Hyper struct WebService { framework: Arc>, } impl Service for WebService { type Request = Request; type Response = Response; type Error = hyper::Error; type Future = Box>; /// HTTP request handler fn call(&self, req: Self::Request) -> Self::Future { Box::new(future::ok(match (req.method(), req.path()) { // This endpoint should be usable directly from a