This is an automated email from the ASF dual-hosted git repository. twolf pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
The following commit(s) were added to refs/heads/master by this push: new 6a8e2ee [SSHD-1182] Fix SftpInputStreamAsync.skip() 6a8e2ee is described below commit 6a8e2eec37295367a34b6914c3de431b2520b075 Author: Pavel Stetsuk <pstet...@exadel.com> AuthorDate: Tue Jun 15 09:35:35 2021 +0300 [SSHD-1182] Fix SftpInputStreamAsync.skip() On an initial skip before the first read() both clientOffset and requestOffset need to be set. --- .../sftp/client/impl/SftpInputStreamAsync.java | 2 ++ .../java/org/apache/sshd/sftp/client/SftpTest.java | 30 ++++++++++++++++ .../client/impl/SftpRemotePathChannelTest.java | 41 ++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/impl/SftpInputStreamAsync.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/impl/SftpInputStreamAsync.java index 6721c74..71d8251 100644 --- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/impl/SftpInputStreamAsync.java +++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/impl/SftpInputStreamAsync.java @@ -79,6 +79,7 @@ public class SftpInputStreamAsync extends InputStreamWithChannel implements Sftp this.path = path; this.handle = handle; this.bufferSize = bufferSize; + this.requestOffset = clientOffset; this.clientOffset = clientOffset; this.fileSize = fileSize; } @@ -207,6 +208,7 @@ public class SftpInputStreamAsync extends InputStreamWithChannel implements Sftp if (log.isDebugEnabled()) { log.debug("skip({}) virtual skip of {} bytes", this, n); } + requestOffset = n; clientOffset = n; return n; } diff --git a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpTest.java b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpTest.java index ed67b0c..eb8ca4e 100644 --- a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpTest.java +++ b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpTest.java @@ -564,6 +564,36 @@ public class SftpTest extends AbstractSftpClientTestSupport { } } + @Test // see SSHD-1182 + public void testInputStreamSkipBeforeRead() throws Exception { + Path targetPath = detectTargetFolder(); + Path parentPath = targetPath.getParent(); + Path localFile = CommonTestSupportUtils.resolve( + targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName()); + Files.createDirectories(localFile.getParent()); + byte[] data + = (getClass().getName() + "#" + getCurrentTestName() + "[" + localFile + "]").getBytes(StandardCharsets.UTF_8); + Files.write(localFile, data, StandardOpenOption.CREATE); + try (SftpClient sftp = createSingleSessionClient(); + InputStream stream = sftp.read( + CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, localFile), OpenMode.Read)) { + int toSkip = data.length / 4; + int readLen = data.length / 2; + byte[] expected = new byte[readLen]; + byte[] actual = new byte[readLen]; + + System.arraycopy(data, toSkip, expected, 0, readLen); + + long skipped = stream.skip(toSkip); + assertEquals("Mismatched skipped forward size", toSkip, skipped); + + int actuallyRead = IoUtils.read(stream, actual); + assertEquals("Failed to read fully skipped forward data", readLen, actuallyRead); + + assertArrayEquals("Unexpected data read after skipping", expected, actual); + } + } + @Test public void testSftpFileSystemAccessor() throws Exception { List<? extends SubsystemFactory> factories = sshd.getSubsystemFactories(); diff --git a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/impl/SftpRemotePathChannelTest.java b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/impl/SftpRemotePathChannelTest.java index a69e3db..bdabd91 100644 --- a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/impl/SftpRemotePathChannelTest.java +++ b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/impl/SftpRemotePathChannelTest.java @@ -139,6 +139,47 @@ public class SftpRemotePathChannelTest extends AbstractSftpClientTestSupport { assertArrayEquals("Mismatched transferred data", expected, actual); } + @Test // see SSHD-1182 + public void testTransferToFileChannelWithOffset() throws IOException { + Path targetPath = detectTargetFolder(); + Path lclSftp = CommonTestSupportUtils.resolve( + targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName()); + Path srcFile = assertHierarchyTargetFolderExists(lclSftp).resolve(getCurrentTestName() + "-src.txt"); + Path parentPath = targetPath.getParent(); + + Files.deleteIfExists(srcFile); + try (Writer output = Files.newBufferedWriter(srcFile, StandardCharsets.UTF_8)) { + String seed = getClass().getName() + "#" + getCurrentTestName() + "(" + new Date() + ")"; + for (long totalWritten = 0L; + totalWritten <= SftpModuleProperties.COPY_BUF_SIZE.getRequiredDefault(); + totalWritten += seed.length()) { + output.append(seed).append(System.lineSeparator()); + } + } + + byte[] data = Files.readAllBytes(srcFile); + int offset = data.length / 4; + byte[] expected = new byte[data.length - offset]; + System.arraycopy(data, offset, expected, 0, expected.length); + + Path dstFile = srcFile.getParent().resolve(getCurrentTestName() + "-dst.txt"); + Files.deleteIfExists(dstFile); + + String remFilePath = CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, srcFile); + try (SftpClient sftp = createSingleSessionClient(); + FileChannel srcChannel = sftp.openRemotePathChannel( + remFilePath, EnumSet.of(StandardOpenOption.READ)); + FileChannel dstChannel = FileChannel.open(dstFile, + StandardOpenOption.CREATE, StandardOpenOption.WRITE)) { + long numXfered = srcChannel.transferTo(offset, expected.length, dstChannel); + assertEquals("Mismatched reported transfer count", expected.length, numXfered); + } + + byte[] actual = Files.readAllBytes(dstFile); + assertEquals("Mismatched transferred size", expected.length, actual.length); + assertArrayEquals("Mismatched transferred data", expected, actual); + } + @Test(timeout = 10000) // see SSHD-970 public void testTransferToFileChannelLoopFile() throws IOException { Path targetPath = detectTargetFolder();