Compare commits
No commits in common. "6736cdd431a7eb23f261d9ddc2051395e7b133aa" and "b8fe678ff057c647f4971465ad8b15a6d9f8c8d1" have entirely different histories.
6736cdd431
...
b8fe678ff0
9 changed files with 66 additions and 188 deletions
24
build.rs
24
build.rs
|
|
@ -52,9 +52,8 @@ fn emit_git_commit() {
|
||||||
eprintln!("`git rev-parse --short HEAD` failed, stderr: {stderr}");
|
eprintln!("`git rev-parse --short HEAD` failed, stderr: {stderr}");
|
||||||
panic!("`git rev-parse --short HEAD` failed");
|
panic!("`git rev-parse --short HEAD` failed");
|
||||||
}
|
}
|
||||||
let rev = std::str::from_utf8(&output.stdout)
|
let rev =
|
||||||
.expect("git did not output utf8")
|
std::str::from_utf8(&output.stdout).expect("git did not output utf8");
|
||||||
.trim();
|
|
||||||
|
|
||||||
println!("cargo::rustc-env=REPO_REV={rev}");
|
println!("cargo::rustc-env=REPO_REV={rev}");
|
||||||
}
|
}
|
||||||
|
|
@ -87,20 +86,13 @@ fn emit_git_dirty() {
|
||||||
// If there *was* any output, parse it and tell cargo to re-run if any of
|
// If there *was* any output, parse it and tell cargo to re-run if any of
|
||||||
// these files changed. (Maybe they get reverted! Then the repo status
|
// these files changed. (Maybe they get reverted! Then the repo status
|
||||||
// will change.)
|
// will change.)
|
||||||
let mut split = output.split('\x00');
|
for line in output.lines() {
|
||||||
while let Some(field) = split.next() {
|
let fields: Vec<_> = line.split('\x00').collect();
|
||||||
if field.is_empty() {
|
let parts: Vec<_> = fields[0].split(' ').collect();
|
||||||
continue;
|
let path = parts[1];
|
||||||
}
|
println!("cargo::rerun-if-changed={path}");
|
||||||
let prefix = &field[0..3];
|
|
||||||
println!("cargo::rerun-if-changed={}", &field[3..]);
|
|
||||||
let b = prefix.as_bytes();
|
|
||||||
if b[0] == b'R' || b[1] == b'R' || b[0] == b'C' || b[1] == b'C' {
|
|
||||||
if let Some(additional) = split.next() {
|
|
||||||
println!("cargo::rerun-if-changed={additional}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit the repository status.
|
// Emit the repository status.
|
||||||
let dirty = if output.trim().is_empty() {
|
let dirty = if output.trim().is_empty() {
|
||||||
""
|
""
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,6 @@ impl ServerConfig {
|
||||||
ServerConfig { auto: true, ports: HashMap::new() }
|
ServerConfig { auto: true, ports: HashMap::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub fn insert(&mut self, port: u16, config: PortConfig) {
|
|
||||||
self.ports.insert(port, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains_key(&self, port: u16) -> bool {
|
pub fn contains_key(&self, port: u16) -> bool {
|
||||||
self.ports.contains_key(&port)
|
self.ports.contains_key(&port)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::message::{Message, MessageReader, MessageWriter};
|
use crate::message::{Message, MessageReader, MessageWriter};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
|
use copypasta::{ClipboardContext, ClipboardProvider};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -212,11 +213,16 @@ async fn client_handle_messages<T: AsyncRead + Unpin>(
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipStart(id) => {
|
ClipStart(id) => {
|
||||||
|
info!("Starting clip op {id}");
|
||||||
clipboard_messages.insert(id, Vec::new());
|
clipboard_messages.insert(id, Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipData(id, mut data) => match clipboard_messages.get_mut(&id) {
|
ClipData(id, mut data) => match clipboard_messages.get_mut(&id) {
|
||||||
Some(bytes) => {
|
Some(bytes) => {
|
||||||
|
info!(
|
||||||
|
"Received data for clip op {id} ({len} bytes)",
|
||||||
|
len = data.len()
|
||||||
|
);
|
||||||
if bytes.len() < MAX_CLIPBOARD_SIZE {
|
if bytes.len() < MAX_CLIPBOARD_SIZE {
|
||||||
bytes.append(&mut data);
|
bytes.append(&mut data);
|
||||||
}
|
}
|
||||||
|
|
@ -237,10 +243,9 @@ async fn client_handle_messages<T: AsyncRead + Unpin>(
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) =
|
let mut ctx = ClipboardContext::new().unwrap();
|
||||||
events.send(ui::UIEvent::SetClipboard(data)).await
|
if let Err(e) = ctx.set_contents(data) {
|
||||||
{
|
error!("Unable to set clipboard data for op {id}: {e:?}");
|
||||||
error!("Error sending clipboard request: {:?}", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use super::{client_listen, config::ServerConfig};
|
use super::{client_listen, config::ServerConfig};
|
||||||
use crate::message::PortDesc;
|
use crate::message::PortDesc;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use copypasta::{ClipboardContext, ClipboardProvider};
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{Event, EventStream, KeyCode, KeyEvent, KeyModifiers},
|
event::{Event, EventStream, KeyCode, KeyEvent, KeyModifiers},
|
||||||
execute,
|
execute,
|
||||||
|
|
@ -34,7 +33,6 @@ pub enum UIEvent {
|
||||||
ServerLine(String),
|
ServerLine(String),
|
||||||
LogLine(log::Level, String),
|
LogLine(log::Level, String),
|
||||||
Ports(Vec<PortDesc>),
|
Ports(Vec<PortDesc>),
|
||||||
SetClipboard(String),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum UIReturn {
|
pub enum UIReturn {
|
||||||
|
|
@ -168,6 +166,7 @@ impl Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct UI {
|
pub struct UI {
|
||||||
events: mpsc::Receiver<UIEvent>,
|
events: mpsc::Receiver<UIEvent>,
|
||||||
ports: HashMap<u16, Listener>,
|
ports: HashMap<u16, Listener>,
|
||||||
|
|
@ -180,7 +179,6 @@ pub struct UI {
|
||||||
show_help: bool,
|
show_help: bool,
|
||||||
alternate_screen: bool,
|
alternate_screen: bool,
|
||||||
raw_mode: bool,
|
raw_mode: bool,
|
||||||
clipboard: ClipboardContext,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UI {
|
impl UI {
|
||||||
|
|
@ -197,8 +195,6 @@ impl UI {
|
||||||
config,
|
config,
|
||||||
alternate_screen: false,
|
alternate_screen: false,
|
||||||
raw_mode: false,
|
raw_mode: false,
|
||||||
clipboard: ClipboardContext::new()
|
|
||||||
.expect("Unable to initialize clipboard context"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,7 +567,7 @@ impl UI {
|
||||||
// Grab the selected port
|
// Grab the selected port
|
||||||
let selected_port = self.get_selected_port();
|
let selected_port = self.get_selected_port();
|
||||||
|
|
||||||
for mut port_desc in p.into_iter() {
|
for port_desc in p.into_iter() {
|
||||||
leftover_ports.remove(&port_desc.port);
|
leftover_ports.remove(&port_desc.port);
|
||||||
if let Some(listener) = self.ports.get_mut(&port_desc.port)
|
if let Some(listener) = self.ports.get_mut(&port_desc.port)
|
||||||
{
|
{
|
||||||
|
|
@ -579,8 +575,6 @@ impl UI {
|
||||||
} else {
|
} else {
|
||||||
let config = self.config.get(port_desc.port);
|
let config = self.config.get(port_desc.port);
|
||||||
info!("Port config {port_desc:?} -> {config:?}");
|
info!("Port config {port_desc:?} -> {config:?}");
|
||||||
port_desc.desc =
|
|
||||||
config.description.unwrap_or(port_desc.desc);
|
|
||||||
|
|
||||||
self.ports.insert(
|
self.ports.insert(
|
||||||
port_desc.port,
|
port_desc.port,
|
||||||
|
|
@ -627,14 +621,6 @@ impl UI {
|
||||||
}
|
}
|
||||||
self.lines.push_back(format!("[CLIENT] {line}"));
|
self.lines.push_back(format!("[CLIENT] {line}"));
|
||||||
}
|
}
|
||||||
Some(UIEvent::SetClipboard(contents)) => {
|
|
||||||
let length = contents.len();
|
|
||||||
if let Err(e) = self.clipboard.set_contents(contents) {
|
|
||||||
error!("Error setting clipboard contents: {e:#}");
|
|
||||||
} else {
|
|
||||||
info!("Received clipboard contents ({length} bytes)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
self.running = false;
|
self.running = false;
|
||||||
}
|
}
|
||||||
|
|
@ -674,8 +660,6 @@ fn centered_rect(width_chars: u16, height_chars: u16, r: Rect) -> Rect {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::client::config::PortConfig;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
|
|
||||||
|
|
@ -940,56 +924,4 @@ mod tests {
|
||||||
assert_eq!(centered.width, 10);
|
assert_eq!(centered.width, 10);
|
||||||
assert_eq!(centered.height, 10);
|
assert_eq!(centered.height, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn port_config_description_respected() {
|
|
||||||
let (sender, receiver) = mpsc::channel(64);
|
|
||||||
let mut config = ServerConfig::default();
|
|
||||||
config.insert(
|
|
||||||
8080,
|
|
||||||
PortConfig {
|
|
||||||
enabled: true,
|
|
||||||
description: Some("override".to_string()),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut ui = UI::new(receiver, config);
|
|
||||||
|
|
||||||
// There are ports...
|
|
||||||
ui.handle_internal_event(Some(UIEvent::Ports(vec![PortDesc {
|
|
||||||
port: 8080,
|
|
||||||
desc: "my-service".to_string(),
|
|
||||||
}])));
|
|
||||||
|
|
||||||
let description = ui.ports.get(&8080).unwrap().desc.as_ref().unwrap();
|
|
||||||
assert_eq!(description.desc, "override");
|
|
||||||
|
|
||||||
drop(sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn port_config_enabled_respected() {
|
|
||||||
let (sender, receiver) = mpsc::channel(64);
|
|
||||||
let mut config = ServerConfig::default();
|
|
||||||
config.insert(
|
|
||||||
8080,
|
|
||||||
PortConfig {
|
|
||||||
enabled: false,
|
|
||||||
description: Some("override".to_string()),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut ui = UI::new(receiver, config);
|
|
||||||
|
|
||||||
// There are ports...
|
|
||||||
ui.handle_internal_event(Some(UIEvent::Ports(vec![PortDesc {
|
|
||||||
port: 8080,
|
|
||||||
desc: "my-service".to_string(),
|
|
||||||
}])));
|
|
||||||
|
|
||||||
let state = ui.ports.get(&8080).unwrap().state();
|
|
||||||
assert_eq!(state, State::Disabled);
|
|
||||||
|
|
||||||
drop(sender);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,6 @@ mod message;
|
||||||
mod reverse;
|
mod reverse;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
||||||
pub const REV: &str = env!("REPO_REV");
|
|
||||||
pub const DIRTY: &str = env!("REPO_DIRTY");
|
|
||||||
|
|
||||||
pub use client::run_client;
|
pub use client::run_client;
|
||||||
pub use reverse::browse_url;
|
pub use reverse::browse_url;
|
||||||
pub use reverse::clip_file;
|
pub use reverse::clip_file;
|
||||||
|
|
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -1,6 +1,10 @@
|
||||||
// TODO: An actual proper command line parsing
|
// TODO: An actual proper command line parsing
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
|
|
||||||
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
const REV: &str = env!("REPO_REV");
|
||||||
|
const DIRTY: &str = env!("REPO_DIRTY");
|
||||||
|
|
||||||
fn usage() {
|
fn usage() {
|
||||||
println!(indoc! {"
|
println!(indoc! {"
|
||||||
usage: fwd [options] (<server> | browse <url> | clip [<file>])
|
usage: fwd [options] (<server> | browse <url> | clip [<file>])
|
||||||
|
|
@ -117,7 +121,7 @@ fn parse_args(args: Vec<String>) -> Args {
|
||||||
async fn browse_url(url: &str) {
|
async fn browse_url(url: &str) {
|
||||||
if let Err(e) = fwd::browse_url(url).await {
|
if let Err(e) = fwd::browse_url(url).await {
|
||||||
eprintln!("Unable to open {url}");
|
eprintln!("Unable to open {url}");
|
||||||
eprintln!("{:#}", e);
|
eprintln!("{}", e);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +129,7 @@ async fn browse_url(url: &str) {
|
||||||
async fn clip_file(file: String) {
|
async fn clip_file(file: String) {
|
||||||
if let Err(e) = fwd::clip_file(&file).await {
|
if let Err(e) = fwd::clip_file(&file).await {
|
||||||
eprintln!("Unable to copy to the clipboard");
|
eprintln!("Unable to copy to the clipboard");
|
||||||
eprintln!("{:#}", e);
|
eprintln!("{}", e);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +141,7 @@ async fn main() {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
Args::Version => {
|
Args::Version => {
|
||||||
println!("fwd {} (rev {}{})", fwd::VERSION, fwd::REV, fwd::DIRTY);
|
println!("fwd {VERSION} (rev {REV}{DIRTY})");
|
||||||
}
|
}
|
||||||
Args::Server => {
|
Args::Server => {
|
||||||
fwd::run_server().await;
|
fwd::run_server().await;
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,16 @@ use tokio::io::{AsyncRead, AsyncReadExt};
|
||||||
mod unix;
|
mod unix;
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
pub use unix::{handle_reverse_connections, ReverseConnection};
|
pub use unix::{handle_reverse_connections, send_reverse_message};
|
||||||
|
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
|
|
||||||
#[cfg(not(target_family = "unix"))]
|
#[cfg(not(target_family = "unix"))]
|
||||||
pub struct ReverseConnection {}
|
pub async fn send_reverse_message(_message: Message) -> Result<()> {
|
||||||
|
use anyhow::anyhow;
|
||||||
#[cfg(not(target_family = "unix"))]
|
Err(anyhow!(
|
||||||
impl ReverseConnection {
|
"Server-side operations are not supported on this platform"
|
||||||
pub async fn new() -> Result<Self> {
|
))
|
||||||
use anyhow::anyhow;
|
|
||||||
Err(anyhow!(
|
|
||||||
"Server-side operations are not supported on this platform"
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send(&mut self, message: Message) -> Result<()> {
|
|
||||||
use anyhow::anyhow;
|
|
||||||
Err(anyhow!(
|
|
||||||
"Server-side operations are not supported on this platform"
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_family = "unix"))]
|
#[cfg(not(target_family = "unix"))]
|
||||||
|
|
@ -39,16 +27,12 @@ pub async fn handle_reverse_connections(
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn browse_url(url: &str) -> Result<()> {
|
pub async fn browse_url(url: &str) -> Result<()> {
|
||||||
ReverseConnection::new()
|
send_reverse_message(Message::Browse(url.to_string())).await
|
||||||
.await?
|
|
||||||
.send(Message::Browse(url.to_string()))
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn clip_reader<T: AsyncRead + Unpin>(reader: &mut T) -> Result<()> {
|
async fn clip_reader<T: AsyncRead + Unpin>(reader: &mut T) -> Result<()> {
|
||||||
let mut connection = ReverseConnection::new().await?;
|
|
||||||
let clip_id: u64 = random();
|
let clip_id: u64 = random();
|
||||||
connection.send(Message::ClipStart(clip_id)).await?;
|
send_reverse_message(Message::ClipStart(clip_id)).await?;
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let mut buf = vec![0; 1024];
|
let mut buf = vec![0; 1024];
|
||||||
|
|
@ -59,7 +43,7 @@ async fn clip_reader<T: AsyncRead + Unpin>(reader: &mut T) -> Result<()> {
|
||||||
}
|
}
|
||||||
count += read;
|
count += read;
|
||||||
if count == buf.len() {
|
if count == buf.len() {
|
||||||
connection.send(Message::ClipData(clip_id, buf)).await?;
|
send_reverse_message(Message::ClipData(clip_id, buf)).await?;
|
||||||
buf = vec![0; 1024];
|
buf = vec![0; 1024];
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -67,10 +51,10 @@ async fn clip_reader<T: AsyncRead + Unpin>(reader: &mut T) -> Result<()> {
|
||||||
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
buf.resize(count, 0);
|
buf.resize(count, 0);
|
||||||
connection.send(Message::ClipData(clip_id, buf)).await?;
|
send_reverse_message(Message::ClipData(clip_id, buf)).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.send(Message::ClipEnd(clip_id)).await?;
|
send_reverse_message(Message::ClipEnd(clip_id)).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,32 @@ use tokio::sync::mpsc;
|
||||||
|
|
||||||
use crate::message::{Message, MessageReader, MessageWriter};
|
use crate::message::{Message, MessageReader, MessageWriter};
|
||||||
|
|
||||||
pub struct ReverseConnection {
|
pub async fn send_reverse_message(message: Message) -> Result<()> {
|
||||||
writer: MessageWriter<UnixStream>,
|
let path = socket_path().context("Error getting socket path")?;
|
||||||
|
let stream = match UnixStream::connect(&path).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => bail!(
|
||||||
|
"Error connecting to socket: {e} (is fwd actually connected here?)"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
let mut writer = MessageWriter::new(stream);
|
||||||
|
writer
|
||||||
|
.write(message)
|
||||||
|
.await
|
||||||
|
.context("Error sending browse message")?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReverseConnection {
|
fn socket_directory() -> Result<std::path::PathBuf> {
|
||||||
pub async fn new() -> Result<Self> {
|
let base_directories = xdg::BaseDirectories::new()
|
||||||
let path = socket_path().context("Error getting socket path")?;
|
.context("Error creating BaseDirectories")?;
|
||||||
let stream = match UnixStream::connect(&path).await {
|
match base_directories.place_runtime_file("fwd") {
|
||||||
Ok(s) => s,
|
Ok(path) => Ok(path),
|
||||||
Err(e) => bail!("Error connecting to socket: {e} (is fwd actually connected here?)"),
|
Err(_) => {
|
||||||
};
|
let mut path = std::env::temp_dir();
|
||||||
|
path.push(format!("fwd{}", users::get_current_uid()));
|
||||||
Ok(ReverseConnection { writer: MessageWriter::new(stream) })
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&mut self, message: Message) -> Result<()> {
|
|
||||||
self.writer
|
|
||||||
.write(message)
|
|
||||||
.await
|
|
||||||
.context("Error sending reverse message")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,19 +53,6 @@ pub fn socket_path() -> Result<PathBuf> {
|
||||||
Ok(socket_path)
|
Ok(socket_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn socket_directory() -> Result<std::path::PathBuf> {
|
|
||||||
let base_directories = xdg::BaseDirectories::new()
|
|
||||||
.context("Error creating BaseDirectories")?;
|
|
||||||
match base_directories.place_runtime_file("fwd") {
|
|
||||||
Ok(path) => Ok(path),
|
|
||||||
Err(_) => {
|
|
||||||
let mut path = std::env::temp_dir();
|
|
||||||
path.push(format!("fwd{}", users::get_current_uid()));
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn handle_reverse_connections(
|
pub async fn handle_reverse_connections(
|
||||||
messages: mpsc::Sender<Message>,
|
messages: mpsc::Sender<Message>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
|
@ -95,18 +87,10 @@ async fn handle_connection(
|
||||||
sender: mpsc::Sender<Message>,
|
sender: mpsc::Sender<Message>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut reader = MessageReader::new(socket);
|
let mut reader = MessageReader::new(socket);
|
||||||
while let Ok(message) = reader.read().await {
|
let message = reader.read().await.context("Error reading message")?;
|
||||||
match message {
|
match message {
|
||||||
Message::Browse(url) => sender.send(Message::Browse(url)).await?,
|
Message::Browse(url) => sender.send(Message::Browse(url)).await?,
|
||||||
Message::ClipStart(id) => {
|
_ => bail!("Unsupported message: {:?}", message),
|
||||||
sender.send(Message::ClipStart(id)).await?
|
|
||||||
}
|
|
||||||
Message::ClipData(id, data) => {
|
|
||||||
sender.send(Message::ClipData(id, data)).await?
|
|
||||||
}
|
|
||||||
Message::ClipEnd(id) => sender.send(Message::ClipEnd(id)).await?,
|
|
||||||
_ => bail!("Unsupported message: {:?}", message),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -26,26 +26,12 @@ async fn server_loop<Reader: AsyncRead + Unpin>(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// The first message we send must be an announcement.
|
// The first message we send must be an announcement.
|
||||||
writer.send(Message::Hello(0, 2, vec![])).await?;
|
writer.send(Message::Hello(0, 2, vec![])).await?;
|
||||||
let mut version_reported = false;
|
|
||||||
loop {
|
loop {
|
||||||
use Message::*;
|
use Message::*;
|
||||||
match reader.read().await? {
|
match reader.read().await? {
|
||||||
Ping => (),
|
Ping => (),
|
||||||
Refresh => {
|
Refresh => {
|
||||||
// Just log the version, if we haven't yet. We do this extra
|
|
||||||
// work to avoid spamming the log, but we wait until we
|
|
||||||
// receive the first message to be sure that the client is in
|
|
||||||
// a place to display our logging properly.
|
|
||||||
if !version_reported {
|
|
||||||
eprintln!(
|
|
||||||
"fwd server {} (rev {}{})",
|
|
||||||
crate::VERSION,
|
|
||||||
crate::REV,
|
|
||||||
crate::DIRTY
|
|
||||||
);
|
|
||||||
version_reported = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ports = match refresh::get_entries().await {
|
let ports = match refresh::get_entries().await {
|
||||||
Ok(ports) => ports,
|
Ok(ports) => ports,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue