Preserve alternate screen snapshots and speed builds
This commit is contained in:
+5
-3
@@ -27,6 +27,8 @@ vt100 = "0.15"
|
|||||||
tempfile = "3.14"
|
tempfile = "3.14"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
opt-level = 2
|
||||||
lto = "thin"
|
codegen-units = 16
|
||||||
strip = true
|
incremental = true
|
||||||
|
lto = false
|
||||||
|
strip = false
|
||||||
|
|||||||
+15
-4
@@ -277,7 +277,7 @@ async fn handle_bootstrap_attach(
|
|||||||
session.parser.set_size(req.rows, req.cols);
|
session.parser.set_size(req.rows, req.cols);
|
||||||
}
|
}
|
||||||
let client_id = crypto::random_16();
|
let client_id = crypto::random_16();
|
||||||
let snapshot = session.parser.screen().state_formatted();
|
let snapshot = screen_snapshot(session.parser.screen());
|
||||||
let screen = session.parser.screen().clone();
|
let screen = session.parser.screen().clone();
|
||||||
let output_seq = session.output_seq;
|
let output_seq = session.output_seq;
|
||||||
session.clients.insert(
|
session.clients.insert(
|
||||||
@@ -385,7 +385,7 @@ async fn handle_ticket_attach(
|
|||||||
session.parser.set_size(req.rows, req.cols);
|
session.parser.set_size(req.rows, req.cols);
|
||||||
}
|
}
|
||||||
let client_id = crypto::random_16();
|
let client_id = crypto::random_16();
|
||||||
let snapshot = session.parser.screen().state_formatted();
|
let snapshot = screen_snapshot(session.parser.screen());
|
||||||
let screen = session.parser.screen().clone();
|
let screen = session.parser.screen().clone();
|
||||||
let output_seq = session.output_seq;
|
let output_seq = session.output_seq;
|
||||||
session.clients.insert(
|
session.clients.insert(
|
||||||
@@ -491,7 +491,7 @@ async fn handle_resume(
|
|||||||
session.pty.resize(req.cols, req.rows)?;
|
session.pty.resize(req.cols, req.rows)?;
|
||||||
session.parser.set_size(req.rows, req.cols);
|
session.parser.set_size(req.rows, req.cols);
|
||||||
}
|
}
|
||||||
let snapshot = session.parser.screen().state_formatted();
|
let snapshot = screen_snapshot(session.parser.screen());
|
||||||
client.last_screen = Some(session.parser.screen().clone());
|
client.last_screen = Some(session.parser.screen().clone());
|
||||||
(client.send_seq, session.output_seq, snapshot)
|
(client.send_seq, session.output_seq, snapshot)
|
||||||
};
|
};
|
||||||
@@ -675,7 +675,7 @@ async fn broadcast_output(
|
|||||||
let current_screen = session.parser.screen().clone();
|
let current_screen = session.parser.screen().clone();
|
||||||
let (bytes, snapshot) = if client.pending.len() >= retransmit_window {
|
let (bytes, snapshot) = if client.pending.len() >= retransmit_window {
|
||||||
client.pending.clear();
|
client.pending.clear();
|
||||||
(current_screen.state_formatted(), true)
|
(screen_snapshot(¤t_screen), true)
|
||||||
} else {
|
} else {
|
||||||
(output.bytes.clone(), false)
|
(output.bytes.clone(), false)
|
||||||
};
|
};
|
||||||
@@ -758,6 +758,17 @@ async fn broadcast_session_exit(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn screen_snapshot(screen: &vt100::Screen) -> Vec<u8> {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
if screen.alternate_screen() {
|
||||||
|
bytes.extend_from_slice(b"\x1b[?1049h");
|
||||||
|
} else {
|
||||||
|
bytes.extend_from_slice(b"\x1b[?1049l");
|
||||||
|
}
|
||||||
|
bytes.extend(screen.state_formatted());
|
||||||
|
bytes
|
||||||
|
}
|
||||||
|
|
||||||
async fn retransmit_pending(
|
async fn retransmit_pending(
|
||||||
state: &Arc<Mutex<ServerState>>,
|
state: &Arc<Mutex<ServerState>>,
|
||||||
socket: &Arc<UdpSocket>,
|
socket: &Arc<UdpSocket>,
|
||||||
|
|||||||
@@ -572,6 +572,63 @@ fn live_output_forwards_terminal_control_sequences() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resume_snapshot_preserves_alternate_screen_mode() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let port = free_udp_port();
|
||||||
|
let config = write_server_config(&dir, port);
|
||||||
|
let mut server = start_server(&dir, &config);
|
||||||
|
let (socket, bootstrap, ok) = direct_attach(&config, port, "read-write");
|
||||||
|
|
||||||
|
let input = Input {
|
||||||
|
bytes: b"printf '\\033[?1049hALT_SNAPSHOT'\n".to_vec(),
|
||||||
|
};
|
||||||
|
send_encrypted(
|
||||||
|
&socket,
|
||||||
|
port,
|
||||||
|
PacketKind::Input,
|
||||||
|
ok.client_id,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
&bootstrap.session_key,
|
||||||
|
&protocol::to_body(&input).unwrap(),
|
||||||
|
);
|
||||||
|
let _ = collect_frame_text(&socket, &bootstrap.session_key, 500);
|
||||||
|
let new_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||||
|
new_socket
|
||||||
|
.set_read_timeout(Some(Duration::from_secs(2)))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let resume = ResumeRequest {
|
||||||
|
session: "default".to_string(),
|
||||||
|
last_rendered_seq: ok.initial_seq,
|
||||||
|
cols: 80,
|
||||||
|
rows: 24,
|
||||||
|
};
|
||||||
|
send_encrypted(
|
||||||
|
&new_socket,
|
||||||
|
port,
|
||||||
|
PacketKind::ResumeRequest,
|
||||||
|
ok.client_id,
|
||||||
|
3,
|
||||||
|
0,
|
||||||
|
&bootstrap.session_key,
|
||||||
|
&protocol::to_body(&resume).unwrap(),
|
||||||
|
);
|
||||||
|
let (_header, resume_frame) =
|
||||||
|
recv_frame(&new_socket, &bootstrap.session_key).expect("resume response");
|
||||||
|
|
||||||
|
let _ = server.kill();
|
||||||
|
let _ = server.wait();
|
||||||
|
|
||||||
|
assert!(resume_frame.snapshot);
|
||||||
|
assert!(
|
||||||
|
resume_frame.bytes.starts_with(b"\x1b[?1049h"),
|
||||||
|
"snapshot did not enter alternate screen first: {:?}",
|
||||||
|
String::from_utf8_lossy(&resume_frame.bytes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resume_updates_udp_endpoint_for_roaming() {
|
fn resume_updates_udp_endpoint_for_roaming() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user