diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-11-15 13:11:07 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-11-15 13:11:07 -0500 |
commit | bbf15cfef8134da720a27bd71a93efcb8467025b (patch) | |
tree | aa58a5d7c1862fcdd6c8629651f664aa12c70f66 /teleterm/src/web.rs | |
parent | fe4fa53dbbb6030beae2094e33d1db008532ae3c (diff) | |
download | teleterm-bbf15cfef8134da720a27bd71a93efcb8467025b.tar.gz teleterm-bbf15cfef8134da720a27bd71a93efcb8467025b.zip |
use workspaces
Diffstat (limited to 'teleterm/src/web.rs')
-rw-r--r-- | teleterm/src/web.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/teleterm/src/web.rs b/teleterm/src/web.rs new file mode 100644 index 0000000..afc5128 --- /dev/null +++ b/teleterm/src/web.rs @@ -0,0 +1,87 @@ +mod ws; + +use futures::{Future as _, Sink as _, Stream as _}; +use gotham::router::builder::{DefineSingleRoute as _, DrawRoutes as _}; +use gotham::state::FromState as _; + +pub fn router() -> impl gotham::handler::NewHandler { + gotham::router::builder::build_simple_router(|route| { + route.get("/").to(root); + route.get("/ws").to(handle_websocket_connection); + }) +} + +fn root(state: gotham::state::State) -> (gotham::state::State, String) { + log::info!("request for /"); + (state, "hello world".to_string()) +} + +fn handle_websocket_connection( + mut state: gotham::state::State, +) -> (gotham::state::State, hyper::Response<hyper::Body>) { + let body = hyper::Body::take_from(&mut state); + let headers = hyper::HeaderMap::take_from(&mut state); + if ws::requested(&headers) { + let (response, stream) = match ws::accept(&headers, body) { + Ok(res) => res, + Err(_) => { + log::error!("failed to accept websocket request"); + return ( + state, + hyper::Response::builder() + .status(hyper::StatusCode::BAD_REQUEST) + .body(hyper::Body::empty()) + .unwrap(), + ); + } + }; + let req_id = gotham::state::request_id(&state).to_owned(); + let stream = stream + .map_err(|e| { + log::error!( + "error upgrading connection for websockets: {}", + e + ) + }) + .and_then(move |stream| handle_websocket_stream(req_id, stream)); + tokio::spawn(stream); + (state, response) + } else { + ( + state, + hyper::Response::new(hyper::Body::from( + "non-websocket request to websocket endpoint", + )), + ) + } +} + +fn handle_websocket_stream<S>( + req_id: String, + stream: S, +) -> impl futures::Future<Item = (), Error = ()> +where + S: futures::Stream< + Item = tokio_tungstenite::tungstenite::protocol::Message, + Error = tokio_tungstenite::tungstenite::Error, + > + futures::Sink< + SinkItem = tokio_tungstenite::tungstenite::protocol::Message, + SinkError = tokio_tungstenite::tungstenite::Error, + >, +{ + let (sink, stream) = stream.split(); + sink.send_all(stream.map(move |msg| { + handle_websocket_message(&req_id, &msg); + msg + })) + .map_err(|e| log::error!("error during websocket stream: {}", e)) + .map(|_| log::info!("disconnect")) +} + +fn handle_websocket_message( + req_id: &str, + msg: &tokio_tungstenite::tungstenite::protocol::Message, +) { + // TODO + log::info!("websocket stream message for {}: {:?}", req_id, msg); +} |