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 <[email protected]>
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();