GH-9123: SFTP: Use canonicalPath for read operation

Fixes: #9123

The `/` at the beginning of the remote dir path is not necessary when listing files, although it is necessary to download them
The `SftpTemplate.get()` should work also with `remote-dir/MyFile.csv` as input.

* Fix `SftpSession.readRaw()` to call `sftpClient.canonicalPath(source)` if the path does not start with a `/`.
Something similar what is does
* Delegate to `SftpSession.readRaw()` from the `SftpSession.read()`
* Reuse `normalizePath()` for `doList()`

**Auto-cherry-pick to `6.2.x` & `6.1.x`**
This commit is contained in:
Artem Bilan
2024-05-07 13:46:27 -04:00
parent 243141e19a
commit a2215afdf7
2 changed files with 14 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,23 +107,24 @@ public class SftpSession implements Session<SftpClient.DirEntry> {
remoteDir = remotePath;
}
}
remoteDir =
!remoteDir.isEmpty() && remoteDir.charAt(0) == '/'
? remoteDir
: this.sftpClient.canonicalPath(remoteDir);
remoteDir = normalizePath(remoteDir);
return StreamSupport.stream(this.sftpClient.readDir(remoteDir).spliterator(), false)
.filter((entry) -> !isPattern || PatternMatchUtils.simpleMatch(remoteFile, entry.getFilename()));
}
@Override
public void read(String source, OutputStream os) throws IOException {
InputStream is = this.sftpClient.read(source);
InputStream is = readRaw(source);
FileCopyUtils.copy(is, os);
}
@Override
public InputStream readRaw(String source) throws IOException {
return this.sftpClient.read(source);
return this.sftpClient.read(normalizePath(source));
}
private String normalizePath(String path) throws IOException {
return !path.isEmpty() && path.charAt(0) == '/' ? path : this.sftpClient.canonicalPath(path);
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -193,8 +193,11 @@ public class SftpInboundRemoteFileSystemSynchronizerTests {
String[] files = new File("remote-test-dir").list();
for (String fileName : files) {
when(sftpClient.read("remote-test-dir/" + fileName))
.thenReturn(new FileInputStream("remote-test-dir/" + fileName));
String remoteFilePath = "remote-test-dir/" + fileName;
when(sftpClient.canonicalPath(remoteFilePath))
.thenReturn("/" + remoteFilePath);
when(sftpClient.read("/" + remoteFilePath))
.thenReturn(new FileInputStream(remoteFilePath));
}
when(sftpClient.readDir("/remote-test-dir")).thenReturn(this.sftpEntries);