Make command configurable per-request
This commit is contained in:
parent
c9c85aacab
commit
093e87fad9
30
src/lib.rs
30
src/lib.rs
@ -63,6 +63,7 @@ mod terminado;
|
|||||||
pub struct Websocket {
|
pub struct Websocket {
|
||||||
cons: Option<Addr<Terminal>>,
|
cons: Option<Addr<Terminal>>,
|
||||||
hb: Instant,
|
hb: Instant,
|
||||||
|
command: Option<Command>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for Websocket {
|
impl Actor for Websocket {
|
||||||
@ -72,8 +73,13 @@ impl Actor for Websocket {
|
|||||||
// Start heartbeat
|
// Start heartbeat
|
||||||
self.hb(ctx);
|
self.hb(ctx);
|
||||||
|
|
||||||
|
let command = self
|
||||||
|
.command
|
||||||
|
.take()
|
||||||
|
.expect("command was None at start of WebSocket.");
|
||||||
|
|
||||||
// Start PTY
|
// Start PTY
|
||||||
self.cons = Some(Terminal::new(ctx.address()).start());
|
self.cons = Some(Terminal::new(ctx.address(), command).start());
|
||||||
|
|
||||||
trace!("Started WebSocket");
|
trace!("Started WebSocket");
|
||||||
}
|
}
|
||||||
@ -117,10 +123,11 @@ impl Handler<event::TerminadoMessage> for Websocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Websocket {
|
impl Websocket {
|
||||||
pub fn new() -> Self {
|
pub fn new(command: Command) -> Self {
|
||||||
Self {
|
Self {
|
||||||
hb: Instant::now(),
|
hb: Instant::now(),
|
||||||
cons: None,
|
cons: None,
|
||||||
|
command: Some(command),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,14 +191,16 @@ pub struct Terminal {
|
|||||||
pty_write: Option<AsyncPtyMasterWriteHalf>,
|
pty_write: Option<AsyncPtyMasterWriteHalf>,
|
||||||
child: Option<Child>,
|
child: Option<Child>,
|
||||||
ws: Addr<Websocket>,
|
ws: Addr<Websocket>,
|
||||||
|
command: Command,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Terminal {
|
impl Terminal {
|
||||||
pub fn new(ws: Addr<Websocket>) -> Self {
|
pub fn new(ws: Addr<Websocket>, command: Command) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pty_write: None,
|
pty_write: None,
|
||||||
child: None,
|
child: None,
|
||||||
ws,
|
ws,
|
||||||
|
command,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +226,7 @@ impl Actor for Terminal {
|
|||||||
Ok(pty) => pty,
|
Ok(pty) => pty,
|
||||||
};
|
};
|
||||||
|
|
||||||
let child = match Command::new("/bin/sh").spawn_pty_async(&pty) {
|
let child = match self.command.spawn_pty_async(&pty) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Unable to spawn child: {:?}", e);
|
error!("Unable to spawn child: {:?}", e);
|
||||||
ctx.stop();
|
ctx.stop();
|
||||||
@ -327,11 +336,18 @@ impl Handler<event::TerminadoMessage> for Terminal {
|
|||||||
/// Trait to extend an [actix_web::App] by serving a web terminal.
|
/// Trait to extend an [actix_web::App] by serving a web terminal.
|
||||||
pub trait WebTermExt {
|
pub trait WebTermExt {
|
||||||
/// Serve the websocket for the webterm
|
/// Serve the websocket for the webterm
|
||||||
fn webterm_socket(self: Self, endpoint: &str) -> Self;
|
fn webterm_socket<F>(self: Self, endpoint: &str, handler: F) -> Self
|
||||||
|
where
|
||||||
|
F: Fn(&actix_web::Request) -> Command + 'static;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebTermExt for App<()> {
|
impl WebTermExt for App<()> {
|
||||||
fn webterm_socket(self: Self, endpoint: &str) -> Self {
|
fn webterm_socket<F>(self: Self, endpoint: &str, handler: F) -> Self
|
||||||
self.resource(endpoint, |r| r.f(|req| ws::start(req, Websocket::new())))
|
where
|
||||||
|
F: Fn(&actix_web::Request) -> Command + 'static,
|
||||||
|
{
|
||||||
|
self.resource(endpoint, move |r| {
|
||||||
|
r.f(move |req| ws::start(req, Websocket::new(handler(req))))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,8 @@ extern crate webterm;
|
|||||||
use actix_web::{fs::NamedFile, fs::StaticFiles, server, App, HttpRequest, Result};
|
use actix_web::{fs::NamedFile, fs::StaticFiles, server, App, HttpRequest, Result};
|
||||||
use webterm::WebTermExt;
|
use webterm::WebTermExt;
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
fn index(_req: &HttpRequest) -> Result<NamedFile> {
|
fn index(_req: &HttpRequest) -> Result<NamedFile> {
|
||||||
Ok(NamedFile::open("static/term.html")?)
|
Ok(NamedFile::open("static/term.html")?)
|
||||||
}
|
}
|
||||||
@ -20,7 +22,11 @@ fn main() {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.show_files_listing(),
|
.show_files_listing(),
|
||||||
)
|
)
|
||||||
.webterm_socket("/websocket")
|
.webterm_socket("/websocket", |_req| {
|
||||||
|
let mut cmd = Command::new("/bin/sh");
|
||||||
|
cmd.env("TERM", "xterm");
|
||||||
|
cmd
|
||||||
|
})
|
||||||
.resource("/", |r| r.f(index))
|
.resource("/", |r| r.f(index))
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8080")
|
.bind("127.0.0.1:8080")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user