GH-9821: SFTP: Use STAT command to follow symlinks

Fixes: #9821
Issue link: https://github.com/spring-projects/spring-integration/issues/9821

Previously, Spring Integration used JSch library for SFTP protocol,
and that one was able to follow symlinks.
Currently, the `SftpSession` uses `LSTAT` command which does not follow symlinks

* Fix `SftpSession` to call `sftpClient.stat()` instead of `lstat()`
to mitigate migration pain from JSch

**Auto-cherry-pick to `6.4.x` & `6.3.x`**
This commit is contained in:
Artem Bilan
2025-02-12 13:28:41 -05:00
parent 478409e199
commit efa8dc50b7
3 changed files with 9 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@@ -101,7 +101,7 @@ public class SftpSession implements Session<SftpClient.DirEntry> {
boolean isPattern = remoteFile != null && remoteFile.contains("*");
if (!isPattern && remoteFile != null) {
SftpClient.Attributes attributes = this.sftpClient.lstat(path);
SftpClient.Attributes attributes = this.sftpClient.stat(path);
if (!attributes.isDirectory()) {
return Stream.of(new SftpClient.DirEntry(remoteFile, path, attributes));
}
@@ -201,7 +201,7 @@ public class SftpSession implements Session<SftpClient.DirEntry> {
@Override
public boolean exists(String path) {
try {
this.sftpClient.lstat(normalizePath(path));
this.sftpClient.stat(normalizePath(path));
return true;
}
catch (SftpException ex) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@@ -279,15 +279,15 @@ public class SftpOutboundTests {
willReturn(new SftpClient.Attributes())
.given(sftpClient)
.lstat("/exist");
.stat("/exist");
willThrow(new SftpException(SftpConstants.SSH_FX_NO_SUCH_FILE, "notExist"))
.given(sftpClient)
.lstat("/notExist");
.stat("/notExist");
willThrow(new SshException(SshConstants.SSH_OPEN_CONNECT_FAILED, "Connection lost."))
.given(sftpClient)
.lstat(and(not(eq("/exist")), not(eq("/notExist"))));
.stat(and(not(eq("/exist")), not(eq("/notExist"))));
SftpSession sftpSession = new SftpSession(sftpClient);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 the original author or authors.
* Copyright 2014-2025 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.
@@ -86,7 +86,7 @@ public class SftpRemoteFileTemplateTests extends SftpTestSupport {
assertThat(template.exists("foo/foobar.txt")).isTrue();
template.executeWithClient((ClientCallbackWithoutResult<SftpClient>) client -> {
try {
SftpClient.Attributes file = client.lstat("foo/foobar.txt");
SftpClient.Attributes file = client.stat("foo/foobar.txt");
assertThat(file.getSize()).isEqualTo(6);
}
catch (IOException e) {