-
v1.1.0 Stable
released this
2026-06-30 19:46:23 +00:00 | 0 commits to main since this releaseAdded
Documentation
- Standalone troff manpage —
man/goget.1is now the single source
of truth for the goget(1) manual. The previous embedded manpage listed
only ~30 of the 138 CLI flags and was missing every standard section;
the new file documents every flag with a dedicated entry, the
full set of conventional.SHsections (NAME, SYNOPSIS, DESCRIPTION,
OPTIONS, EXAMPLES, EXIT STATUS, FILES, ENVIRONMENT, SEE ALSO, HISTORY,
AUTHORS, REPORTING BUGS, COPYRIGHT), curl/wget compatibility notes, and
a release-history entry. The manpage is embedded into the binary via
//go:embed, so--generate-man-pageandman gogetnow agree. just man— new task that runsgroff -man -ww -Kutf-8 -zover
man/goget.1to validate the troff source. Skips cleanly whengroff
is not installed (CI on minimal images still passes).just install-manandjust uninstall-man— install the
manpage to$HOME/.local/share/man/man1/goget.1.gz(XDG rootless,
gzipped, reinstall-safe). Afterjust install-man,man goget
resolves the page automatically via the user'sMANPATH.
Core engine
- Unified worker pool — single protocol-agnostic worker pool (
internal/pool)
used by FTP, SFTP, and WebDAV recursive-parallel downloads. Replaces three
near-identical semaphore+WaitGroup implementations with a shared, tested
concurrency primitive. - Graceful shutdown on SIGINT — persist
.goget.metasidecar on interrupt
for SFTP single-file downloads, ensuring progress is saved for resume. - Gemini resume & metadata — Gemini downloads now persist
.goget.meta
sidecar on interrupt and delete it on successful completion.--resume
continues interrupted Gemini transfers from the saved byte offset. - Gopher resume & metadata — Gopher
typeHTMLandtypeTextFile
responses now persist.goget.metasidecar on interrupt and delete it on
successful completion.--resumecontinues interrupted Gopher text
transfers, skipping already-written output bytes (post-transform length
because Gopher line metadata is stripped before writing).
Security
- Certificate pinning across all TLS protocols —
--pinned-certnow
applies to FTPS, Gemini, and WebDAVS in addition to HTTP/HTTPS. The leaf
certificate SHA-256 hash is verified viatls.Config.VerifyPeerCertificate
on every TLS-bearing protocol. - SSH host-key pinning for SFTP — new
--pinned-host-keyflag pins the
SSH host key by its OpenSSH fingerprint (SHA256:<base64>, as produced by
ssh-keygen -lf). Raw lowercase-hex SHA-256 of the key wire format is also
accepted. Pinning takes precedence over--ssh-insecureandknown_hosts. - WebDAV TLS config fix —
webdav.Protocol.getHTTPTransportnow builds
itstls.Configfrom the caller-providedtransport.TLSConfiginstead of
a fresh config that silently dropped CA certs, mTLS, keylog, and pinned-cert
settings.
Recursive downloading & mirroring
--adjust-extensionextended to non-HTTP protocols — applies.html
extension totext/htmlfiles downloaded via Gopher and WebDAV.--backup-converted— keep.origbackups of files before link conversion
during recursive mirroring. Previously only available for HTTP/HTTPS;
now works for WebDAV mirrors too.
Download management
--show-metadata— displays.goget.metasidecar contents for debugging
interrupted / resumed downloads. Accepts a path to the downloaded output
(the sidecar is located next to it) or a direct path to the sidecar file.
Renders a human-readable summary by default and switches to raw JSON
output when combined with--json. Credentials embedded in the stored
URL are masked before display (the password placeholder isxxxxx).
Fixed
-
Gopher:
ctx.Done()cancellation goroutine leak — the goroutine
spawned inDownloadto close the socket onctx.Done()previously
waited indefinitely on the parent context, leaking every time the
context outlived the function. Now bounded by adefer-closed
donechannel so the goroutine exits on every return path. -
Gemini:
ctx.Done()cancellation goroutine leak — same bug,
same fix indownloadWithRedirects. -
Gopher: partial state lost on cancel-then-close — when the server
closed the connection afterctxwas cancelled,downloadText
treated the resulting EOF as a successful end-of-stream and never
persisted.goget.meta. Mirrors the equivalent Gemini behavior
(already present from the Gemini resume feature): ifctx.Err() != nil,
save partial state and return the context error. -
Gopher:
--resumeignored when caller suppliesWriter— when
--resumewas set together with a caller-suppliedWriter, the
partial-state sidecar would track bytes that landed in theWriter
rather thanOutput.--resumeis now silently disabled in that
case (with a--verbosewarning), keeping metadata consistent with
the actual on-disk state. -
Gemini:
--resumeignored when caller suppliesWriter— same
fix applied todownloadWithRedirects.
Testing
cmd/goget/man_page_test.go— new test file. Asserts the embedded
manpage is non-empty, carries a.TH GOGET 1header, contains every
mandatory.SHsection, and documents every flag registered by
defineFlags(so adding a new flag without documenting it now breaks
the build). Whengroffis installed, also runsgroff -man -ww -Kutf-8 -zover the embedded source and fails on any warning.- Resume tests deterministic across the protocol stack
(TestGeminiResume{SaveMetadata,Download}and
TestGopherResume{SaveMetadata,Download}) — the four tests previously
relied on a fixedtime.Sleepbefore callingcancel(), making them
flaky on slow CI schedulers. They now wait for aProgressCallback
signal, which fires synchronously after the firstwriter.Write
lands on disk. - Goroutine leak regression suite
(TestGeminiCancelGoroutineExits,TestGopherCancelGoroutineExits)
— runs 50 downloads back-to-back, settles the runtime via
runtime.GC(), and assertsruntime.NumGoroutine()returns to
baseline + 1 within a 2-second window. TestGopherResumeInformation— new regression test covering the
typeInformationtext-mode path through resume, which differs from
typeHTML/typeTextFilebecause lines are passed through verbatim
(no metadata strip).TestGopherResumeStaleMetadatanow asserts that an orphan
.goget.metacarried over from a different URL is deleted once a
successful fresh download completes, preventing it from being
picked up by a future--resumerun.
Downloads
- Standalone troff manpage —