Skip to content

Tags: VirusAlex/NetCopy

Tags

v1.0.0

Toggle v1.0.0's commit message
v1.0.0 — first production release

NetCopy is a multi-stream file-transfer tool for two trusted hosts on a
LAN. Key properties:

  - Pull-only data flow with mutual peers; one auth token shared per pair.
  - HTTP/Range or custom TCP data plane, picked per transfer; both stream
    via FileChannel.transferTo / sendfile-class zero-copy.
  - Per-chunk XXH3-128 verification on the wire; full-file SHA-256 finalize.
  - Resumable transfers (sidecars per file + JSON job state); chunks
    already verified on disk are skipped on resume.
  - No-delete invariant enforced statically by ArchUnit; the only paths
    that touch destructive APIs (Files.move, RandomAccessFile.setLength,
    FileChannel.truncate, REPLACE_EXISTING) are an audited 4-class
    whitelist.

What 1.0 commits to:

  - REST JSON wire formats and TCP frame layout are stable; breaking
    them needs a major bump. Persisted state files (jobs/*.json,
    <file>.netcopy/meta.json) carry schemaVersion=1 as the
    forward-compat backstop.
  - CLI flags (see README) are stable.
  - Security model: NOFOLLOW_LINKS on every data-plane open, the
    backend acknowledgeOverwrite gate, the constant-time TokenGate,
    and POSIX 0600 perms on state files.

Path from 0.x:

  - 0.1: initial skeleton
  - 0.2: Docker image, multi-host, Pause/Resume, conflict policies
  - 0.3: TCP wire-protocol v2 (single-pass hash + DataEndV2),
    selection stats, performance metrics in UI, batched bitmap fsync,
    cross-panel match highlighting
  - 0.4: comprehensive release-readiness audit (closed every BLOCKER,
    HIGH, MEDIUM finding); LICENSE + pom metadata, schemaVersion,
    multi-arch image, HEALTHCHECK, SHA-pinned bases, gosu binary
    verification, symlink-traversal hardening, registry cleanup task,
    TCP HELLO timeout + connection cap, WS subscription cap, body
    size cap, classified Connect errors, sort + filter UI, version
    chips
  - 0.4.x patches: TCP pool sizing fix, logback XML comment hotfix,
    UI version display

Known constraints (documented in README, intentional for 1.0):

  - LAN-only assumption; no TLS by design.
  - Windows + Java NIO Selector loopback quirk (use real LAN address).
  - Sidecar leftovers after cancel (no-delete invariant; clean up
    manually if desired).
  - source_changed fail-safe instead of silent garbage on
    edited-mid-transfer files.

See CHANGELOG.md for the full per-release history.

v0.4.2

Toggle v0.4.2's commit message
v0.4.2 — hotfix: logback.xml SAXParseException at startup

PR #65 (post-audit cleanup) added a comment to logback.xml that included
the literal token 'kubectl logs --previous'. XML forbids '--' inside
comments — every JVM startup since v0.4.0 hit:

  ch.qos.logback.core.joran.spi.JoranException:
    Problem parsing XML document
  Caused by: org.xml.sax.SAXParseException; line 9 col 46;
    The string "--" is not permitted within comments

The runtime kept going (Logback fell back to its default appender) but
the configured pattern + the date-in-timestamp from v0.4.0 were silently
ignored.

This release replaces the verbose comment with a tight one-liner that
doesn't reference command-line flags. No other changes from v0.4.1.

v0.4.1

Toggle v0.4.1's commit message
v0.4.1 — pool fix, sort + filter, connect UX

Performance
- TCP connection pool sized for global chunk-worker count (chunksPerFile ×
  fileParallelism). Pre-v0.4.1 pool was just chunksPerFile, so the default
  4×8=32 chunk workers contended for 8 sockets → ~280 ms acquire wait.
  Now 1:1 ratio.

UX
- Clickable sort columns in both panels (Name / Size / Modified, asc/desc
  with ▲/▼ indicator). 'Dirs first' grouping preserved.
- Per-panel substring filter row (debounced, Esc / × clears, resets on
  navigation; sort prefs persist).
- Symmetric Connect button on the local-token side (was: peer had a
  button, local needed Enter).
- 4-state connection status (idle/connecting/ok/error) + classified error
  text (401 — invalid token, 404 — endpoint not found …, unreachable
  hint for fetch rejects). Pre-v0.4.1 connect failures were silently
  swallowed.

v0.4.0

Toggle v0.4.0's commit message
v0.4.0 — audit fixes (security, license, schemaVersion, multi-arch im…

…age, docs)

Closes the v1.0.0 readiness audit's BLOCKER, HIGH, and MEDIUM tier:

- ArchUnit no-delete invariant restored (was a silent no-op on JDK 25 in v0.3.x)
- LICENSE (Apache-2.0), NOTICE, pom <licenses>/<scm>/<url>/<developers>
- Symlink-traversal hardening (NOFOLLOW_LINKS everywhere on the data plane,
  manifest/register validates real-path containment)
- Backend acknowledgeOverwrite gate
- Token-in-URL scope reduced to /ws/* only
- ManifestRegistry actually evicts now (cleanup task wired in App.boot)
- TCP HELLO timeout, connection cap, WS subscription cap, body size cap
- POSIX 0600 perms on state files
- JobState + SidecarMeta gain schemaVersion (read-side reject of unknown major)
- Multi-arch image (linux/amd64,linux/arm64), HEALTHCHECK, SHA-pinned bases,
  gosu binary verification, :latest only for non-0.x
- README endpoint table, hash claims (XXH3-128 chunk / SHA-256 finalize),
  data-formats.md proto v2 + lowercase enums, protocol-comparison.md cleanup
- .dockerignore unignores staged jar so the release workflow actually publishes (re-tag fix)

See CHANGELOG.md for the full list.

main-snapshot

Toggle main-snapshot's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
docs(readme): add status badges (#72)

Five small badges right under the H1, in the order people read them:

  - CI status (green = main is healthy)
  - Latest released version (semver-sorted, colour=blue)
  - Container link to GHCR (clarifies where to pull from at a glance)
  - License (Apache-2.0 from the LICENSE file)
  - Java 25 (the build/runtime requirement)

All badges are static-image services hosted by GitHub or shields.io —
no extra moving parts in the project itself. Each badge links to the
relevant page so the reader can act on the signal.

Co-authored-by: VirusAlex <[email protected]>
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>

v0.3.3

Toggle v0.3.3's commit message
v0.3.3 — UX polish + Performance metrics fix

UX:
- Cross-panel match highlight extended to folders (weak yellow on
  same-name match; recursive size/mtime stays out of scope to avoid
  fs-walk thrash on every browse).

Docs:
- README cleanup: dropped Debian-specific framing (NetCopy works on any
  Linux, macOS, Windows with caveats), removed maintainer-only Releasing
  section, condensed Contributing.

Fix:
- Performance modal's 'This transfer (chunks)' tile now actually shows
  per-chunk metrics (sourceLatency, wireTime, persistTime, pool acquire
  wait, succeeded/retried/failed/inFlight). Backend was producing them
  all along; UI was never reading them onto t.metrics.

v0.3.2

Toggle v0.3.2's commit message
v0.3.2 — cross-panel match highlight

Subtle row tint when a file in one panel has a counterpart in the OTHER panel:
- green:  same name + size + mtime  (would skip on Copy)
- yellow: same name + size, ≠ mtime (worth a hash check)
- none:   different size or no match

v0.3.1

Toggle v0.3.1's commit message
v0.3.1

UX:
- Selection stats (recursive file count + bytes) in panel footer
- Receive-root free space in panel footer
- Pre-flight free-space check in Copy modal
- Per-file progress bars in detail dialog (download blue, verify gold)

Perf:
- Batched bitmap fsync: 8 chunks or 500 ms between force() triples
  (partial -> hashes -> bitmap), removes the periodic 0 B/s drops on HDD

v0.3.0

Toggle v0.3.0's commit message
v0.3.0: TCP proto v2 — single-pass hash on source (~2x HDD throughput)

v0.2.7

Toggle v0.2.7's commit message
v0.2.7: PUID/PGID entrypoint — Docker UX no longer requires --user / …

…pre-created dirs