Update to actix-web 1.0 and use handlebars
This commit is contained in:
parent
d71b42665f
commit
e74a974d51
1260
Cargo.lock
generated
1260
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -16,10 +16,13 @@ travis-ci = { repository = "fubarnetes/webterm", branch = "master" }
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
||||
[dependencies]
|
||||
actix-files = "0.1.4"
|
||||
actix-service = "0.4.2"
|
||||
actix-web-actors = "1.0.2"
|
||||
actix-web= "1.0.8"
|
||||
actix= "0.8.3"
|
||||
askama = { version = "0.8.0", features= ["with-actix-web"] }
|
||||
futures = "0.1.29"
|
||||
handlebars = "2.0.2"
|
||||
lazy_static = "1.3.0"
|
||||
libc = "0.2.62"
|
||||
log = "0.4.8"
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use actix::Message;
|
||||
use actix_web::Binary;
|
||||
use futures::{Future, Poll};
|
||||
use libc::c_ushort;
|
||||
use tokio_pty_process::PtyMaster;
|
||||
@ -37,8 +36,8 @@ impl Message for IO {
|
||||
type Result = ();
|
||||
}
|
||||
|
||||
impl Into<Binary> for IO {
|
||||
fn into(self) -> Binary {
|
||||
impl Into<actix_web::web::Bytes> for IO {
|
||||
fn into(self) -> actix_web::web::Bytes {
|
||||
self.0.into()
|
||||
}
|
||||
}
|
||||
@ -49,8 +48,8 @@ impl AsRef<[u8]> for IO {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Binary> for IO {
|
||||
fn from(b: Binary) -> Self {
|
||||
impl From<actix_web::web::Bytes> for IO {
|
||||
fn from(b: actix_web::web::Bytes) -> Self {
|
||||
Self(b.as_ref().into())
|
||||
}
|
||||
}
|
||||
|
||||
63
src/lib.rs
63
src/lib.rs
@ -29,10 +29,11 @@
|
||||
|
||||
extern crate actix;
|
||||
extern crate actix_web;
|
||||
extern crate askama;
|
||||
extern crate futures;
|
||||
extern crate handlebars;
|
||||
extern crate libc;
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
extern crate tokio;
|
||||
extern crate tokio_codec;
|
||||
@ -41,12 +42,11 @@ extern crate tokio_pty_process;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate pretty_env_logger;
|
||||
use askama::actix_web::TemplateIntoResponse;
|
||||
|
||||
use actix::*;
|
||||
use actix_web::{ws, App};
|
||||
|
||||
use futures::prelude::*;
|
||||
use actix::prelude::*;
|
||||
use actix::{Actor, StreamHandler};
|
||||
use actix_web::{web, App, HttpRequest, HttpResponse};
|
||||
use actix_web_actors::ws;
|
||||
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
@ -55,11 +55,12 @@ use std::time::{Duration, Instant};
|
||||
use tokio_codec::{BytesCodec, Decoder, FramedRead};
|
||||
use tokio_pty_process::{AsyncPtyMaster, AsyncPtyMasterWriteHalf, Child, CommandExt};
|
||||
|
||||
use handlebars::Handlebars;
|
||||
|
||||
const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5);
|
||||
const CLIENT_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
|
||||
mod event;
|
||||
pub mod templates;
|
||||
mod terminado;
|
||||
|
||||
/// Actix WebSocket actor
|
||||
@ -175,6 +176,7 @@ impl StreamHandler<ws::Message, ws::ProtocolError> for Websocket {
|
||||
}
|
||||
ws::Message::Binary(b) => cons.do_send(event::IO::from(b)),
|
||||
ws::Message::Close(_) => ctx.stop(),
|
||||
ws::Message::Nop => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -341,7 +343,7 @@ pub trait WebTermExt {
|
||||
/// Serve the websocket for the webterm
|
||||
fn webterm_socket<F>(self: Self, endpoint: &str, handler: F) -> Self
|
||||
where
|
||||
F: Fn(&actix_web::Request) -> Command + 'static;
|
||||
F: Clone + Fn(&actix_web::HttpRequest) -> Command + 'static;
|
||||
|
||||
fn webterm_ui(
|
||||
self: Self,
|
||||
@ -351,14 +353,27 @@ pub trait WebTermExt {
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
impl WebTermExt for App<()> {
|
||||
impl<T, B> WebTermExt for App<T, B>
|
||||
where
|
||||
B: actix_web::body::MessageBody,
|
||||
T: actix_service::NewService<
|
||||
Config = (),
|
||||
Request = actix_web::dev::ServiceRequest,
|
||||
Response = actix_web::dev::ServiceResponse<B>,
|
||||
Error = actix_web::Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
fn webterm_socket<F>(self: Self, endpoint: &str, handler: F) -> Self
|
||||
where
|
||||
F: Fn(&actix_web::Request) -> Command + 'static,
|
||||
F: Clone + Fn(&actix_web::HttpRequest) -> Command + 'static,
|
||||
{
|
||||
self.resource(endpoint, move |r| {
|
||||
r.f(move |req| ws::start(req, Websocket::new(handler(req))))
|
||||
})
|
||||
self.route(
|
||||
endpoint,
|
||||
web::get().to(move |req: HttpRequest, stream: web::Payload| {
|
||||
ws::start(Websocket::new(handler(&req)), &req, stream)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn webterm_ui(
|
||||
@ -367,9 +382,23 @@ impl WebTermExt for App<()> {
|
||||
webterm_socket_endpoint: &str,
|
||||
static_path: &str,
|
||||
) -> Self {
|
||||
let template = templates::WebTerm::new(webterm_socket_endpoint, static_path);
|
||||
self.resource(endpoint, move |r| {
|
||||
r.get().f(move |_| template.into_response())
|
||||
})
|
||||
let mut handlebars = Handlebars::new();
|
||||
handlebars
|
||||
.register_templates_directory(".html", "./templates")
|
||||
.unwrap();
|
||||
let handlebars_ref = web::Data::new(handlebars);
|
||||
let static_path = static_path.to_owned();
|
||||
let webterm_socket_endpoint = webterm_socket_endpoint.to_owned();
|
||||
self.register_data(handlebars_ref.clone()).route(
|
||||
endpoint,
|
||||
web::get().to(move |hb: web::Data<Handlebars>| {
|
||||
let data = json!({
|
||||
"websocket_path": webterm_socket_endpoint,
|
||||
"static_path": static_path,
|
||||
});
|
||||
let body = hb.render("term", &data).unwrap();
|
||||
HttpResponse::Ok().body(body)
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
extern crate actix;
|
||||
extern crate actix_web;
|
||||
extern crate webterm;
|
||||
extern crate structopt;
|
||||
extern crate webterm;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use actix_web::{fs::StaticFiles, server, App};
|
||||
use actix_web::{App, HttpServer};
|
||||
use structopt::StructOpt;
|
||||
use webterm::WebTermExt;
|
||||
|
||||
@ -31,18 +31,12 @@ lazy_static! {
|
||||
static ref OPT: Opt = Opt::from_args();
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
pretty_env_logger::init();
|
||||
|
||||
server::new(|| {
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.handler(
|
||||
"/static",
|
||||
StaticFiles::new("node_modules")
|
||||
.unwrap()
|
||||
.show_files_listing(),
|
||||
)
|
||||
.service(actix_files::Files::new("/static", "./node_modules"))
|
||||
.webterm_socket("/websocket", |_req| {
|
||||
let mut cmd = Command::new(OPT.command.clone());
|
||||
cmd.env("TERM", "xterm");
|
||||
@ -52,5 +46,6 @@ fn main() {
|
||||
})
|
||||
.bind(format!("{}:{}", OPT.host, OPT.port))
|
||||
.unwrap()
|
||||
.run();
|
||||
.run()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
use askama::Template;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "term.html")]
|
||||
pub struct WebTerm {
|
||||
websocket_path: String,
|
||||
static_path: String,
|
||||
}
|
||||
|
||||
impl WebTerm {
|
||||
pub fn new<S>(websocket_path: S, static_path: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
Self {
|
||||
websocket_path: websocket_path.into(),
|
||||
static_path: static_path.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,12 +7,12 @@ SPDX-License-Identifier: BSD-3-Clause
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="{{ static_path|safe }}/xterm/dist/xterm.css" />
|
||||
<script src="{{ static_path|safe }}/xterm/dist/xterm.js"></script>
|
||||
<script src="{{ static_path|safe }}/xterm/dist/addons/attach/attach.js"></script>
|
||||
<script src="{{ static_path|safe }}/xterm/dist/addons/terminado/terminado.js"></script>
|
||||
<script src="{{ static_path|safe }}/xterm/dist/addons/fit/fit.js"></script>
|
||||
<script src="{{ static_path|safe }}/xterm/dist/addons/search/search.js"></script>
|
||||
<link rel="stylesheet" href="{{ static_path }}/xterm/dist/xterm.css" />
|
||||
<script src="{{ static_path }}/xterm/dist/xterm.js"></script>
|
||||
<script src="{{ static_path }}/xterm/dist/addons/attach/attach.js"></script>
|
||||
<script src="{{ static_path }}/xterm/dist/addons/terminado/terminado.js"></script>
|
||||
<script src="{{ static_path }}/xterm/dist/addons/fit/fit.js"></script>
|
||||
<script src="{{ static_path }}/xterm/dist/addons/search/search.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
@ -32,7 +32,7 @@ SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
var term = new Terminal();
|
||||
var protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
|
||||
var socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + "{{ websocket_path|safe }}";
|
||||
var socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + "{{ websocket_path }}";
|
||||
var sock = new WebSocket(socketURL);
|
||||
|
||||
sock.addEventListener('open', function() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user