Releases: lotgon/folder-transfer
Release list
folder-transfer v0.16.0
folder-transfer v0.16.0
Adds an embeddable library so you can drive transfers from your own code (no spawning the CLI).
PowerShell scripts unchanged.
Artifacts
folder-transfer-0.16.0.zip— the PowerShell sender (reference implementation).ft-0.16.0-x86_64-windows.zip—ft.exe+ft.dll(+ft.dll.lib), the C header
ft.h, and a .NET bindingFolderTransfer.cs, plusserver.example.json.ft-0.16.0-x86_64-linux.tar.gz—ft(static musl CLI) +libft.so(glibc, for embedding),
ft.h,server.example.json.
New: C-ABI library (ft.dll / libft.so)
Call file transfer straight from .NET (P/Invoke), C, or C++:
ft_get(server, port, token, fingerprint, to, ignore, streams)— pull a folder.ft_serve_start(folder, port, streams, ignore, no_compress, once, out_token, …, out_fp, …)—
serve in the background; the token + certificate fingerprint come back immediately to hand to the
receiver.ft_serve_wait(handle)blocks until it finishes.ft_last_error(buf, len)— last error for the current thread.
A ready C# wrapper (FolderTransfer.cs) is included:
var srv = new FolderTransfer.Server(@"D:\data", 8722); // returns srv.Token, srv.Fingerprint
FolderTransfer.Get("10.0.0.1", 8722, token, fingerprint, @"E:\incoming"); // on the receiver
srv.Wait();Everything from 0.15.x (no subcommand, server-pushed config, interactive destination, live
progress, read-timeout/keepalives) is included. CLI behaviour is unchanged.
folder-transfer v0.15.3
folder-transfer v0.15.3
Reliability fix for the Rust ft client. PowerShell scripts unchanged.
Artifacts
folder-transfer-0.15.3.zip— the PowerShell sender (reference implementation).ft-0.15.3-x86_64-windows.zip— Rustft.exefor Windows (+server.example.json).ft-0.15.3-x86_64-linux.tar.gz— Rustftfor Linux, static musl (+server.example.json).
Fixed
- No more silent hang when the connection drops. Previously, if the link stalled or dropped
mid-sync the client would sit forever at the last progress line with no message. Now it has a read
timeout and fails fast with a clear message —connection to the server was lost before the sync finished+sync INCOMPLETE … re-run to resume— and exits non-zero. - The server sends
PINGkeepalives while it waits for its file-walker, so the timeout never fires
on a slow scan (the client ignoresPING). - The client now always prints a final line:
sync DONE …on success,sync INCOMPLETE …on a drop.
Everything from 0.15.2 (no subcommand, server-pushed config, interactive destination, live
aggregated progress with elapsed time, highlighted copy-command) is included.
folder-transfer v0.15.2
folder-transfer v0.15.2
The complete Rust ft drop (supersedes the partial 0.15.1). PowerShell scripts unchanged.
Artifacts
folder-transfer-0.15.2.zip— the PowerShell sender (reference implementation).ft-0.15.2-x86_64-windows.zip— Rustft.exefor Windows (+server.example.json).ft-0.15.2-x86_64-linux.tar.gz— Rustftfor Linux, static musl (+server.example.json).
Highlights
- No subcommand needed —
ft <folder|server.json>serves;ft <connection.json> [DEST]receives. - Server pushes config after connecting, so the connection file/command carry only
server/port/token/fingerprint(the client gets ignore patterns + stream count automatically). - Interactive destination — omit it and the client asks (Enter = current folder).
- Highlighted, cream-coloured "copy this" command printed by the server.
- Live aggregated progress on both sides:
N files, X MB in MM:SS @ Y MB/s(summed across all
streams, with elapsed time; mid-file ticks so one big file isn't silent). - Fixes: empty-string config values (
clientOut/serverHost/allowIp= "") treated as
"not set"; filesystem errors name the offending path;--allow-ipenforced.
See CHANGELOG.md. Cross-OS (Windows↔Ubuntu) verified byte-for-byte.
folder-transfer v0.15.1
folder-transfer v0.15.1
Quality-of-life update to the Rust ft port. PowerShell scripts unchanged.
Artifacts
folder-transfer-0.15.1.zip— the PowerShell sender (reference implementation).ft-0.15.1-x86_64-windows.zip— Rustft.exefor Windows (+server.example.json).ft-0.15.1-x86_64-linux.tar.gz— Rustftfor Linux, static musl (+server.example.json).
What's new
-
No subcommand needed — point
ftat a folder or a JSON, PowerShell-style. The first
argument is auto-routed:ft server.example.jsonorft C:\data→ serveft ft-download-Name.json D:\incoming→ receive (2nd arg = destination)
ft serve/ft getstill work if you want to be explicit; extra flags (--port,--once, …)
still override the JSON. -
server.example.jsonincluded in the Rust archives — a ready, fully-commented server config
(same keys as the PowerShellft-server.ps1). It runs out of the box:
ft server.example.json(edit thefolderslist to taste).
See CHANGELOG.md.
folder-transfer v0.15.0
folder-transfer v0.15.0
This release ships the new Rust port (ft) alongside the existing PowerShell tool —
both side by side, in one release.
Artifacts
folder-transfer-0.15.0.zip— the PowerShell sender (unchanged reference implementation).ft-0.15.0-x86_64-windows.zip— Rustft.exefor Windows.ft-0.15.0-x86_64-linux.tar.gz— Rustftfor Linux, fully static (musl), no dependencies.
Highlights
- One self-contained binary on Windows and Linux, wire-compatible with the PowerShell tool:
ft serve(== ft-server.ps1) andft get(== ft-client.ps1), single-stream and parallel. - TLS 1.2/1.3 (rustls) + SHA-256 certificate pinning, auto token, adaptive per-block compression,
JSONC config (CLI wins), ignore-pattern parity,--allow-ip, mirror delete. - Verified Windows ↔ Ubuntu byte-for-byte with mtime-ticks preserved (no-op re-syncs).
- ~1.5× raw LAN goodput on incompressible data vs PowerShell and 94–99% saturation on fast links —
see BENCHMARKS-rust.md.
See CHANGELOG.md for details. The PowerShell scripts are
unchanged and remain the protocol reference.
folder-transfer v0.14.0
Added
- Adaptive compression. Compression is no longer all‑or‑nothing: the server measures, per
connection, how fast it actually moves data raw vs compressed and only compresses when that is at
least 25% faster end‑to‑end. On a fast LAN it sends raw (compression there is pure CPU cost
and roughly halved throughput); on a slow or compressible link it compresses and effective
throughput rises by about the compression ratio. Fully automatic —-NoCompressstill forces it
off. The wire format is unchanged (the receiver already decodes mixed raw/compressed blocks). - Benchmark suite (
bench/).bench\bench.ps1builds corpora, drives real transfers through a
bandwidth/latency‑emulating proxy (bench\bench-proxy.ps1), and writesBENCHMARKS.md; method
and reproduction steps inbench/README.md. A results table is shown on the project home page.
Changed
- Hot path moved from cmdlets to .NET on both sides (file existence/size/mtime checks, directory
creation, timestamps, line timing) — a measurable speed‑up on many‑small‑file transfers, in both
single‑stream and parallel modes.
Fixed
- Destination on an 8.3 short path synced nothing. If
-ToFolderresolved to a short path
(e.g.C:\Users\RUNNER~1\...), the receiver's path‑safety check compared a short root against
expanded target paths and rejected every file as unsafe. The destination is now normalised the
same way as the targets. - Files >= 2 GB in the raw (uncompressed) path crashed with an Int32 overflow in the read loop;
the byte count is now 64‑bit throughout. - Small parallel jobs could skip the mirror delete. A stream that lost the connect race and
claimed no work was treated as a failed stream, marking the whole run incomplete so nothing was
deleted; such idle streams are now benign and the reconciliation pass runs as intended.
folder-transfer v0.13.0
Changed
- Parallel mode now shards by fine‑grained work units (bundles / large files), not whole
folders. A single producer lazily walks the source and feeds a bounded shared queue; the N
connections pull units until it's drained. Result: even one giant folder now spreads across all
streams automatically — no need to split it into separatefoldersentries for balance. - Mirror is exact again in parallel mode. All streams record what they received into one shared
set; after every stream finishes cleanly, the receiver does a single reconciliation pass and
deletes any local file the source no longer has — including files under a whole top‑level folder
removed on the source. This removes the v0.12.0 limitation where vanished top‑level folders were
not pruned in parallel mode. If any stream drops, the run is treated as incomplete and nothing is
deleted that time (re‑run to complete). As before, the mirror deletes files, not directories.
Fixed
- Parallel server handlers initialise their progress timers before sending, fixing an
op_Subtractionerror that could abort sends (and write 0‑byte files) under the new unit model.
folder-transfer v0.12.0
Added
- Parallel streams (
-Streams <n>, default 4). Transfers now use several TCP connections at
once, which lifts the single‑connectionwindow ÷ RTTthroughput ceiling — a large speed‑up on
high‑latency links. The sender queues the shared folders and each connection pulls a whole folder
at a time (runspace per connection on both sides), so the streams self‑balance. Small‑file
bundling and adaptive compression still apply within each stream. Set-Streams 1(or
"streams": 1) for the classic single‑stream behavior;-Cutoverforces single‑stream.
Notes / limitations
- Balance is per shared folder — a single giant folder is handled by one connection and is not
split across streams. List its subfolders as separatefoldersentries to parallelize one big
tree. - In parallel mode, a whole top‑level folder deleted on the source is not auto‑removed on the
receiver (files removed inside a folder still are). This keeps the per‑folder mirror simple and
always correct; run once with-Streams 1to prune vanished folders, or delete them by hand. The
server and client print this caveat at startup when-Streams > 1.
folder-transfer v0.11.3
Changed
- Adaptive compression — try, and back off when it doesn't help. For large files the per‑block
compressor now measures each 1 MB block: if it doesn't shrink (≥ 5 %) the block is sent raw, and
after a few poor blocks the server stops compressing for a while before probing again. So no CPU
is wasted compressing data that doesn't compress (e.g. an unknown but already‑compressed format),
and incompressible data is never expanded on the wire. Known already‑compressed extensions still
skip compression up front.
folder-transfer v0.11.2
Changed
- Bundle by size, and bundle bigger files. Small‑file bundling now batches files up to 1 MB
(was 64 KB) and flushes a bundle once it has accumulated ~10 MB of files (was a flat
1024‑file count), with a 4096‑file safety cap for huge numbers of tiny files. Grouping by size
means each round‑trip carries a meaningful chunk of data regardless of individual file sizes.
(Bundled files are sent raw; files > 1 MB still go individually and compressed.)