From 67ac3c2b93be2c3ead11b3c64f1bb48bdd9d7ae6 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Tue, 7 May 2024 14:23:17 -0400 Subject: [PATCH] GH-9114: SFTP: Use `canonicalPath` `exists` operation Fixes: #9114 If path is not in normalized presentation, the SFTP operation might fail like: ``` Caused by: SFTP error (SSH_FX_NO_SUCH_PATH): The file path does not exist or is invalid. at org.apache.sshd.sftp.client.impl.AbstractSftpClient.throwStatusException(AbstractSftpClient.java:277) at org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkAttributesResponse(AbstractSftpClient.java:333) at org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkAttributes(AbstractSftpClient.java:325) at org.apache.sshd.sftp.client.impl.AbstractSftpClient.lstat(AbstractSftpClient.java:1010) at org.springframework.integration.sftp.session.SftpSession.exists(SftpSession.java:191) ``` * Use it now like this `this.sftpClient.lstat(normalizePath(path))` (cherry picked from commit 8b88668fbeb842ec9003ebb1363981bd04948404) --- .../integration/sftp/session/SftpSession.java | 2 +- .../sftp/outbound/SftpOutboundTests.java | 16 ++++++++++++---- .../sftp/outbound/SftpServerOutboundTests.java | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java index a9c17d19d3..414cd2fa5d 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java @@ -189,7 +189,7 @@ public class SftpSession implements Session { @Override public boolean exists(String path) { try { - this.sftpClient.lstat(path); + this.sftpClient.lstat(normalizePath(path)); return true; } catch (SftpException ex) { diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java index 928df96cc0..695b90400a 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java @@ -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. @@ -260,17 +260,25 @@ public class SftpOutboundTests { public void testExists() throws IOException { SftpClient sftpClient = mock(SftpClient.class); + willReturn("/exist") + .given(sftpClient) + .canonicalPath("exist"); + + willReturn("/notExist") + .given(sftpClient) + .canonicalPath("notExist"); + willReturn(new SftpClient.Attributes()) .given(sftpClient) - .lstat(eq("exist")); + .lstat("/exist"); willThrow(new SftpException(SftpConstants.SSH_FX_NO_SUCH_FILE, "notExist")) .given(sftpClient) - .lstat(eq("notExist")); + .lstat("/notExist"); willThrow(new SshException(SshConstants.SSH_OPEN_CONNECT_FAILED, "Connection lost.")) .given(sftpClient) - .lstat(and(not(eq("exist")), not(eq("notExist")))); + .lstat(and(not(eq("/exist")), not(eq("/notExist")))); SftpSession sftpSession = new SftpSession(sftpClient); diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpServerOutboundTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpServerOutboundTests.java index 2af7fbb44e..4974abc275 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpServerOutboundTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpServerOutboundTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 the original author or authors. + * Copyright 2013-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. @@ -701,7 +701,7 @@ public class SftpServerOutboundTests extends SftpTestSupport { assertThatExceptionOfType(UncheckedIOException.class) .isThrownBy(() -> session.exists("any")) .withRootCauseInstanceOf(IOException.class) - .withStackTraceContaining("lstat(any) client is closed"); + .withStackTraceContaining("canonicalPath(any) client is closed"); } @SuppressWarnings("unused")