Remote file access (3/4): downloadFile(remote, local) — the symmetric, digest-verified counterpart of uploadFile
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- java
- Área
- api, backend, networking
Línea de trabajo
Empieza leyendo WinRMClient.uploadFile y la lectura por rangos/streaming del issue #146; después inspecciona ShellFileCopy.digestHex, parseAnyDigest, CERTUTIL_ALGORITHMS y las constantes de reintento por cuota. Usa las pruebas de FakeWsmanServer para cubrir round trips, discrepancias de digest, interrupciones y destinos idénticos, y añade la comprobación en vivo en WinRMLiveTest. Se considera terminado cuando mvn verify site pasa, file-transfers.md y el README documentan las garantías y la recomendación de SMB, y no queda ningún archivo de destino parcial.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Third issue of the remote file access family: the missing symmetric half of
WinRMClient.uploadFile(Path, String). Builds on the ranged/streaming read of #146.
Context
client.uploadFile(Path localFile, String remoteFile) has existed since the smbj removal (#117): it pushes a local file through the WinRM channel itself, digest-verified, skipping the transfer when the destination already has identical content. There is no way back. Every caller that needs to retrieve a remote log or a command's output file has to shell out to type/Get-Content and hope the encoding survives.
downloadFile is the mirror image, and it should mirror the upload's guarantees, not just its direction: verified integrity, no wasted transfer, and no half-written local file left behind on failure.
Proposed API
Symmetric with the existing method, on the client:
client.downloadFile("C:\\Windows\\Temp\\collect.log", Path.of("collect.log"));
And as a terminal on the per-path request, for the fluent form:
long bytes = client.file("C:\\Windows\\Temp\\collect.log")
.downloadTo(Path.of("collect.log"));
Requirements
- Digest verification, both ways. Compute the remote digest with the probe
ShellFileCopyalready has (certutil -hashfile, SHA256 with a SHA1 fallback — seeCERTUTIL_ALGORITHMS), compare it with the digest of the received bytes, and fail with the same shape ofWindowsRemoteExceptionthe upload path raises on a mismatch. ReuseShellFileCopy.digestHex/parseAnyDigestrather than reimplementing. - Skip an identical transfer, matching the upload's behavior: if the local destination already exists with the same digest, do not transfer, and say so (return value or documented no-op).
- Atomic destination: stream into a temporary file in the destination's directory,
fsync, thenATOMIC_MOVEonto the target. A failure or a timeout must never leave a truncated file at the destination path. - Bounded memory: built on the streaming read, never
readBytes()into abyte[]first. A 500 MB file must download in constant memory (slowly — see below). - Downloads are not resumable — decided, and deliberately out of scope: an interrupted download starts over. Resuming would mean tracking verified byte counts across attempts and re-validating that the remote file has not changed, which is more state machine than this transport's speed justifies. Say so in the Javadoc and in
file-transfers.mdso callers do not expect otherwise. - Reuse the quota-rejection retry (
isRetryableQuotaRejection,QUOTA_RETRIES,QUOTA_RETRY_DELAY_MILLIS): a long download hits the same WinRM operation quotas the upload does. - Directory destination:
downloadFile(remote, Path.of("C:\\dir"))where the local path is an existing directory should writedir\<remote file name>— or reject it. Pick one, document it. - Honest performance documentation. Base64 through a command shell is roughly an order of magnitude slower than SMB; publish a measured figure from the live host in
file-transfers.mdand keep the existing "not a bulk transport" caveat prominent. Callers moving gigabytes should use SMB, and the docs should say so. - Timeout is the client's wall-clock deadline for the blocking method; a large download will need an explicitly raised timeout, and the exception message must make the cause obvious (bytes transferred / total when it fired).
Tests & docs
- Round-trip test:
uploadFilethendownloadFilereturns byte-identical content, for a binary file with every byte value and for a file with a non-ASCII name. FakeWsmanServertests: digest mismatch → failure with no file at the destination; interruption mid-transfer → no partial file left behind and no half-written temporary file; identical-digest destination → no transfer performed.WinRMLiveTest: download a real file fromanaxagoreand verify its digest.file-transfers.mdextended with the download direction, the integrity and atomicity guarantees, the measured throughput, and the SMB recommendation for bulk data; README snippet next touploadFile.
Acceptance criteria
downloadFileretrieves byte-exact content, digest-verified against the remote host.- No partial file is ever visible at the destination path — verified by a test that interrupts mid-transfer.
- An identical local file is not re-downloaded.
- A file substantially larger than the JVM heap downloads successfully.
mvn verify sitegreen: no checkstyle/PMD/SpotBugs findings, full Javadoc, docs updated.
🤖 Generated with Claude Code
- Lenguaje dominante
- Java
- Estrellas
- 11
- Forks
- 4
- Merge medio
- 5 d 5 h
- PR fusionados (30 d)
- 6
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de MetricsHub/winrm-java
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
MetricsHub/winrm-java#148 ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 38/100
MetricsHub/winrm-java#146 ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
MetricsHub/winrm-java#145 ·
-
Kerberos credential delegation: allowDelegation() and CLI --allow-delegate (winrs -allowdelegate) Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
MetricsHub/winrm-java#141 ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 68/100
MetricsHub/winrm-java#139 ·
Todos los issues de MetricsHub/winrm-java
Issues similares
-
bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
apache/cloudstack#14222 ·
-
[BUG]茶杯方块在取茶时会引发崩溃 Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
Cannot differ own consent and managed consents in My Consents view and detailed consent view. Abierto1.0.0-alpha2 Type/Improvement
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
wso2/dpdp-accelerator#272 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
infinispan/infinispan#18150 ·
-
area/frontend
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100