Skip to content

Releases: lotgon/folder-transfer

folder-transfer v0.16.0

Choose a tag to compare

@lotgon lotgon released this 29 Jun 18:17

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.zipft.exe + ft.dll (+ ft.dll.lib), the C header
    ft.h, and a .NET binding FolderTransfer.cs, plus server.example.json.
  • ft-0.16.0-x86_64-linux.tar.gzft (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

Choose a tag to compare

@lotgon lotgon released this 29 Jun 16:42

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 — Rust ft.exe for Windows (+ server.example.json).
  • ft-0.15.3-x86_64-linux.tar.gz — Rust ft for 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 PING keepalives while it waits for its file-walker, so the timeout never fires
    on a slow scan (the client ignores PING).
  • 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

Choose a tag to compare

@lotgon lotgon released this 29 Jun 16:24

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 — Rust ft.exe for Windows (+ server.example.json).
  • ft-0.15.2-x86_64-linux.tar.gz — Rust ft for Linux, static musl (+ server.example.json).

Highlights

  • No subcommand neededft <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-ip enforced.

See CHANGELOG.md. Cross-OS (Windows↔Ubuntu) verified byte-for-byte.

folder-transfer v0.15.1

Choose a tag to compare

@lotgon lotgon released this 29 Jun 13:04

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 — Rust ft.exe for Windows (+ server.example.json).
  • ft-0.15.1-x86_64-linux.tar.gz — Rust ft for Linux, static musl (+ server.example.json).

What's new

  • No subcommand needed — point ft at a folder or a JSON, PowerShell-style. The first
    argument is auto-routed:

    • ft server.example.json or ft C:\dataserve
    • ft ft-download-Name.json D:\incomingreceive (2nd arg = destination)

    ft serve / ft get still work if you want to be explicit; extra flags (--port, --once, …)
    still override the JSON.

  • server.example.json included in the Rust archives — a ready, fully-commented server config
    (same keys as the PowerShell ft-server.ps1). It runs out of the box:
    ft server.example.json (edit the folders list to taste).

See CHANGELOG.md.

folder-transfer v0.15.0

Choose a tag to compare

@lotgon lotgon released this 29 Jun 11:10

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 — Rust ft.exe for Windows.
  • ft-0.15.0-x86_64-linux.tar.gz — Rust ft for 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) and ft 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

Choose a tag to compare

@lotgon lotgon released this 28 Jun 16:58

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 — -NoCompress still forces it
    off. The wire format is unchanged (the receiver already decodes mixed raw/compressed blocks).
  • Benchmark suite (bench/). bench\bench.ps1 builds corpora, drives real transfers through a
    bandwidth/latency‑emulating proxy (bench\bench-proxy.ps1), and writes BENCHMARKS.md; method
    and reproduction steps in bench/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 -ToFolder resolved 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

Choose a tag to compare

@lotgon lotgon released this 28 Jun 00:06

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 separate folders entries 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_Subtraction error that could abort sends (and write 0‑byte files) under the new unit model.

folder-transfer v0.12.0

Choose a tag to compare

@lotgon lotgon released this 27 Jun 22:49

Added

  • Parallel streams (-Streams <n>, default 4). Transfers now use several TCP connections at
    once, which lifts the single‑connection window ÷ RTT throughput 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; -Cutover forces 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 separate folders entries 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 1 to 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

Choose a tag to compare

@lotgon lotgon released this 27 Jun 15:55

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

Choose a tag to compare

@lotgon lotgon released this 27 Jun 15:46

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.)