mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-02-17 14:07:28 +08:00
feat: file transfer, resume (#12626)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
2
.github/workflows/flutter-build.yml
vendored
2
.github/workflows/flutter-build.yml
vendored
@@ -38,7 +38,7 @@ env:
|
||||
# https://github.com/rustdesk/rustdesk/actions/runs/14414119794/job/40427970174
|
||||
# 2. Update the `VCPKG_COMMIT_ID` in `ci.yml` and `playground.yml`.
|
||||
VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836"
|
||||
VERSION: "1.4.1"
|
||||
VERSION: "1.4.2"
|
||||
NDK_VERSION: "r27c"
|
||||
#signing keys env variable checks
|
||||
ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"
|
||||
|
||||
2
.github/workflows/playground.yml
vendored
2
.github/workflows/playground.yml
vendored
@@ -17,7 +17,7 @@ env:
|
||||
TAG_NAME: "nightly"
|
||||
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||
VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836"
|
||||
VERSION: "1.4.1"
|
||||
VERSION: "1.4.2"
|
||||
NDK_VERSION: "r26d"
|
||||
#signing keys env variable checks
|
||||
ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"
|
||||
|
||||
4
.github/workflows/winget.yml
vendored
4
.github/workflows/winget.yml
vendored
@@ -10,6 +10,6 @@ jobs:
|
||||
- uses: vedantmgoyal9/winget-releaser@main
|
||||
with:
|
||||
identifier: RustDesk.RustDesk
|
||||
version: "1.4.1"
|
||||
release-tag: "1.4.1"
|
||||
version: "1.4.2"
|
||||
release-tag: "1.4.2"
|
||||
token: ${{ secrets.WINGET_TOKEN }}
|
||||
|
||||
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -6110,7 +6110,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustdesk"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
dependencies = [
|
||||
"android-wakelock",
|
||||
"android_logger",
|
||||
@@ -6216,7 +6216,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustdesk-portable-packer"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"dirs 5.0.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rustdesk"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
authors = ["rustdesk <info@rustdesk.com>"]
|
||||
edition = "2021"
|
||||
build= "build.rs"
|
||||
|
||||
@@ -18,7 +18,7 @@ AppDir:
|
||||
id: rustdesk
|
||||
name: rustdesk
|
||||
icon: rustdesk
|
||||
version: 1.4.1
|
||||
version: 1.4.2
|
||||
exec: usr/share/rustdesk/rustdesk
|
||||
exec_args: $@
|
||||
apt:
|
||||
|
||||
@@ -18,7 +18,7 @@ AppDir:
|
||||
id: rustdesk
|
||||
name: rustdesk
|
||||
icon: rustdesk
|
||||
version: 1.4.1
|
||||
version: 1.4.2
|
||||
exec: usr/share/rustdesk/rustdesk
|
||||
exec_args: $@
|
||||
apt:
|
||||
|
||||
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1, but iOS store not allow 4 numbers
|
||||
version: 1.4.1+59
|
||||
version: 1.4.2+60
|
||||
|
||||
environment:
|
||||
sdk: '^3.1.0'
|
||||
|
||||
Submodule libs/hbb_common updated: 57c8a23ab9...024380d0f9
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rustdesk-portable-packer"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
edition = "2021"
|
||||
description = "RustDesk Remote Desktop"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pkgname=rustdesk
|
||||
pkgver=1.4.1
|
||||
pkgver=1.4.2
|
||||
pkgrel=0
|
||||
epoch=
|
||||
pkgdesc=""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: rustdesk
|
||||
Version: 1.4.1
|
||||
Version: 1.4.2
|
||||
Release: 0
|
||||
Summary: RPM package
|
||||
License: GPL-3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: rustdesk
|
||||
Version: 1.4.1
|
||||
Version: 1.4.2
|
||||
Release: 0
|
||||
Summary: RPM package
|
||||
License: GPL-3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: rustdesk
|
||||
Version: 1.4.1
|
||||
Version: 1.4.2
|
||||
Release: 0
|
||||
Summary: RPM package
|
||||
License: GPL-3.0
|
||||
|
||||
@@ -704,6 +704,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
if is_remote {
|
||||
if let Some(job) = get_job(id, &mut self.write_jobs) {
|
||||
job.is_last_job = false;
|
||||
job.is_resume = true;
|
||||
allow_err!(
|
||||
peer.send(&fs::new_send(
|
||||
id,
|
||||
@@ -718,12 +719,13 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
} else {
|
||||
if let Some(job) = get_job(id, &mut self.read_jobs) {
|
||||
match &job.data_source {
|
||||
fs::DataSource::FilePath(p) => {
|
||||
fs::DataSource::FilePath(_p) => {
|
||||
job.is_last_job = false;
|
||||
job.is_resume = true;
|
||||
allow_err!(
|
||||
peer.send(&fs::new_receive(
|
||||
id,
|
||||
p.to_string_lossy().to_string(),
|
||||
job.remote.clone(),
|
||||
job.file_num,
|
||||
job.files.clone(),
|
||||
job.total_size(),
|
||||
@@ -771,7 +773,8 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
Some(file_transfer_send_confirm_request::Union::Skip(true))
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
})
|
||||
.await;
|
||||
}
|
||||
} else {
|
||||
if let Some(job) = fs::get_job(id, &mut self.write_jobs) {
|
||||
@@ -790,7 +793,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
job.confirm(&req).await;
|
||||
file_action.set_send_confirm(req);
|
||||
msg.set_file_action(file_action);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
@@ -1471,14 +1474,21 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
if let fs::DataSource::FilePath(p) = &job.data_source {
|
||||
let read_path =
|
||||
get_string(&fs::TransferJob::join(p, &file.name));
|
||||
let overwrite_strategy =
|
||||
let mut overwrite_strategy =
|
||||
job.default_overwrite_strategy();
|
||||
let mut offset = 0;
|
||||
if digest.is_identical && job.is_resume {
|
||||
if digest.transferred_size > 0 {
|
||||
overwrite_strategy = Some(true);
|
||||
offset = digest.transferred_size as _;
|
||||
}
|
||||
}
|
||||
if let Some(overwrite) = overwrite_strategy {
|
||||
let req = FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(if overwrite {
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(offset)
|
||||
} else {
|
||||
file_transfer_send_confirm_request::Union::Skip(
|
||||
true,
|
||||
@@ -1486,7 +1496,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
job.confirm(&req).await;
|
||||
let msg = new_send_confirm(req);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
} else {
|
||||
@@ -1507,25 +1517,40 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
if let fs::DataSource::FilePath(p) = &job.data_source {
|
||||
let write_path =
|
||||
get_string(&fs::TransferJob::join(p, &file.name));
|
||||
let overwrite_strategy =
|
||||
job.default_overwrite_strategy();
|
||||
job.set_digest(digest.file_size, digest.last_modified);
|
||||
let peer_ver = self.handler.lc.read().unwrap().version;
|
||||
let is_support_resume =
|
||||
crate::is_support_file_transfer_resume_num(
|
||||
peer_ver,
|
||||
);
|
||||
match fs::is_write_need_confirmation(
|
||||
is_support_resume && job.is_resume,
|
||||
&write_path,
|
||||
&digest,
|
||||
) {
|
||||
Ok(res) => match res {
|
||||
DigestCheckResult::IsSame => {
|
||||
let req = FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(file_transfer_send_confirm_request::Union::Skip(true)),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(file_transfer_send_confirm_request::Union::Skip(true)),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req).await;
|
||||
let msg = new_send_confirm(req);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
}
|
||||
DigestCheckResult::NeedConfirm(digest) => {
|
||||
let mut overwrite_strategy =
|
||||
job.default_overwrite_strategy();
|
||||
let mut offset = 0;
|
||||
if digest.is_identical
|
||||
&& job.is_resume
|
||||
&& digest.transferred_size > 0
|
||||
{
|
||||
overwrite_strategy = Some(true);
|
||||
offset = digest.transferred_size as _;
|
||||
}
|
||||
if let Some(overwrite) = overwrite_strategy
|
||||
{
|
||||
let req =
|
||||
@@ -1533,13 +1558,13 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(if overwrite {
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(offset)
|
||||
} else {
|
||||
file_transfer_send_confirm_request::Union::Skip(true)
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
job.confirm(&req).await;
|
||||
let msg = new_send_confirm(req);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
} else {
|
||||
@@ -1559,7 +1584,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
job.confirm(&req).await;
|
||||
let msg = new_send_confirm(req);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
}
|
||||
@@ -1906,7 +1931,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
},
|
||||
Some(file_action::Union::SendConfirm(c)) => {
|
||||
if let Some(job) = fs::get_job(c.id, &mut self.read_jobs) {
|
||||
job.confirm(&c);
|
||||
job.confirm(&c).await;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
||||
@@ -163,6 +163,16 @@ pub fn is_support_screenshot_num(ver: i64) -> bool {
|
||||
ver >= hbb_common::get_version_number("1.4.0")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_support_file_transfer_resume(ver: &str) -> bool {
|
||||
is_support_file_transfer_resume_num(hbb_common::get_version_number(ver))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_support_file_transfer_resume_num(ver: i64) -> bool {
|
||||
ver >= hbb_common::get_version_number("1.4.2")
|
||||
}
|
||||
|
||||
// is server process, with "--server" args
|
||||
#[inline]
|
||||
pub fn is_server() -> bool {
|
||||
|
||||
@@ -104,7 +104,9 @@ pub enum FS {
|
||||
file_size: u64,
|
||||
last_modified: u64,
|
||||
is_upload: bool,
|
||||
is_resume: bool,
|
||||
},
|
||||
SendConfirm(Vec<u8>),
|
||||
Rename {
|
||||
id: i32,
|
||||
path: String,
|
||||
|
||||
@@ -2705,7 +2705,11 @@ impl Connection {
|
||||
}
|
||||
Some(file_action::Union::SendConfirm(r)) => {
|
||||
if let Some(job) = fs::get_job(r.id, &mut self.read_jobs) {
|
||||
job.confirm(&r);
|
||||
job.confirm(&r).await;
|
||||
} else {
|
||||
if let Ok(sc) = r.write_to_bytes() {
|
||||
self.send_fs(ipc::FS::SendConfirm(sc));
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(file_action::Union::Rename(r)) => {
|
||||
@@ -2749,6 +2753,7 @@ impl Connection {
|
||||
file_size: d.file_size,
|
||||
last_modified: d.last_modified,
|
||||
is_upload: true,
|
||||
is_resume: d.is_resume,
|
||||
}),
|
||||
Some(file_response::Union::Error(e)) => {
|
||||
self.send_fs(ipc::FS::WriteError {
|
||||
|
||||
@@ -861,6 +861,7 @@ async fn handle_fs(
|
||||
file_size,
|
||||
last_modified,
|
||||
is_upload,
|
||||
is_resume,
|
||||
} => {
|
||||
if let Some(job) = fs::get_job(id, write_jobs) {
|
||||
let mut req = FileTransferSendConfirmRequest {
|
||||
@@ -879,8 +880,9 @@ async fn handle_fs(
|
||||
if let Some(file) = job.files().get(file_num as usize) {
|
||||
if let fs::DataSource::FilePath(p) = &job.data_source {
|
||||
let path = get_string(&fs::TransferJob::join(p, &file.name));
|
||||
match is_write_need_confirmation(&path, &digest) {
|
||||
match is_write_need_confirmation(is_resume, &path, &digest) {
|
||||
Ok(digest_result) => {
|
||||
job.set_digest(file_size, last_modified);
|
||||
match digest_result {
|
||||
DigestCheckResult::IsSame => {
|
||||
req.set_skip(true);
|
||||
@@ -910,6 +912,13 @@ async fn handle_fs(
|
||||
}
|
||||
}
|
||||
}
|
||||
ipc::FS::SendConfirm(bytes) => {
|
||||
if let Ok(r) = FileTransferSendConfirmRequest::parse_from_bytes(&bytes) {
|
||||
if let Some(job) = fs::get_job(r.id, write_jobs) {
|
||||
job.confirm(&r).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
ipc::FS::Rename { id, path, new_name } => {
|
||||
rename_file(path, new_name, id, tx).await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user