GH-8800: Fix SMB Gateway for recursive MGET

Fixes: gh-8800

The `SmbFile.getName()` returns plain file name, not with a
sub-directory as it is expected by the `AbstractRemoteFileOutboundGateway`
for (S)FTP protocols

* Introduce `AbstractRemoteFileOutboundGateway.getFullFileName()`
with dir and file name concatenation by default (as it was before)
and override it in the `SmbOutboundGateway` to return the full path according this protocol.
* Fix `SmbOutboundGateway.enhanceNameWithSubDirectory()` to return an `SmbFile` instance
since it has all the info about remote file, include requested directory
* Fix `SmbOutboundGateway.getFilename()` to remove the trailing `/` in the dir name
since this is not what expected by the `AbstractRemoteFileOutboundGateway` logic

**Cherry-pick to `6.1.x`**
This commit is contained in:
Artem Bilan
2023-12-06 10:17:11 -05:00
committed by Christian Tzolov
parent 45a32cf13c
commit 0531832a0e
3 changed files with 37 additions and 28 deletions

View File

@@ -1036,6 +1036,10 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
return;
}
String fileName = getFilename(fileToAdd);
// Some remote file protocols don't include sub-dir into file name.
if (StringUtils.hasText(subDirectory) && !fileName.startsWith(subDirectory)) {
fileName = subDirectory + fileName;
}
final boolean isDirectory = isDirectory(file);
boolean isDots = hasDots(fileName);
if ((this.options.contains(Option.SUBDIRS) || !isDirectory)
@@ -1276,10 +1280,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
private File getRemoteFileForMget(Message<?> message, Session<F> session, String remoteDirectory,
AbstractFileInfo<F> lsEntry) throws IOException {
String fullFileName =
remoteDirectory != null
? remoteDirectory + getFilename(lsEntry)
: getFilename(lsEntry);
String fullFileName = getFullFileName(remoteDirectory, lsEntry.getFileInfo());
/*
* With recursion, the filename might contain subdirectory information
* normalize each file separately.
@@ -1289,6 +1290,20 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
return get(message, session, actualRemoteDirectory, fullFileName, fileName, lsEntry.getFileInfo());
}
/**
* By default, this method contacts the remote directory with the remote file name
* to build a full remote file path.
* The remote file protocol-specific implementation may override this method for other approach.
* @param remoteDirectory the directory remote file belongs.
* @param remoteFile the remote file to take a name and adjust its path according provided remote directory.
* @return the full path for the remote file
*/
protected String getFullFileName(String remoteDirectory, F remoteFile) {
return remoteDirectory != null
? remoteDirectory + getFilename(remoteFile)
: getFilename(remoteFile);
}
private String getRemoteDirectory(String remoteFilePath, String remoteFilename) {
String remoteDir = remoteFilePath.substring(0, remoteFilePath.lastIndexOf(remoteFilename));
if (remoteDir.length() == 0) {