Tags: VirusAlex/NetCopy
Tags
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 — 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 — 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 — 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.
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 — 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 — 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 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
PreviousNext