This is an automated email from the ASF dual-hosted git repository.
lgoldstein 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 d567b95 [SSHD-967] Fixed extra bytes written at end of
SftpRemotePathChannel#transferTo
d567b95 is described below
commit d567b9549b52f00266fa2d8d6d32544f6c253afa
Author: Lyor Goldstein <[email protected]>
AuthorDate: Fri Feb 21 14:00:14 2020 +0200
[SSHD-967] Fixed extra bytes written at end of
SftpRemotePathChannel#transferTo
---
CHANGES.md | 2 +
.../subsystem/sftp/SftpRemotePathChannel.java | 283 +++++++++++++++------
.../subsystem/sftp/SftpRemotePathChannelTest.java | 183 +++++++++++++
.../sshd/client/subsystem/sftp/SftpTest.java | 150 ++++++-----
4 files changed, 464 insertions(+), 154 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index dd584ff..1a08198 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,3 +13,5 @@
## Behavioral changes and enhancements
* [SSHD-964](https://issues.apache.org/jira/browse/SSHD-964) - Send
SSH_MSG_CHANNEL_EOF when tunnel channel being closed.
+
+* [SSHD-967](https://issues.apache.org/jira/browse/SSHD-967) - Extra bytes
written when `SftpRemotePathChannel#transferTo` is used.
\ No newline at end of file
diff --git
a/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannel.java
b/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannel.java
index fc81e17..52e3149 100644
---
a/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannel.java
+++
b/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannel.java
@@ -20,6 +20,7 @@
package org.apache.sshd.client.subsystem.sftp;
import java.io.IOException;
+import java.io.StreamCorruptedException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.AsynchronousCloseException;
@@ -33,24 +34,29 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
-import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes;
import org.apache.sshd.common.subsystem.sftp.SftpConstants;
import org.apache.sshd.common.subsystem.sftp.SftpException;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
*/
public class SftpRemotePathChannel extends FileChannel {
+ /** Internal allocate buffer size when copying data to/from the channel */
public static final String COPY_BUFSIZE_PROP =
"sftp-channel-copy-buf-size";
+ /** Default value for {@value #COPY_BUFSIZE_PROP} setting */
public static final int DEFAULT_TRANSFER_BUFFER_SIZE =
IoUtils.DEFAULT_COPY_SIZE;
public static final Set<SftpClient.OpenMode> READ_MODES =
@@ -64,16 +70,21 @@ public class SftpRemotePathChannel extends FileChannel {
SftpClient.OpenMode.Create,
SftpClient.OpenMode.Truncate));
+ protected final Logger log;
+ protected final Collection<SftpClient.OpenMode> modes;
+ protected final boolean closeOnExit;
+ protected final SftpClient sftp;
+ protected final SftpClient.CloseableHandle handle;
+ protected final Object lock = new Object();
+ protected final AtomicLong posTracker = new AtomicLong(0L);
+ protected final AtomicReference<Thread> blockingThreadHolder = new
AtomicReference<>(null);
+
private final String path;
- private final Collection<SftpClient.OpenMode> modes;
- private final boolean closeOnExit;
- private final SftpClient sftp;
- private final SftpClient.CloseableHandle handle;
- private final Object lock = new Object();
- private final AtomicLong posTracker = new AtomicLong(0L);
- private final AtomicReference<Thread> blockingThreadHolder = new
AtomicReference<>(null);
-
- public SftpRemotePathChannel(String path, SftpClient sftp, boolean
closeOnExit, Collection<SftpClient.OpenMode> modes) throws IOException {
+
+ public SftpRemotePathChannel(
+ String path, SftpClient sftp, boolean closeOnExit,
Collection<SftpClient.OpenMode> modes)
+ throws IOException {
+ this.log = LoggerFactory.getLogger(getClass());
this.path = ValidateUtils.checkNotNullAndNotEmpty(path, "No remote
file path specified");
this.modes = Objects.requireNonNull(modes, "No channel modes
specified");
this.sftp = Objects.requireNonNull(sftp, "No SFTP client instance");
@@ -87,41 +98,69 @@ public class SftpRemotePathChannel extends FileChannel {
@Override
public int read(ByteBuffer dst) throws IOException {
- return (int) doRead(Collections.singletonList(dst), -1);
+ long totalRead = doRead(Collections.singletonList(dst), -1L);
+ if (totalRead >= Integer.MAX_VALUE) {
+ throw new StreamCorruptedException("Total read size exceeds
integer: " + totalRead);
+ }
+ return (int) totalRead;
}
@Override
public int read(ByteBuffer dst, long position) throws IOException {
- if (position < 0) {
- throw new IllegalArgumentException("read(" + getRemotePath() + ")
illegal position to read from: " + position);
+ if (position < 0L) {
+ throw new IllegalArgumentException("read(" + getRemotePath() + ")"
+ + " illegal position to read from: " + position);
}
- return (int) doRead(Collections.singletonList(dst), position);
+
+ long totalRead = doRead(Collections.singletonList(dst), position);
+ if (totalRead >= Integer.MAX_VALUE) {
+ throw new StreamCorruptedException("Total read size exceeds
integer: " + totalRead);
+ }
+ return (int) totalRead;
}
@Override
public long read(ByteBuffer[] dsts, int offset, int length) throws
IOException {
- List<ByteBuffer> buffers = Arrays.asList(dsts).subList(offset, offset
+ length);
- return doRead(buffers, -1);
+ Collection<ByteBuffer> buffers = Arrays.asList(dsts)
+ .subList(offset, offset + length);
+ return doRead(buffers, -1L);
}
- protected long doRead(List<ByteBuffer> buffers, long position) throws
IOException {
+ protected long doRead(Collection<? extends ByteBuffer> buffers, long
position) throws IOException {
ensureOpen(READ_MODES);
+
+ ClientSession clientSession = sftp.getClientSession();
+ int copySize = clientSession.getIntProperty(COPY_BUFSIZE_PROP,
DEFAULT_TRANSFER_BUFFER_SIZE);
+ boolean debugEnabled = log.isDebugEnabled();
+ if (debugEnabled) {
+ log.debug("doRead({})[position={}] fill {} buffers using
copySize={}",
+ this, position, buffers.size(), copySize);
+ }
+
+ boolean completed = false;
+ boolean eof = false;
+ long totalRead = 0;
+ int numBufsUsed = 0;
+
synchronized (lock) {
- boolean completed = false;
- boolean eof = false;
long curPos = (position >= 0L) ? position : posTracker.get();
try {
- long totalRead = 0;
- beginBlocking();
+ beginBlocking("doRead");
+
loop:
for (ByteBuffer buffer : buffers) {
+ numBufsUsed++;
+
while (buffer.remaining() > 0) {
ByteBuffer wrap = buffer;
if (!buffer.hasArray()) {
- wrap =
ByteBuffer.allocate(Math.min(IoUtils.DEFAULT_COPY_SIZE, buffer.remaining()));
+ wrap = ByteBuffer.allocate(Math.min(copySize,
buffer.remaining()));
}
- int read = sftp.read(handle, curPos, wrap.array(),
wrap.arrayOffset() + wrap.position(), wrap.remaining());
+
+ int read = sftp.read(handle, curPos, wrap.array(),
+ wrap.arrayOffset() + wrap.position(),
wrap.remaining());
if (read > 0) {
+ // reference equality on purpose
if (wrap == buffer) {
wrap.position(wrap.position() + read);
} else {
@@ -136,60 +175,97 @@ public class SftpRemotePathChannel extends FileChannel {
}
}
completed = true;
- if (totalRead > 0) {
- return totalRead;
- }
-
- if (eof) {
- return -1;
- } else {
- return 0;
- }
} finally {
if (position < 0L) {
posTracker.set(curPos);
}
- endBlocking(completed);
+ endBlocking("doRead", completed);
}
}
+
+ if (debugEnabled) {
+ log.debug("doRead({})[position={}] filled {}/{} with copySize={} -
totalRead={}, completed={}, eof={}",
+ this, position, numBufsUsed, buffers.size(), copySize,
totalRead, completed, eof);
+ }
+
+ if (totalRead > 0L) {
+ return totalRead;
+ }
+
+ if (eof) {
+ return -1L;
+ } else {
+ return 0L;
+ }
}
@Override
public int write(ByteBuffer src) throws IOException {
- return (int) doWrite(Collections.singletonList(src), -1);
+ long totalWritten = doWrite(Collections.singletonList(src), -1L);
+ if (totalWritten >= Integer.MAX_VALUE) {
+ throw new StreamCorruptedException("Total written size exceeds
integer: " + totalWritten);
+ }
+
+ return (int) totalWritten;
}
@Override
public int write(ByteBuffer src, long position) throws IOException {
if (position < 0L) {
- throw new IllegalArgumentException("write(" + getRemotePath() + ")
illegal position to write to: " + position);
+ throw new IllegalArgumentException("write(" + getRemotePath() + ")"
+ + " illegal position to write to: " + position);
}
- return (int) doWrite(Collections.singletonList(src), position);
+
+ long totalWritten = doWrite(Collections.singletonList(src), position);
+ if (totalWritten >= Integer.MAX_VALUE) {
+ throw new StreamCorruptedException("Total written size exceeds
integer: " + totalWritten);
+ }
+
+ return (int) totalWritten;
}
@Override
public long write(ByteBuffer[] srcs, int offset, int length) throws
IOException {
- List<ByteBuffer> buffers = Arrays.asList(srcs).subList(offset, offset
+ length);
- return doWrite(buffers, -1);
+ Collection<ByteBuffer> buffers = Arrays.asList(srcs)
+ .subList(offset, offset + length);
+ return doWrite(buffers, -1L);
}
- protected long doWrite(List<ByteBuffer> buffers, long position) throws
IOException {
+ protected long doWrite(Collection<? extends ByteBuffer> buffers, long
position) throws IOException {
ensureOpen(WRITE_MODES);
+
+ ClientSession clientSession = sftp.getClientSession();
+ int copySize = clientSession.getIntProperty(
+ COPY_BUFSIZE_PROP, DEFAULT_TRANSFER_BUFFER_SIZE);
+ boolean debugEnabled = log.isDebugEnabled();
+ if (debugEnabled) {
+ log.debug("doWrite({})[position={}] write {} buffers using
copySize={}",
+ this, position, buffers.size(), copySize);
+ }
+
+ boolean completed = false;
+ long totalWritten = 0L;
+ int numBufsUsed = 0;
+
synchronized (lock) {
- boolean completed = false;
long curPos = (position >= 0L) ? position : posTracker.get();
try {
- long totalWritten = 0L;
- beginBlocking();
+ beginBlocking("doWrite");
+
for (ByteBuffer buffer : buffers) {
+ numBufsUsed++;
+
while (buffer.remaining() > 0) {
ByteBuffer wrap = buffer;
if (!buffer.hasArray()) {
- wrap =
ByteBuffer.allocate(Math.min(IoUtils.DEFAULT_COPY_SIZE, buffer.remaining()));
+ wrap = ByteBuffer.allocate(Math.min(copySize,
buffer.remaining()));
buffer.get(wrap.array(), wrap.arrayOffset(),
wrap.remaining());
}
+
int written = wrap.remaining();
- sftp.write(handle, curPos, wrap.array(),
wrap.arrayOffset() + wrap.position(), written);
+ sftp.write(handle, curPos, wrap.array(),
+ wrap.arrayOffset() + wrap.position(), written);
+ // reference equality on purpose
if (wrap == buffer) {
wrap.position(wrap.position() + written);
}
@@ -198,14 +274,20 @@ public class SftpRemotePathChannel extends FileChannel {
}
}
completed = true;
- return totalWritten;
} finally {
if (position < 0L) {
posTracker.set(curPos);
}
- endBlocking(completed);
+ endBlocking("doWrite", completed);
}
}
+
+ if (debugEnabled) {
+ log.debug("doWrite({})[position={}] used {}/{} with copySize={} -
totalWritten={}, completed={}",
+ this, position, numBufsUsed, buffers.size(), copySize,
totalWritten, completed);
+ }
+
+ return totalWritten;
}
@Override
@@ -217,7 +299,8 @@ public class SftpRemotePathChannel extends FileChannel {
@Override
public FileChannel position(long newPosition) throws IOException {
if (newPosition < 0L) {
- throw new IllegalArgumentException("position(" + getRemotePath() +
") illegal file channel position: " + newPosition);
+ throw new IllegalArgumentException("position(" + getRemotePath() +
")"
+ + " illegal file channel position: " + newPosition);
}
ensureOpen(Collections.emptySet());
@@ -228,7 +311,8 @@ public class SftpRemotePathChannel extends FileChannel {
@Override
public long size() throws IOException {
ensureOpen(Collections.emptySet());
- return sftp.stat(handle).getSize();
+ Attributes stat = sftp.stat(handle);
+ return stat.getSize();
}
@Override
@@ -245,24 +329,37 @@ public class SftpRemotePathChannel extends FileChannel {
@Override
public long transferTo(long position, long count, WritableByteChannel
target) throws IOException {
- if ((position < 0) || (count < 0)) {
- throw new IllegalArgumentException("transferTo(" + getRemotePath()
+ ") illegal position (" + position + ") or count (" + count + ")");
+ if ((position < 0L) || (count < 0L)) {
+ throw new IllegalArgumentException("transferTo(" + getRemotePath()
+ ")"
+ + " illegal position (" + position + ") or count (" + count +
")");
}
ensureOpen(READ_MODES);
+
+ ClientSession clientSession = sftp.getClientSession();
+ int copySize = clientSession.getIntProperty(
+ COPY_BUFSIZE_PROP, DEFAULT_TRANSFER_BUFFER_SIZE);
+ boolean debugEnabled = log.isDebugEnabled();
+ if (debugEnabled) {
+ log.debug("transferTo({})[position={}, count={}] use copySize={}
for target={}",
+ this, position, count, copySize, target);
+ }
+
+ boolean completed = false;
+ boolean eof = false;
+ long curPos = position;
+ int bufSize = (int) Math.min(count, copySize);
+ byte[] buffer = new byte[bufSize];
+ long totalRead = 0L;
+
synchronized (lock) {
- boolean completed = false;
- boolean eof = false;
- long curPos = position;
try {
- beginBlocking();
+ beginBlocking("transferTo");
- int bufSize = (int) Math.min(count, Short.MAX_VALUE + 1);
- byte[] buffer = new byte[bufSize];
- long totalRead = 0L;
while (totalRead < count) {
- int read = sftp.read(handle, curPos, buffer, 0,
buffer.length);
+ int read = sftp.read(handle, curPos, buffer, 0,
+ (int) Math.min(count - totalRead, buffer.length));
if (read > 0) {
- ByteBuffer wrap = ByteBuffer.wrap(buffer);
+ ByteBuffer wrap = ByteBuffer.wrap(buffer, 0, read);
while (wrap.remaining() > 0) {
target.write(wrap);
}
@@ -273,21 +370,35 @@ public class SftpRemotePathChannel extends FileChannel {
}
}
completed = true;
- return totalRead > 0 ? totalRead : eof ? -1 : 0;
} finally {
- endBlocking(completed);
+ endBlocking("transferTo", completed);
}
}
+
+ if (debugEnabled) {
+ log.debug("transferTo({})[position={}, count={}] with copySize={}
- totalRead={}, eo{} for target={}",
+ this, position, count, copySize, totalRead, eof, target);
+ }
+
+ return totalRead > 0L ? totalRead : eof ? -1L : 0L;
}
@Override
public long transferFrom(ReadableByteChannel src, long position, long
count) throws IOException {
- if ((position < 0) || (count < 0)) {
- throw new IllegalArgumentException("transferFrom(" +
getRemotePath() + ") illegal position (" + position + ") or count (" + count +
")");
+ if ((position < 0L) || (count < 0L)) {
+ throw new IllegalArgumentException("transferFrom(" +
getRemotePath() + ")"
+ + " illegal position (" + position + ") or count (" + count +
")");
}
ensureOpen(WRITE_MODES);
- int copySize =
sftp.getClientSession().getIntProperty(COPY_BUFSIZE_PROP,
DEFAULT_TRANSFER_BUFFER_SIZE);
+ ClientSession clientSession = sftp.getClientSession();
+ int copySize = clientSession.getIntProperty(COPY_BUFSIZE_PROP,
DEFAULT_TRANSFER_BUFFER_SIZE);
+ boolean debugEnabled = log.isDebugEnabled();
+ if (debugEnabled) {
+ log.debug("transferFrom({})[position={}, count={}] use copySize={}
for source={}",
+ this, position, count, copySize, src);
+ }
+
boolean completed = false;
long curPos = (position >= 0L) ? position : posTracker.get();
long totalRead = 0L;
@@ -295,10 +406,11 @@ public class SftpRemotePathChannel extends FileChannel {
synchronized (lock) {
try {
- beginBlocking();
+ beginBlocking("transferFrom");
while (totalRead < count) {
- ByteBuffer wrap = ByteBuffer.wrap(buffer, 0, (int)
Math.min(buffer.length, count - totalRead));
+ ByteBuffer wrap = ByteBuffer.wrap(
+ buffer, 0, (int) Math.min(buffer.length, count -
totalRead));
int read = src.read(wrap);
if (read > 0) {
sftp.write(handle, curPos, buffer, 0, read);
@@ -309,16 +421,22 @@ public class SftpRemotePathChannel extends FileChannel {
}
}
completed = true;
- return totalRead;
} finally {
- endBlocking(completed);
+ endBlocking("transferFrom", completed);
}
}
+
+ if (debugEnabled) {
+ log.debug("transferFrom({})[position={}, count={}] use copySize={}
- totalRead={}, completed={} for source={}",
+ this, position, count, copySize, totalRead, completed, src);
+ }
+ return totalRead;
}
@Override
public MappedByteBuffer map(MapMode mode, long position, long size) throws
IOException {
- throw new UnsupportedOperationException("map(" + getRemotePath() +
")[" + mode + "," + position + "," + size + "] N/A");
+ throw new UnsupportedOperationException("map(" + getRemotePath() + ")"
+ + "[" + mode + "," + position + "," + size + "] N/A");
}
@Override
@@ -327,7 +445,7 @@ public class SftpRemotePathChannel extends FileChannel {
}
@Override
- public FileLock tryLock(final long position, final long size, boolean
shared) throws IOException {
+ public FileLock tryLock(long position, long size, boolean shared) throws
IOException {
ensureOpen(Collections.emptySet());
try {
@@ -347,7 +465,6 @@ public class SftpRemotePathChannel extends FileChannel {
return acquiredBy().isOpen() && valid.get();
}
- @SuppressWarnings("synthetic-access")
@Override
public void release() throws IOException {
if (valid.compareAndSet(true, false)) {
@@ -359,6 +476,10 @@ public class SftpRemotePathChannel extends FileChannel {
@Override
protected void implCloseChannel() throws IOException {
+ if (log.isDebugEnabled()) {
+ log.debug("implCloseChannel({}) closeOnExit={}", this,
closeOnExit);
+ }
+
try {
Thread thread = blockingThreadHolder.get();
if (thread != null) {
@@ -375,12 +496,21 @@ public class SftpRemotePathChannel extends FileChannel {
}
}
- private void beginBlocking() {
+ protected void beginBlocking(Object actionHint) {
+ if (log.isDebugEnabled()) {
+ log.debug("beginBlocking({})[{}]", this, actionHint);
+ }
+
begin();
blockingThreadHolder.set(Thread.currentThread());
}
- private void endBlocking(boolean completed) throws
AsynchronousCloseException {
+ protected void endBlocking(Object actionHint, boolean completed)
+ throws AsynchronousCloseException {
+ if (log.isDebugEnabled()) {
+ log.debug("endBlocking({})[{}] completed={}", this, actionHint,
completed);
+ }
+
blockingThreadHolder.set(null);
end(completed);
}
@@ -390,8 +520,7 @@ public class SftpRemotePathChannel extends FileChannel {
* at least one of the required ones
*
* @param reqModes The required modes - ignored if {@code null}/empty
- * @throws IOException If channel not open or the required modes are not
- * satisfied
+ * @throws IOException If channel not open or the required modes are not
satisfied
*/
private void ensureOpen(Collection<SftpClient.OpenMode> reqModes) throws
IOException {
if (!isOpen()) {
@@ -405,7 +534,9 @@ public class SftpRemotePathChannel extends FileChannel {
}
}
- throw new IOException("ensureOpen(" + getRemotePath() + ") current
channel modes (" + this.modes + ") do contain any of the required: " +
reqModes);
+ throw new IOException("ensureOpen(" + getRemotePath() + ")"
+ + " current channel modes (" + this.modes + ")"
+ + " do contain any of the required ones: " + reqModes);
}
}
diff --git
a/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannelTest.java
b/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannelTest.java
new file mode 100644
index 0000000..2a496a9
--- /dev/null
+++
b/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpRemotePathChannelTest.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.subsystem.sftp;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.util.test.CommonTestSupportUtils;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@SuppressWarnings("checkstyle:MethodCount")
+public class SftpRemotePathChannelTest extends AbstractSftpClientTestSupport {
+ public SftpRemotePathChannelTest() throws IOException {
+ super();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ setupServer();
+ }
+
+ @Test // see SSHD-697
+ public void testFileChannel() throws IOException {
+ Path targetPath = detectTargetFolder();
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName());
+ Path lclFile =
assertHierarchyTargetFolderExists(lclSftp).resolve(getCurrentTestName() +
".txt");
+ Files.deleteIfExists(lclFile);
+ byte[] expected = (getClass().getName() + "#" + getCurrentTestName() +
"(" + new Date() + ")").getBytes(StandardCharsets.UTF_8);
+
+ try (ClientSession session = client.connect(getCurrentTestName(),
TEST_LOCALHOST, port)
+ .verify(7L, TimeUnit.SECONDS)
+ .getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ try (SftpClient sftp = createSftpClient(session)) {
+ Path parentPath = targetPath.getParent();
+ String remFilePath =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, lclFile);
+
+ try (FileChannel fc = sftp.openRemotePathChannel(
+ remFilePath, EnumSet.of(
+ StandardOpenOption.CREATE,
StandardOpenOption.READ, StandardOpenOption.WRITE))) {
+ int writeLen = fc.write(ByteBuffer.wrap(expected));
+ assertEquals("Mismatched written length", expected.length,
writeLen);
+
+ FileChannel fcPos = fc.position(0L);
+ assertSame("Mismatched positioned file channel", fc,
fcPos);
+
+ byte[] actual = new byte[expected.length];
+ int readLen = fc.read(ByteBuffer.wrap(actual));
+ assertEquals("Mismatched read len", writeLen, readLen);
+ assertArrayEquals("Mismatched read data", expected,
actual);
+ }
+ }
+ }
+
+ byte[] actual = Files.readAllBytes(lclFile);
+ assertArrayEquals("Mismatched persisted data", expected, actual);
+ }
+
+ @Test // see SSHD-967
+ public void testTransferToFileChannel() 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 <=
SftpRemotePathChannel.DEFAULT_TRANSFER_BUFFER_SIZE;
+ totalWritten += seed.length()) {
+ output.append(seed).append(System.lineSeparator());
+ }
+ }
+
+ byte[] expected = Files.readAllBytes(srcFile);
+ Path dstFile = srcFile.getParent().resolve(getCurrentTestName() +
"-dst.txt");
+ Files.deleteIfExists(dstFile);
+
+ String remFilePath =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, srcFile);
+ try (ClientSession session = client.connect(getCurrentTestName(),
TEST_LOCALHOST, port)
+ .verify(7L, TimeUnit.SECONDS)
+ .getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ try (SftpClient sftp = createSftpClient(session);
+ FileChannel srcChannel = sftp.openRemotePathChannel(
+ remFilePath, EnumSet.of(StandardOpenOption.READ));
+ FileChannel dstChannel = FileChannel.open(dstFile,
+ StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
+ long numXfered = srcChannel.transferTo(0L, expected.length,
dstChannel);
+ assertEquals("Mismatched reported transfer count",
expected.length, numXfered);
+ }
+ }
+
+ byte[] actual = Files.readAllBytes(dstFile);
+ assertEquals("Mismatched transfered size", expected.length,
actual.length);
+ assertArrayEquals("Mismatched transferred data", expected, actual);
+ }
+
+ @Test // see SSHD-967
+ public void testTransferFromFileChannel() 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 <=
SftpRemotePathChannel.DEFAULT_TRANSFER_BUFFER_SIZE;
+ totalWritten += seed.length()) {
+ output.append(seed).append(System.lineSeparator());
+ }
+ }
+
+ byte[] expected = Files.readAllBytes(srcFile);
+ Path dstFile = srcFile.getParent().resolve(getCurrentTestName() +
"-dst.txt");
+ Files.deleteIfExists(dstFile);
+
+ String remFilePath =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, dstFile);
+ try (ClientSession session = client.connect(getCurrentTestName(),
TEST_LOCALHOST, port)
+ .verify(7L, TimeUnit.SECONDS)
+ .getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ try (SftpClient sftp = createSftpClient(session);
+ FileChannel dstChannel = sftp.openRemotePathChannel(
+ remFilePath, EnumSet.of(StandardOpenOption.CREATE,
StandardOpenOption.WRITE));
+ FileChannel srcChannel = FileChannel.open(srcFile,
StandardOpenOption.READ)) {
+ long numXfered = dstChannel.transferFrom(srcChannel, 0L,
expected.length);
+ assertEquals("Mismatched reported transfer count",
expected.length, numXfered);
+ }
+ }
+
+ byte[] actual = Files.readAllBytes(dstFile);
+ assertEquals("Mismatched transfered size", expected.length,
actual.length);
+ assertArrayEquals("Mismatched transferred data", expected, actual);
+ }
+}
\ No newline at end of file
diff --git
a/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
b/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
index 17b11cf..9abf06b 100644
---
a/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
+++
b/sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
@@ -26,8 +26,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.CopyOption;
@@ -44,7 +42,6 @@ import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Date;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
@@ -159,7 +156,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
public void testWriteOffsetIgnoredForAppendMode() throws IOException {
Path targetPath = detectTargetFolder();
Path parentPath = targetPath.getParent();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
Path testFile =
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
Files.deleteIfExists(testFile);
@@ -178,7 +176,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
try (SftpClient sftp = createSftpClient(session)) {
String file =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, testFile);
- try (CloseableHandle handle = sftp.open(file, OpenMode.Create,
OpenMode.Write, OpenMode.Read, OpenMode.Append)) {
+ try (CloseableHandle handle = sftp.open(
+ file, OpenMode.Create, OpenMode.Write, OpenMode.Read,
OpenMode.Append)) {
sftp.write(handle, 7365L, expectedRandom);
byte[] actualRandom = new byte[expectedRandom.length];
int readLen = sftp.read(handle, 0L, actualRandom);
@@ -195,7 +194,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
}
byte[] actualBytes = Files.readAllBytes(testFile);
- assertEquals("Mismatched result file size", expectedRandom.length +
expectedText.length, actualBytes.length);
+ assertEquals("Mismatched result file size",
+ expectedRandom.length + expectedText.length, actualBytes.length);
byte[] actualRandom = Arrays.copyOfRange(actualBytes, 0,
expectedRandom.length);
assertArrayEquals("Mismatched random part", expectedRandom,
actualRandom);
@@ -208,7 +208,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
public void testReadBufferLimit() throws Exception {
Path targetPath = detectTargetFolder();
Path parentPath = targetPath.getParent();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
Path testFile =
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
byte[] expected = new byte[1024];
@@ -228,7 +229,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
byte[] actual = new byte[expected.length];
int maxAllowed = actual.length / 4;
// allow less than actual
- PropertyResolverUtils.updateProperty(sshd,
AbstractSftpSubsystemHelper.MAX_READDATA_PACKET_LENGTH_PROP, maxAllowed);
+ PropertyResolverUtils.updateProperty(
+ sshd,
AbstractSftpSubsystemHelper.MAX_READDATA_PACKET_LENGTH_PROP, maxAllowed);
try (CloseableHandle handle = sftp.open(file, OpenMode.Read)) {
int readLen = sftp.read(handle, 0L, actual);
assertEquals("Mismatched read len", maxAllowed, readLen);
@@ -283,8 +285,9 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
private void testCannotEscapeRoot(boolean useAbsolutePath) throws
Exception {
Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
- assertHierarchyTargetFolderExists(lclSftp);
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
+ lclSftp = assertHierarchyTargetFolderExists(lclSftp);
sshd.setFileSystemFactory(new VirtualFileSystemFactory(lclSftp));
try (ClientSession session = client.connect(getCurrentTestName(),
TEST_LOCALHOST, port)
@@ -351,7 +354,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
public void testNormalizeRemotePathsValues() throws Exception {
Path targetPath = detectTargetFolder();
Path parentPath = targetPath.getParent();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
Path testFile =
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
String file =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, testFile);
String[] comps = GenericUtils.split(file, '/');
@@ -405,7 +409,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
public void testOpen() throws Exception {
Path targetPath = detectTargetFolder();
Path parentPath = targetPath.getParent();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
Path clientFolder = lclSftp.resolve("client");
Path testFile = clientFolder.resolve("file.txt");
String file =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, testFile);
@@ -458,7 +463,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
javaFile.setWritable(true, false);
- try (SftpClient.CloseableHandle h = sftp.open(file,
EnumSet.of(SftpClient.OpenMode.Truncate, SftpClient.OpenMode.Write))) {
+ try (SftpClient.CloseableHandle h = sftp.open(
+ file, EnumSet.of(SftpClient.OpenMode.Truncate,
SftpClient.OpenMode.Write))) {
// OK should succeed
assertTrue("Handle not marked as open for file=" + file,
h.isOpen());
}
@@ -524,7 +530,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
try (SftpClient sftp = createSftpClient(session)) {
Collection<PosixFilePermission> initialPermissions =
IoUtils.getPermissions(testFile);
assertTrue("File does not have enough initial permissions: " +
initialPermissions,
-
initialPermissions.containsAll(EnumSet.of(PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE)));
+ initialPermissions.containsAll(
+ EnumSet.of(PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE)));
try (CloseableHandle handle = sendRawAttributeImpactOpen(file,
sftp)) {
outputDebugMessage("%s - handle=%s", getCurrentTestName(),
handle);
@@ -541,7 +548,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
}
private CloseableHandle sendRawAttributeImpactOpen(String path, SftpClient
sftpClient) throws Exception {
- RawSftpClient sftp = assertObjectInstanceOf("Not a raw SFTP client
used", RawSftpClient.class, sftpClient);
+ RawSftpClient sftp = assertObjectInstanceOf(
+ "Not a raw SFTP client used", RawSftpClient.class, sftpClient);
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
buffer.putString(path, StandardCharsets.UTF_8);
//access
@@ -573,7 +581,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
public void testInputStreamSkipAndReset() throws Exception {
Path targetPath = detectTargetFolder();
Path parentPath = targetPath.getParent();
- Path localFile = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ 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);
@@ -584,7 +593,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
session.auth().verify(5L, TimeUnit.SECONDS);
try (SftpClient sftp = createSftpClient(session);
- InputStream stream =
sftp.read(CommonTestSupportUtils.resolveRelativeRemotePath(parentPath,
localFile), OpenMode.Read)) {
+ InputStream stream = sftp.read(
+
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, localFile),
OpenMode.Read)) {
assertFalse("Stream reported mark supported",
stream.markSupported());
try {
stream.mark(data.length);
@@ -650,7 +660,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
@Override
public DirectoryStream<Path> openDirectory(
- ServerSession session, SftpEventListenerManager
subsystem, DirectoryHandle dirHandle, Path dir, String handle)
+ ServerSession session, SftpEventListenerManager
subsystem,
+ DirectoryHandle dirHandle, Path dir, String handle)
throws IOException {
dirHolder.set(dir);
return SftpFileSystemAccessor.super.openDirectory(session,
subsystem, dirHandle, dir, handle);
@@ -801,8 +812,9 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
@Override
@SuppressWarnings("checkstyle:ParameterNumber")
- public void read(ServerSession session, String remoteHandle,
FileHandle localHandle,
- long offset, byte[] data, int dataOffset, int dataLen, int
readLen, Throwable thrown) {
+ public void read(
+ ServerSession session, String remoteHandle, FileHandle
localHandle, long offset,
+ byte[] data, int dataOffset, int dataLen, int readLen,
Throwable thrown) {
readSize.addAndGet(readLen);
if (log.isDebugEnabled()) {
log.debug("read(" + session + ")[" + localHandle.getFile()
+ "] offset=" + offset + ", requested=" + dataLen + ", read=" + readLen);
@@ -810,7 +822,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
}
@Override
- public void read(ServerSession session, String remoteHandle,
DirectoryHandle localHandle, Map<String, Path> entries) {
+ public void read(
+ ServerSession session, String remoteHandle,
DirectoryHandle localHandle, Map<String, Path> entries) {
int numEntries = GenericUtils.size(entries);
entriesCount.addAndGet(numEntries);
@@ -945,7 +958,8 @@ public class SftpTest extends AbstractSftpClientTestSupport
{
session.auth().verify(5L, TimeUnit.SECONDS);
Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
CommonTestSupportUtils.deleteRecursive(lclSftp);
Path parentPath = targetPath.getParent();
@@ -963,13 +977,20 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
PropertyResolverUtils.updateProperty(clientChannel,
AbstractSftpClient.WRITE_CHUNK_SIZE,
Math.min(SftpClient.DEFAULT_WRITE_BUFFER_SIZE,
AbstractSftpClient.DEFAULT_WRITE_CHUNK_SIZE) - Byte.MAX_VALUE);
- uploadAndVerifyFile(sftp, clientFolder, dir,
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT - 1,
"bufferMaxLenMinusOneFile.txt");
- uploadAndVerifyFile(sftp, clientFolder, dir,
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT, "bufferMaxLenFile.txt");
- uploadAndVerifyFile(sftp, clientFolder, dir,
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT + 1,
"bufferMaxLenPlusOneFile.txt");
- uploadAndVerifyFile(sftp, clientFolder, dir, (int) (1.5 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT),
"1point5BufferMaxLenFile.txt");
- uploadAndVerifyFile(sftp, clientFolder, dir, (2 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT) - 1,
"2TimesBufferMaxLenMinusOneFile.txt");
- uploadAndVerifyFile(sftp, clientFolder, dir, 2 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT,
"2TimesBufferMaxLenFile.txt");
- uploadAndVerifyFile(sftp, clientFolder, dir, (2 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT) + 1,
"2TimesBufferMaxLenPlusOneFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT - 1,
"bufferMaxLenMinusOneFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT,
"bufferMaxLenFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT + 1,
"bufferMaxLenPlusOneFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ (int) (1.5 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT),
"1point5BufferMaxLenFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ (2 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT) - 1,
"2TimesBufferMaxLenMinusOneFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ 2 * SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT,
"2TimesBufferMaxLenFile.txt");
+ uploadAndVerifyFile(sftp, clientFolder, dir,
+ (2 *
SshConstants.SSH_REQUIRED_TOTAL_PACKET_LENGTH_SUPPORT) + 1,
"2TimesBufferMaxLenPlusOneFile.txt");
uploadAndVerifyFile(sftp, clientFolder, dir, 200000,
"largerFile.txt");
// test erroneous calls that check for negative values
@@ -986,7 +1007,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
// generate random file and upload it
String randomData = randomString(5);
byte[] randomBytes = randomData.getBytes(StandardCharsets.UTF_8);
- try (SftpClient.CloseableHandle handle = sftp.open(filePath,
EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
+ try (SftpClient.CloseableHandle handle = sftp.open(
+ filePath, EnumSet.of(SftpClient.OpenMode.Write,
SftpClient.OpenMode.Create))) {
try {
sftp.write(handle, -1, randomBytes, 0, 0);
fail("should not have been able to write file with invalid
file offset for " + filePath);
@@ -1023,11 +1045,14 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
assertFalse("File should not be there: " + file.toString(),
Files.exists(file));
}
- private void uploadAndVerifyFile(SftpClient sftp, Path clientFolder,
String remoteDir, int size, String filename) throws Exception {
+ private void uploadAndVerifyFile(
+ SftpClient sftp, Path clientFolder, String remoteDir, int size,
String filename)
+ throws Exception {
// generate random file and upload it
String remotePath = remoteDir + "/" + filename;
String randomData = randomString(size);
- try (SftpClient.CloseableHandle handle = sftp.open(remotePath,
EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
+ try (SftpClient.CloseableHandle handle = sftp.open(
+ remotePath, EnumSet.of(SftpClient.OpenMode.Write,
SftpClient.OpenMode.Create))) {
sftp.write(handle, 0, randomData.getBytes(StandardCharsets.UTF_8),
0, randomData.length());
}
@@ -1046,7 +1071,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
String d = getCurrentTestName() + "\n";
Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
CommonTestSupportUtils.deleteRecursive(lclSftp);
Path target =
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
@@ -1072,7 +1098,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
@Test
public void testReadWriteWithOffset() throws Exception {
Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
CommonTestSupportUtils.deleteRecursive(lclSftp);
Path localPath =
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
@@ -1150,7 +1177,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
@Test
public void testRename() throws Exception {
Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
CommonTestSupportUtils.deleteRecursive(lclSftp);
Path parentPath = targetPath.getParent();
@@ -1348,7 +1376,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
} catch (SocketTimeoutException | EOFException |
WindowClosedException | SshChannelClosedException e) {
// expected - ignored
} finally {
- PropertyResolverUtils.updateProperty(session,
SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, SftpClient.DEFAULT_CHANNEL_OPEN_TIMEOUT);
+ PropertyResolverUtils.updateProperty(
+ session, SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT,
SftpClient.DEFAULT_CHANNEL_OPEN_TIMEOUT);
}
} finally {
sshd.setSubsystemFactories(factories);
@@ -1357,7 +1386,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
private void testClient(FactoryManager manager, SftpClient sftp) throws
Exception {
Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(),
getCurrentTestName());
+ Path lclSftp = CommonTestSupportUtils.resolve(
+ targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME,
getClass().getSimpleName(), getCurrentTestName());
CommonTestSupportUtils.deleteRecursive(lclSftp);
Path parentPath = targetPath.getParent();
@@ -1366,7 +1396,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
sftp.mkdir(dir);
String file = dir + "/" + getCurrentTestName() + "-file.txt";
- try (SftpClient.CloseableHandle h = sftp.open(file,
EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
+ try (SftpClient.CloseableHandle h = sftp.open(
+ file, EnumSet.of(SftpClient.OpenMode.Write,
SftpClient.OpenMode.Create))) {
byte[] d = "0123456789\n".getBytes(StandardCharsets.UTF_8);
sftp.write(h, 0, d, 0, d.length);
sftp.write(h, d.length, d, 0, d.length);
@@ -1466,7 +1497,8 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
}
@Override
- public void linked(ServerSession session, Path src, Path target,
boolean symLink, Throwable thrown) {
+ public void linked(
+ ServerSession session, Path src, Path target, boolean
symLink, Throwable thrown) {
LinkData data = linkDataHolder.get();
assertNotNull("No previous linking call", data);
assertSame("Mismatched source", data.getSource(), src);
@@ -1537,44 +1569,6 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
assertNotNull("No symlink signalled", linkDataHolder.getAndSet(null));
}
- @Test // see SSHD-697
- public void testFileChannel() throws IOException {
- Path targetPath = detectTargetFolder();
- Path lclSftp = CommonTestSupportUtils.resolve(targetPath,
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName());
- Path lclFile = lclSftp.resolve(getCurrentTestName() + ".txt");
- Files.deleteIfExists(lclFile);
- byte[] expected = (getClass().getName() + "#" + getCurrentTestName() +
"(" + new Date() + ")").getBytes(StandardCharsets.UTF_8);
-
- try (ClientSession session = client.connect(getCurrentTestName(),
TEST_LOCALHOST, port)
- .verify(7L, TimeUnit.SECONDS)
- .getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
-
- try (SftpClient sftp = createSftpClient(session)) {
- Path parentPath = targetPath.getParent();
- String remFilePath =
CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, lclFile);
-
- try (FileChannel fc = sftp.openRemotePathChannel(
- remFilePath, EnumSet.of(StandardOpenOption.CREATE,
StandardOpenOption.READ, StandardOpenOption.WRITE))) {
- int writeLen = fc.write(ByteBuffer.wrap(expected));
- assertEquals("Mismatched written length", expected.length,
writeLen);
-
- FileChannel fcPos = fc.position(0L);
- assertSame("Mismatched positioned file channel", fc,
fcPos);
-
- byte[] actual = new byte[expected.length];
- int readLen = fc.read(ByteBuffer.wrap(actual));
- assertEquals("Mismatched read len", writeLen, readLen);
- assertArrayEquals("Mismatched read data", expected,
actual);
- }
- }
- }
-
- byte[] actual = Files.readAllBytes(lclFile);
- assertArrayEquals("Mismatched persisted data", expected, actual);
- }
-
@Test // see SSHD-903
public void testForcedVersionNegotiation() throws Exception {
PropertyResolverUtils.updateProperty(sshd,
SftpSubsystemEnvironment.SFTP_VERSION, SftpConstants.SFTP_V3);
@@ -1601,7 +1595,7 @@ public class SftpTest extends
AbstractSftpClientTestSupport {
bos.write(buffer, 0, count);
}
- return bos.toString();
+ return bos.toString(StandardCharsets.UTF_8.name());
} finally {
c.disconnect();
}