You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/07/13 16:26:41 UTC
[2/2] mina-sshd git commit: [SSHD-538] Handle correctly paths with
double-slashes in them
[SSHD-538] Handle correctly paths with double-slashes in them
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/5da0d1a8
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/5da0d1a8
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/5da0d1a8
Branch: refs/heads/master
Commit: 5da0d1a86bff354e71916954a31257f9c5e45dbc
Parents: 14579eb
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Mon Jul 13 17:26:28 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Mon Jul 13 17:26:28 2015 +0300
----------------------------------------------------------------------
.../org/apache/sshd/common/scp/ScpHelper.java | 10 +-
.../java/org/apache/sshd/common/util/Pair.java | 7 +
.../apache/sshd/common/util/SelectorUtils.java | 34 +-
.../server/subsystem/sftp/SftpSubsystem.java | 209 ++++----
.../org/apache/sshd/client/scp/ScpTest.java | 482 +++++++++++--------
.../subsystem/sftp/SftpFileSystemTest.java | 16 +-
.../sshd/client/subsystem/sftp/SftpTest.java | 161 +++++--
.../AbstractCheckFileExtensionTest.java | 7 +-
.../AbstractMD5HashExtensionTest.java | 9 +-
.../extensions/CopyDataExtensionImplTest.java | 9 +-
.../sftp/extensions/OpenSSHExtensionsTest.java | 7 +-
.../server/subsystem/sftp/SshFsMounter.java | 318 ++++++++++++
.../org/apache/sshd/util/BaseTestSupport.java | 29 +-
13 files changed, 893 insertions(+), 405 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
index 96efe39..88e604a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
@@ -46,6 +46,7 @@ import org.apache.sshd.common.file.util.MockPath;
import org.apache.sshd.common.scp.ScpTransferEventListener.FileOperation;
import org.apache.sshd.common.util.DirectoryScanner;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.SelectorUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.LimitInputStream;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
@@ -473,7 +474,7 @@ public class ScpHelper extends AbstractLoggingBean {
}
}
- public Path resolveLocalPath(String basedir, String subpath) {
+ public Path resolveLocalPath(String basedir, String subpath) throws IOException {
if (GenericUtils.isEmpty(basedir)) {
return resolveLocalPath(subpath);
} else {
@@ -481,8 +482,11 @@ public class ScpHelper extends AbstractLoggingBean {
}
}
- public Path resolveLocalPath(String path) {
- String localPath = (path == null) ? null : path.replace('/', File.separatorChar);
+ public Path resolveLocalPath(String remotePath) throws IOException {
+ // In case double slashes and other patterns are used
+ String path = SelectorUtils.normalizePath(remotePath, "/");
+ String localPath = SelectorUtils.translateToLocalPath(path);
+
return fileSystem.getPath(localPath);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java b/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
index d885b14..21e23d6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
@@ -18,6 +18,8 @@
*/
package org.apache.sshd.common.util;
+import java.util.Objects;
+
/**
* Represents a pair of values
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -38,4 +40,9 @@ public class Pair<U,V> {
public V getSecond() {
return second;
}
+
+ @Override
+ public String toString() {
+ return Objects.toString(getFirst()) + ", " + Objects.toString(getSecond());
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java
index 0b0c19e..2ac0976 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java
@@ -532,33 +532,51 @@ public final class SelectorUtils {
/**
* Normalizes the path by removing '.', '..' and double separators (e.g. '//')
- * @param path
- * @param separator
+ * @param path Original path - ignored if {@code null}/empty
+ * @param separator The separator used for the path components
* @return normalized path
* @throws IOException when the path is invalid (e.g. '/first/../..')
*/
public static String normalizePath(String path, String separator) throws IOException {
+ if (GenericUtils.isEmpty(path)) {
+ return path;
+ }
+
boolean startsWithSeparator = path.startsWith(separator);
- // tokenize
List<String> tokens = tokenizePath(path, separator);
-
+ int removedDots = 0;
// clean up
for (int i = tokens.size() - 1; i >= 0; i--) {
String t = tokens.get(i);
- if (t.length() == 0 || t.equals(".")) {
+ if (GenericUtils.isEmpty(t)) {
+ tokens.remove(i);
+ } else if (t.equals(".")) {
tokens.remove(i);
+ removedDots++;
} else if (t.equals("..")) {
tokens.remove(i);
+ removedDots++;
if (i >= 1) {
tokens.remove(--i);
+ removedDots++;
}
}
}
+ if (GenericUtils.isEmpty(tokens)) {
+ if (removedDots > 0) {
+ return ""; // had some "." and ".." after which we remained with no path
+ } else {
+ return separator; // it was all separators
+ }
+ }
+
// serialize
StringBuilder buffer = new StringBuilder(path.length());
for (int i = 0; i < tokens.size(); i++) {
- if (i > 0 || (i == 0 && startsWithSeparator)) buffer.append(separator);
+ if ((i > 0) || ((i == 0) && startsWithSeparator)) {
+ buffer.append(separator);
+ }
buffer.append(tokens.get(i));
}
@@ -574,7 +592,7 @@ public final class SelectorUtils {
* Converts a possibly '/' separated path to a local path. <B>Note:</B>
* takes special care of Windows drive paths - e.g., {@code C:}
* by converting them to "C:\"
- * @param path The original path
+ * @param path The original path - ignored if {@code null}/empty
* @return The local path
*/
public static String translateToLocalPath(String path) {
@@ -582,7 +600,7 @@ public final class SelectorUtils {
return path;
}
- // this means we are running on Windows
+ // This code is reached if we are running on Windows
String localPath=path.replace('/', File.separatorChar);
if ((localPath.length() < 2) || (localPath.charAt(1) != ':')) {
return localPath; // assume a relative path
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
index add23fe..a12811f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
@@ -40,6 +40,7 @@ import java.nio.file.FileSystem;
import java.nio.file.FileSystemLoopException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.NotDirectoryException;
@@ -88,11 +89,12 @@ import org.apache.sshd.common.digest.Digest;
import org.apache.sshd.common.file.FileSystemAware;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.subsystem.sftp.SftpConstants;
-import org.apache.sshd.common.subsystem.sftp.extensions.openssh.FsyncExtensionParser;
import org.apache.sshd.common.subsystem.sftp.extensions.openssh.AbstractOpenSSHExtensionParser.OpenSSHExtension;
+import org.apache.sshd.common.subsystem.sftp.extensions.openssh.FsyncExtensionParser;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.Int2IntFunction;
import org.apache.sshd.common.util.OsUtils;
+import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.SelectorUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -1531,7 +1533,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
log.debug("Received SSH_FXP_STAT (path={}, flags=0x{})", path, Integer.toHexString(flags));
}
Path p = resolveFile(path);
- return resolveFileAttributes(p, flags, true);
+ return resolveFileAttributes(p, flags, IoUtils.getLinkOptions(false));
}
protected void doRealPath(Buffer buffer, int id) throws IOException {
@@ -1543,12 +1545,21 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
}
Map<String,?> attrs = Collections.<String, Object>emptyMap();
- Path p;
+ Pair<Path,Boolean> result;
try {
+ LinkOption[] options = IoUtils.getLinkOptions(false);
if (version < SFTP_V6) {
- p = doRealPathV6(id, path);
+ /*
+ * See http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt:
+ *
+ * The SSH_FXP_REALPATH request can be used to have the server
+ * canonicalize any given path name to an absolute path.
+ *
+ * See also SSHD-294
+ */
+ result = doRealPathV345(id, path, options);
} else {
- // Read control byte
+ // see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 section 8.9
int control = 0;
if (buffer.available() > 0) {
control = buffer.getUByte();
@@ -1559,18 +1570,35 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
extraPaths.add(buffer.getString());
}
- p = doRealPathV345(id, path, extraPaths);
+ result = doRealPathV6(id, path, extraPaths, options);
+
+ Path p = result.getFirst();
+ Boolean status = result.getSecond();
if (control == SSH_FXP_REALPATH_STAT_IF) {
- try {
- attrs = getAttributes(p, false);
- } catch (IOException e) {
+ if (status == null) {
+ attrs = handleUnknownStatusFileAttributes(p, SSH_FILEXFER_ATTR_ALL, options);
+ } else if (status.booleanValue()) {
+ try {
+ attrs = getAttributes(p, IoUtils.getLinkOptions(false));
+ } catch (IOException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Failed ({}) to retrieve attributes of {}: {}",
+ e.getClass().getSimpleName(), p, e.getMessage());
+ }
+ }
+ } else {
if (log.isDebugEnabled()) {
- log.debug("Failed ({}) to retrieve attributes of {}: {}",
- e.getClass().getSimpleName(), p, e.getMessage());
+ log.debug("Dummy attributes for non-existing file: " + p);
}
}
} else if (control == SSH_FXP_REALPATH_STAT_ALWAYS) {
- attrs = getAttributes(p, false);
+ if (status == null) {
+ attrs = handleUnknownStatusFileAttributes(p, SSH_FILEXFER_ATTR_ALL, options);
+ } else if (status.booleanValue()) {
+ attrs = getAttributes(p, options);
+ } else {
+ throw new FileNotFoundException(p.toString());
+ }
}
}
} catch (IOException | RuntimeException e) {
@@ -1578,52 +1606,46 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
return;
}
- sendPath(BufferUtils.clear(buffer), id, p, attrs);
+ sendPath(BufferUtils.clear(buffer), id, result.getFirst(), attrs);
}
- protected Path doRealPathV345(int id, String path, Collection<String> extraPaths) throws IOException {
+ protected Pair<Path,Boolean> doRealPathV6(int id, String path, Collection<String> extraPaths, LinkOption ... options) throws IOException {
Path p = resolveFile(path);
-
- if (GenericUtils.size(extraPaths) > 0) {
+ int numExtra = GenericUtils.size(extraPaths);
+ if (numExtra > 0) {
+ StringBuilder sb = new StringBuilder(GenericUtils.length(path) + numExtra * 8);
+ sb.append(path);
+
for (String p2 : extraPaths) {
p = p.resolve(p2);
+ sb.append('/').append(p2);
}
+
+ path = sb.toString();
}
- p = p.toAbsolutePath();
- return p.normalize();
+ return validateRealPath(id, path, p, options);
}
- protected Path doRealPathV6(int id, String path) throws IOException {
- Path f = resolveFile(path);
- Path abs = f.toAbsolutePath();
- Path p = abs.normalize();
- Boolean status = IoUtils.checkFileExists(p, IoUtils.EMPTY_LINK_OPTIONS);
- if (status == null) {
- return handleUnknownRealPathStatus(path, abs, p);
- } else if (status.booleanValue()) {
- return p;
- } else {
- throw new FileNotFoundException(path);
- }
+ protected Pair<Path,Boolean> doRealPathV345(int id, String path, LinkOption ... options) throws IOException {
+ return validateRealPath(id, path, resolveFile(path), options);
}
- protected Path handleUnknownRealPathStatus(String path, Path absolute, Path normalized) throws IOException {
- switch(unsupportedAttributePolicy) {
- case Ignore:
- break;
- case Warn:
- log.warn("handleUnknownRealPathStatus(" + path + ") abs=" + absolute + ", normal=" + normalized);
- break;
- case ThrowException:
- throw new AccessDeniedException("Cannot determine existence status of real path: " + normalized);
-
- default:
- log.warn("handleUnknownRealPathStatus(" + path + ") abs=" + absolute + ", normal=" + normalized
- + " - unknown policy: " + unsupportedAttributePolicy);
- }
-
- return absolute;
+ /**
+ * @param id The request identifier
+ * @param path The original path
+ * @param f The resolve {@link Path}
+ * @param options The {@link LinkOption}s to use to verify file existence and access
+ * @return A {@link Pair} whose left-hand is the <U>absolute <B>normalized</B></U>
+ * {@link Path} and right-hand is a {@link Boolean} indicating its status
+ * @throws IOException If failed to validate the file
+ * @see IoUtils#checkFileExists(Path, LinkOption...)
+ */
+ protected Pair<Path,Boolean> validateRealPath(int id, String path, Path f, LinkOption ... options) throws IOException {
+ Path abs = f.toAbsolutePath();
+ Path p = abs.normalize();
+ Boolean status = IoUtils.checkFileExists(p, options);
+ return new Pair<Path, Boolean>(p, status);
}
protected void doRemoveDirectory(Buffer buffer, int id) throws IOException {
@@ -1727,9 +1749,9 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
throw new EOFException("Directory reading is done");
}
- Path file = dh.getFile();
- LinkOption[] options = IoUtils.getLinkOptions(false);
- Boolean status = IoUtils.checkFileExists(file, options);
+ Path file = dh.getFile();
+ LinkOption[] options = IoUtils.getLinkOptions(false);
+ Boolean status = IoUtils.checkFileExists(file, options);
if (status == null) {
throw new AccessDeniedException("Cannot determine existence of read-dir for " + file);
}
@@ -1755,8 +1777,8 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
int count = doReadDir(id, dh, reply, FactoryManagerUtils.getIntProperty(session, MAX_PACKET_LENGTH_PROP, DEFAULT_MAX_PACKET_LENGTH));
BufferUtils.updateLengthPlaceholder(reply, lenPos, count);
- if (log.isTraceEnabled()) {
- log.trace("doReadDir({})[{}] - sent {} entries", handle, h, Integer.valueOf(count));
+ if (log.isDebugEnabled()) {
+ log.debug("doReadDir({})[{}] - sent {} entries", handle, h, Integer.valueOf(count));
}
if ((!dh.isSendDot()) && (!dh.isSendDotDot()) && (!dh.hasNext())) {
// if no more files to send
@@ -1879,7 +1901,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
log.debug("Received SSH_FXP_FSTAT (handle={}[{}], flags=0x{})", handle, h, Integer.toHexString(flags));
}
- return resolveFileAttributes(validateHandle(handle, h, Handle.class).getFile(), flags, true);
+ return resolveFileAttributes(validateHandle(handle, h, Handle.class).getFile(), flags, IoUtils.getLinkOptions(true));
}
protected void doLStat(Buffer buffer, int id) throws IOException {
@@ -1906,7 +1928,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
log.debug("Received SSH_FXP_LSTAT (path={}[{}], flags=0x{})", path, p, Integer.toHexString(flags));
}
- return resolveFileAttributes(p, flags, false);
+ return resolveFileAttributes(p, flags, IoUtils.getLinkOptions(false));
}
protected void doWrite(Buffer buffer, int id) throws IOException {
@@ -2389,16 +2411,17 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
*/
protected int doReadDir(int id, DirectoryHandle dir, Buffer buffer, int maxSize) throws IOException {
int nb = 0;
+ LinkOption[] options = IoUtils.getLinkOptions(false);
while ((dir.isSendDot() || dir.isSendDotDot() || dir.hasNext()) && (buffer.wpos() < maxSize)) {
if (dir.isSendDot()) {
- writeDirEntry(id, dir, buffer, nb, dir.getFile(), ".");
+ writeDirEntry(id, dir, buffer, nb, dir.getFile(), ".", options);
dir.markDotSent(); // do not send it again
} else if (dir.isSendDotDot()) {
- writeDirEntry(id, dir, buffer, nb, dir.getFile().getParent(), "..");
+ writeDirEntry(id, dir, buffer, nb, dir.getFile().getParent(), "..", options);
dir.markDotDotSent(); // do not send it again
} else {
Path f = dir.next();
- writeDirEntry(id, dir, buffer, nb, f, getShortName(f));
+ writeDirEntry(id, dir, buffer, nb, f, getShortName(f), options);
}
nb++;
@@ -2414,34 +2437,36 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
* @param index Zero-based index of the entry to be written
* @param f The entry {@link Path}
* @param shortName The entry short name
+ * @param options The {@link LinkOption}s to use for querying the entry-s attributes
* @throws IOException If failed to generate the entry data
*/
- protected void writeDirEntry(int id, DirectoryHandle dir, Buffer buffer, int index, Path f, String shortName) throws IOException {
+ protected void writeDirEntry(int id, DirectoryHandle dir, Buffer buffer, int index, Path f, String shortName, LinkOption ... options) throws IOException {
+ Map<String,?> attrs = resolveFileAttributes(f, SSH_FILEXFER_ATTR_ALL, options);
+
buffer.putString(shortName);
if (version == SFTP_V3) {
- String longName = getLongName(f);
+ String longName = getLongName(f, options);
buffer.putString(longName);
if (log.isTraceEnabled()) {
- log.trace("writeDirEntry(id=" + id + ")[" + index + "] - " + shortName + " [" + longName + "]");
+ log.trace("writeDirEntry(id=" + id + ")[" + index + "] - " + shortName + " [" + longName + "]: " + attrs);
}
} else {
if (log.isTraceEnabled()) {
- log.trace("writeDirEntry(id=" + id + ")[" + index + "] - " + shortName);
+ log.trace("writeDirEntry(id=" + id + ")[" + index + "] - " + shortName + ": " + attrs);
}
}
- Map<String,?> attrs = resolveFileAttributes(f, SSH_FILEXFER_ATTR_ALL, false);
writeAttrs(buffer, attrs);
}
- protected String getLongName(Path f) throws IOException {
- return getLongName(f, true);
+ protected String getLongName(Path f, LinkOption ... options) throws IOException {
+ return getLongName(f, true, options);
}
- private String getLongName(Path f, boolean sendAttrs) throws IOException {
+ private String getLongName(Path f, boolean sendAttrs, LinkOption ... options) throws IOException {
Map<String, Object> attributes;
if (sendAttrs) {
- attributes = getAttributes(f, false);
+ attributes = getAttributes(f, options);
} else {
attributes = Collections.emptyMap();
}
@@ -2509,7 +2534,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
return sb.toString();
}
- protected String getShortName(Path f) {
+ protected String getShortName(Path f) throws IOException {
if (OsUtils.isUNIX()) {
Path name=f.getFileName();
if (name == null) {
@@ -2578,15 +2603,14 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
return pf;
}
- protected Map<String, Object> resolveFileAttributes(Path file, int flags, boolean followLinks) throws IOException {
- LinkOption[] options = IoUtils.getLinkOptions(followLinks);
- Boolean status = IoUtils.checkFileExists(file, options);
+ protected Map<String, Object> resolveFileAttributes(Path file, int flags, LinkOption ... options) throws IOException {
+ Boolean status = IoUtils.checkFileExists(file, options);
if (status == null) {
- return handleUnknownStatusFileAttributes(file, flags, followLinks);
+ return handleUnknownStatusFileAttributes(file, flags, options);
} else if (!status.booleanValue()) {
throw new FileNotFoundException(file.toString());
} else {
- return getAttributes(file, flags, followLinks);
+ return getAttributes(file, flags, options);
}
}
@@ -2674,13 +2698,13 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
return (bool != null) && bool.booleanValue();
}
- protected Map<String, Object> getAttributes(Path file, boolean followLinks) throws IOException {
- return getAttributes(file, SSH_FILEXFER_ATTR_ALL, followLinks);
+ protected Map<String, Object> getAttributes(Path file, LinkOption ... options) throws IOException {
+ return getAttributes(file, SSH_FILEXFER_ATTR_ALL, options);
}
public static final List<String> DEFAULT_UNIX_VIEW=Collections.singletonList("unix:*");
- protected Map<String, Object> handleUnknownStatusFileAttributes(Path file, int flags, boolean followLinks) throws IOException {
+ protected Map<String, Object> handleUnknownStatusFileAttributes(Path file, int flags, LinkOption ... options) throws IOException {
switch(unsupportedAttributePolicy) {
case Ignore:
break;
@@ -2693,13 +2717,12 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
log.warn("handleUnknownStatusFileAttributes(" + file + ") unknown policy: " + unsupportedAttributePolicy);
}
- return getAttributes(file, flags, followLinks);
+ return getAttributes(file, flags, options);
}
- protected Map<String, Object> getAttributes(Path file, int flags, boolean followLinks) throws IOException {
+ protected Map<String, Object> getAttributes(Path file, int flags, LinkOption ... options) throws IOException {
FileSystem fs=file.getFileSystem();
Collection<String> supportedViews=fs.supportedFileAttributeViews();
- LinkOption[] opts=IoUtils.getLinkOptions(followLinks);
Map<String,Object> attrs=new HashMap<>();
Collection<String> views;
@@ -2715,7 +2738,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
}
for (String v : views) {
- Map<String, Object> ta=readFileAttributes(file, v, opts);
+ Map<String, Object> ta=readFileAttributes(file, v, options);
attrs.putAll(ta);
}
@@ -2728,15 +2751,15 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
return attrs;
}
- protected Map<String, Object> readFileAttributes(Path file, String view, LinkOption ... opts) throws IOException {
+ protected Map<String, Object> readFileAttributes(Path file, String view, LinkOption ... options) throws IOException {
try {
- return Files.readAttributes(file, view, opts);
+ return Files.readAttributes(file, view, options);
} catch(IOException e) {
- return handleReadFileAttributesException(file, view, opts, e);
+ return handleReadFileAttributesException(file, view, options, e);
}
}
- protected Map<String, Object> handleReadFileAttributesException(Path file, String view, LinkOption[] opts, IOException e) throws IOException {
+ protected Map<String, Object> handleReadFileAttributesException(Path file, String view, LinkOption[] options, IOException e) throws IOException {
switch(unsupportedAttributePolicy) {
case Ignore:
break;
@@ -3167,6 +3190,8 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
return SSH_FX_OP_UNSUPPORTED;
} else if (e instanceof IllegalArgumentException) {
return SSH_FX_INVALID_PARAMETER;
+ } else if (e instanceof InvalidPathException) {
+ return SSH_FX_INVALID_FILENAME;
} else {
return SSH_FX_FAILURE;
}
@@ -3239,23 +3264,29 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
}
}
- private Path resolveFile(String path) {
- //in case we are running on Windows
+ protected Path resolveFile(String remotePath) throws IOException, InvalidPathException {
+ // In case double slashes and other patterns are used
+ String path = SelectorUtils.normalizePath(remotePath, "/");
String localPath = SelectorUtils.translateToLocalPath(path);
+
+ // In case we are running on Windows
return defaultDir.resolve(localPath);
}
- private final static String[] MONTHS = { "Jan", "Feb", "Mar", "Apr", "May",
- "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+ public static final List<String> MONTHS =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ ));
/**
* Get unix style date string.
*/
- private static String getUnixDate(FileTime time) {
+ public static String getUnixDate(FileTime time) {
return getUnixDate(time != null ? time.toMillis() : -1);
}
- private static String getUnixDate(long millis) {
+ public static String getUnixDate(long millis) {
if (millis < 0) {
return "------------";
}
@@ -3265,7 +3296,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
cal.setTimeInMillis(millis);
// month
- sb.append(MONTHS[cal.get(Calendar.MONTH)]);
+ sb.append(MONTHS.get(cal.get(Calendar.MONTH)));
sb.append(' ');
// day
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
index 945f4ef..a1291a0 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -39,11 +39,14 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.Factory;
import org.apache.sshd.common.file.FileSystemFactory;
import org.apache.sshd.common.file.root.RootedFileSystemProvider;
+import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.scp.ScpHelper;
import org.apache.sshd.common.scp.ScpTransferEventListener;
import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.command.ScpCommandFactory;
@@ -135,42 +138,104 @@ public class ScpTest extends BaseTestSupport {
}
@Test
- public void testUploadAbsoluteDriveLetter() throws Exception {
+ public void testNormalizedScpRemotePaths() throws Exception {
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
+ Utils.deleteRecursive(scpRoot);
+
+ Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+ Path localFile = localDir.resolve("file.txt");
+ byte[] data = writeFile(localFile, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
+
+ Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+ Path remoteFile = remoteDir.resolve(localFile.getFileName().toString());
+ String localPath = localFile.toString();
+ String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
+ String[] remoteComps = GenericUtils.split(remotePath, '/');
+
try (SshClient client = SshClient.setUpDefaultClient()) {
client.start();
- try {
- try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
-
- ScpClient scp = createScpClient(session);
- Path targetPath = detectTargetFolder().toPath();
- Path parentPath = targetPath.getParent();
- Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
- Utils.deleteRecursive(scpRoot);
-
- Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
- Path localFile = localDir.resolve(getCurrentTestName() + "-1.txt");
- byte[] data = writeFile(localFile, (getCurrentTestName() + "\n"));
-
- Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
- Path remoteFile = remoteDir.resolve(localFile.getFileName().toString());
- String localPath = localFile.toString();
- String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
- scp.upload(localPath, remotePath);
- assertFileLength(remoteFile, data.length, 5000);
-
- Path secondRemote = remoteDir.resolve(getCurrentTestName() + "-2.txt");
- String secondPath = Utils.resolveRelativeRemotePath(parentPath, secondRemote);
- scp.upload(localPath, secondPath);
- assertFileLength(secondRemote, data.length, 5000);
+ Factory<? extends Random> factory = client.getRandomFactory();
+ Random rnd = factory.create();
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ ScpClient scp = createScpClient(session);
+ StringBuilder sb = new StringBuilder(remotePath.length() + Long.SIZE);
+ for (int i = 0; i < Math.max(Long.SIZE, remoteComps.length); i++) {
+ if (sb.length() > 0) {
+ sb.setLength(0); // start again
+ }
- Path pathRemote = remoteDir.resolve(getCurrentTestName() + "-path.txt");
- String pathPath = Utils.resolveRelativeRemotePath(parentPath, pathRemote);
- scp.upload(localFile, pathPath);
- assertFileLength(pathRemote, data.length, 5000);
+ sb.append(remoteComps[0]);
+ for (int j = 1; j < remoteComps.length; j++) {
+ String name = remoteComps[j];
+ slashify(sb, rnd);
+ sb.append(name);
+ }
+ slashify(sb, rnd);
+
+ String path = sb.toString();
+ scp.upload(localPath, path);
+ assertTrue("Remote file not ready for " + path, waitForFile(remoteFile, data.length, TimeUnit.SECONDS.toMillis(5L)));
+
+ byte[] actual = Files.readAllBytes(remoteFile);
+ assertArrayEquals("Mismatched uploaded data for " + path, data, actual);
+ Files.delete(remoteFile);
+ assertFalse("Remote file (" + remoteFile + ") not deleted for " + path, Files.exists(remoteFile));
}
+ }
+ }
+ }
+
+ private static int slashify(StringBuilder sb, Random rnd) {
+ int slashes = 1 /* at least one slash */ + rnd.random(Byte.SIZE);
+ for (int k=0; k < slashes; k++) {
+ sb.append('/');
+ }
+
+ return slashes;
+ }
+
+ @Test
+ public void testUploadAbsoluteDriveLetter() throws Exception {
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
+ Utils.deleteRecursive(scpRoot);
+
+ Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+ Path localFile = localDir.resolve("file-1.txt");
+ byte[] data = writeFile(localFile, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
+
+ Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+ Path remoteFile = remoteDir.resolve(localFile.getFileName().toString());
+ String localPath = localFile.toString();
+ String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
+
+ try (SshClient client = SshClient.setUpDefaultClient()) {
+ client.start();
+
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ ScpClient scp = createScpClient(session);
+ scp.upload(localPath, remotePath);
+ assertFileLength(remoteFile, data.length, TimeUnit.SECONDS.toMillis(5L));
+
+ Path secondRemote = remoteDir.resolve("file-2.txt");
+ String secondPath = Utils.resolveRelativeRemotePath(parentPath, secondRemote);
+ scp.upload(localPath, secondPath);
+ assertFileLength(secondRemote, data.length, TimeUnit.SECONDS.toMillis(5L));
+
+ Path pathRemote = remoteDir.resolve("file-path.txt");
+ String pathPath = Utils.resolveRelativeRemotePath(parentPath, pathRemote);
+ scp.upload(localFile, pathPath);
+ assertFileLength(pathRemote, data.length, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -182,31 +247,29 @@ public class ScpTest extends BaseTestSupport {
try (SshClient client = SshClient.setUpDefaultClient()) {
client.start();
- try {
- try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
- ScpClient scp = createScpClient(session);
- String data = getCurrentTestName() + "\n";
+ ScpClient scp = createScpClient(session);
+ String data = getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator");
- Path targetPath = detectTargetFolder().toPath();
- Path parentPath = targetPath.getParent();
- Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
- Utils.deleteRecursive(scpRoot);
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
+ Utils.deleteRecursive(scpRoot);
- Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
- Path localFile = localDir.resolve(getCurrentTestName() + ".txt");
- writeFile(localFile, data);
+ Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+ Path localFile = localDir.resolve("file.txt");
+ writeFile(localFile, data);
- Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
- Path remoteFile = remoteDir.resolve(localFile.getFileName());
- writeFile(remoteFile, data + data);
+ Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+ Path remoteFile = remoteDir.resolve(localFile.getFileName());
+ writeFile(remoteFile, data + data);
- String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
- scp.upload(localFile.toString(), remotePath);
- assertFileLength(remoteFile, data.length(), 5000);
- }
+ String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
+ scp.upload(localFile.toString(), remotePath);
+ assertFileLength(remoteFile, data.length(), TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -219,7 +282,7 @@ public class ScpTest extends BaseTestSupport {
Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
- Path zeroLocal = localDir.resolve(getCurrentTestName());
+ Path zeroLocal = localDir.resolve("zero.txt");
try (FileChannel fch = FileChannel.open(zeroLocal, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
if (fch.size() > 0L) {
@@ -234,18 +297,16 @@ public class ScpTest extends BaseTestSupport {
}
try (SshClient client = SshClient.setUpDefaultClient()) {
- try {
- client.start();
+ client.start();
- try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
- ScpClient scp = createScpClient(session);
- String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
- scp.upload(zeroLocal.toString(), remotePath);
- assertFileLength(zeroRemote, 0L, TimeUnit.SECONDS.toMillis(5L));
- }
+ ScpClient scp = createScpClient(session);
+ String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
+ scp.upload(zeroLocal.toString(), remotePath);
+ assertFileLength(zeroRemote, 0L, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -272,18 +333,16 @@ public class ScpTest extends BaseTestSupport {
assertEquals("Non-zero size for remote file=" + zeroRemote, 0L, Files.size(zeroRemote));
try (SshClient client = SshClient.setUpDefaultClient()) {
- try {
- client.start();
+ client.start();
- try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
- ScpClient scp = createScpClient(session);
- String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
- scp.download(remotePath, zeroLocal.toString());
- assertFileLength(zeroLocal, 0L, TimeUnit.SECONDS.toMillis(5L));
- }
+ ScpClient scp = createScpClient(session);
+ String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
+ scp.download(remotePath, zeroLocal.toString());
+ assertFileLength(zeroLocal, 0L, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -292,51 +351,50 @@ public class ScpTest extends BaseTestSupport {
@Test
public void testScpNativeOnSingleFile() throws Exception {
- try (SshClient client = SshClient.setUpDefaultClient()) {
- client.start();
+ String data = getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator");
+
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
+ Utils.deleteRecursive(scpRoot);
- try {
- try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
+ Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+ Path localOutFile = localDir.resolve("file-1.txt");
+ Path remoteDir = scpRoot.resolve("remote");
+ Path remoteOutFile = remoteDir.resolve(localOutFile.getFileName());
- ScpClient scp = createScpClient(session);
- String data = getCurrentTestName() + "\n";
+ try (SshClient client = SshClient.setUpDefaultClient()) {
+ client.start();
- Path targetPath = detectTargetFolder().toPath();
- Path parentPath = targetPath.getParent();
- Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
- Utils.deleteRecursive(scpRoot);
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
- Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
- Path localOutFile = localDir.resolve(getCurrentTestName() + "-1.txt");
- writeFile(localOutFile, data);
+ ScpClient scp = createScpClient(session);
+ writeFile(localOutFile, data);
- Path remoteDir = scpRoot.resolve("remote");
- Path remoteOutFile = remoteDir.resolve(localOutFile.getFileName());
- assertFalse("Remote folder already exists: " + remoteDir, Files.exists(remoteDir));
-
- String localOutPath = localOutFile.toString();
- String remoteOutPath = Utils.resolveRelativeRemotePath(parentPath, remoteOutFile);
- try {
- scp.upload(localOutPath, remoteOutPath);
- fail("Expected IOException for 1st time " + remoteOutPath);
- } catch(IOException e) {
- // ok
- }
-
- Files.createDirectories(remoteDir);
+ assertFalse("Remote folder already exists: " + remoteDir, Files.exists(remoteDir));
+
+ String localOutPath = localOutFile.toString();
+ String remoteOutPath = Utils.resolveRelativeRemotePath(parentPath, remoteOutFile);
+ try {
scp.upload(localOutPath, remoteOutPath);
- assertFileLength(remoteOutFile, data.length(), 5000);
-
- Path secondLocal = localDir.resolve(localOutFile.getFileName());
- scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, secondLocal));
- assertFileLength(secondLocal, data.length(), 5000);
-
- Path localPath = localDir.resolve(getCurrentTestName() + "-path.txt");
- scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, localPath));
- assertFileLength(localPath, data.length(), 5000);
+ fail("Expected IOException for 1st time " + remoteOutPath);
+ } catch(IOException e) {
+ // ok
}
+
+ assertHierarchyTargetFolderExists(remoteDir);
+ scp.upload(localOutPath, remoteOutPath);
+ assertFileLength(remoteOutFile, data.length(), TimeUnit.SECONDS.toMillis(5L));
+
+ Path secondLocal = localDir.resolve(localOutFile.getFileName());
+ scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, secondLocal));
+ assertFileLength(secondLocal, data.length(), TimeUnit.SECONDS.toMillis(5L));
+
+ Path localPath = localDir.resolve("file-path.txt");
+ scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, localPath));
+ assertFileLength(localPath, data.length(), TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -348,78 +406,76 @@ public class ScpTest extends BaseTestSupport {
try (SshClient client = SshClient.setUpDefaultClient()) {
client.start();
- try {
- try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(5L, TimeUnit.SECONDS);
-
- ScpClient scp = createScpClient(session);
- Path targetPath = detectTargetFolder().toPath();
- Path parentPath = targetPath.getParent();
- Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
- Utils.deleteRecursive(scpRoot);
-
- Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
- Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
- byte[] data = writeFile(local1, getCurrentTestName() + "\n");
-
- Path local2 = localDir.resolve(getCurrentTestName() + "-2.txt");
- Files.write(local2, data);
-
- Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
- Path remote1 = remoteDir.resolve(local1.getFileName());
- String remote1Path = Utils.resolveRelativeRemotePath(parentPath, remote1);
- String[] locals = { local1.toString(), local2.toString() };
- try {
- scp.upload(locals, remote1Path);
- fail("Unexpected upload success to missing remote file: " + remote1Path);
- } catch (IOException e) {
- // Ok
- }
-
- Files.write(remote1, data);
- try {
- scp.upload(locals, remote1Path);
- fail("Unexpected upload success to existing remote file: " + remote1Path);
- } catch (IOException e) {
- // Ok
- }
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
- Path remoteSubDir = assertHierarchyTargetFolderExists(remoteDir.resolve("dir"));
- scp.upload(locals, Utils.resolveRelativeRemotePath(parentPath, remoteSubDir));
-
- Path remoteSub1 = remoteSubDir.resolve(local1.getFileName());
- assertFileLength(remoteSub1, data.length, 5000);
-
- Path remoteSub2 = remoteSubDir.resolve(local2.getFileName());
- assertFileLength(remoteSub2, data.length, 5000);
-
- String[] remotes = {
- Utils.resolveRelativeRemotePath(parentPath, remoteSub1),
- Utils.resolveRelativeRemotePath(parentPath, remoteSub2),
- };
-
- try {
- scp.download(remotes, Utils.resolveRelativeRemotePath(parentPath, local1));
- fail("Unexpected download success to existing local file: " + local1);
- } catch (IOException e) {
- // Ok
- }
-
- Path localSubDir = localDir.resolve("dir");
- try {
- scp.download(remotes, localSubDir);
- fail("Unexpected download success to non-existing folder: " + localSubDir);
- } catch (IOException e) {
- // Ok
- }
+ ScpClient scp = createScpClient(session);
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
+ Utils.deleteRecursive(scpRoot);
- Files.createDirectories(localSubDir);
- scp.download(remotes, localSubDir);
+ Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+ Path local1 = localDir.resolve("file-1.txt");
+ byte[] data = writeFile(local1, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
+
+ Path local2 = localDir.resolve("file-2.txt");
+ Files.write(local2, data);
- assertFileLength(localSubDir.resolve(remoteSub1.getFileName()), data.length, 5000);
- assertFileLength(localSubDir.resolve(remoteSub2.getFileName()), data.length, 5000);
+ Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+ Path remote1 = remoteDir.resolve(local1.getFileName());
+ String remote1Path = Utils.resolveRelativeRemotePath(parentPath, remote1);
+ String[] locals = { local1.toString(), local2.toString() };
+ try {
+ scp.upload(locals, remote1Path);
+ fail("Unexpected upload success to missing remote file: " + remote1Path);
+ } catch (IOException e) {
+ // Ok
+ }
+
+ Files.write(remote1, data);
+ try {
+ scp.upload(locals, remote1Path);
+ fail("Unexpected upload success to existing remote file: " + remote1Path);
+ } catch (IOException e) {
+ // Ok
}
+
+ Path remoteSubDir = assertHierarchyTargetFolderExists(remoteDir.resolve("dir"));
+ scp.upload(locals, Utils.resolveRelativeRemotePath(parentPath, remoteSubDir));
+
+ Path remoteSub1 = remoteSubDir.resolve(local1.getFileName());
+ assertFileLength(remoteSub1, data.length, TimeUnit.SECONDS.toMillis(5L));
+
+ Path remoteSub2 = remoteSubDir.resolve(local2.getFileName());
+ assertFileLength(remoteSub2, data.length, TimeUnit.SECONDS.toMillis(5L));
+
+ String[] remotes = {
+ Utils.resolveRelativeRemotePath(parentPath, remoteSub1),
+ Utils.resolveRelativeRemotePath(parentPath, remoteSub2),
+ };
+
+ try {
+ scp.download(remotes, Utils.resolveRelativeRemotePath(parentPath, local1));
+ fail("Unexpected download success to existing local file: " + local1);
+ } catch (IOException e) {
+ // Ok
+ }
+
+ Path localSubDir = localDir.resolve("dir");
+ try {
+ scp.download(remotes, localSubDir);
+ fail("Unexpected download success to non-existing folder: " + localSubDir);
+ } catch (IOException e) {
+ // Ok
+ }
+
+ assertHierarchyTargetFolderExists(localSubDir);
+ scp.download(remotes, localSubDir);
+
+ assertFileLength(localSubDir.resolve(remoteSub1.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
+ assertFileLength(localSubDir.resolve(remoteSub2.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -443,23 +499,23 @@ public class ScpTest extends BaseTestSupport {
Path localDir = scpRoot.resolve("local");
Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
- Path localSub1 = localSubDir.resolve(getCurrentTestName() + "-1.txt");
- byte[] data = writeFile(localSub1, getCurrentTestName() + "\n");
- Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
+ Path localSub1 = localSubDir.resolve("file-1.txt");
+ byte[] data = writeFile(localSub1, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
+ Path localSub2 = localSubDir.resolve("file-2.txt");
Files.write(localSub2, data);
Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
scp.upload(localSubDir, Utils.resolveRelativeRemotePath(parentPath, remoteDir), ScpClient.Option.Recursive);
Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
- assertFileLength(remoteSubDir.resolve(localSub1.getFileName()), data.length, 5000);
- assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, 5000);
+ assertFileLength(remoteSubDir.resolve(localSub1.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
+ assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
Utils.deleteRecursive(localSubDir);
scp.download(Utils.resolveRelativeRemotePath(parentPath, remoteSubDir), localDir, ScpClient.Option.Recursive);
- assertFileLength(localSub1, data.length, 5000);
- assertFileLength(localSub2, data.length, 5000);
+ assertFileLength(localSub1, data.length, TimeUnit.SECONDS.toMillis(5L));
+ assertFileLength(localSub2, data.length, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -482,22 +538,22 @@ public class ScpTest extends BaseTestSupport {
Utils.deleteRecursive(scpRoot);
Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
- Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
- byte[] data = writeFile(local1, getCurrentTestName() + "\n");
- Path local2 = localDir.resolve(getCurrentTestName() + "-2.txt");
+ Path local1 = localDir.resolve("file-1.txt");
+ byte[] data = writeFile(local1, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
+ Path local2 = localDir.resolve("file-2.txt");
Files.write(local2, data);
Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
scp.upload(localDir.toString() + File.separator + "*", remotePath);
- assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, 5000);
- assertFileLength(remoteDir.resolve(local2.getFileName()), data.length, 5000);
+ assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
+ assertFileLength(remoteDir.resolve(local2.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
Files.delete(local1);
Files.delete(local2);
scp.download(remotePath + "/*", localDir);
- assertFileLength(local1, data.length, 5000);
- assertFileLength(local2, data.length, 5000);
+ assertFileLength(local1, data.length, TimeUnit.SECONDS.toMillis(5L));
+ assertFileLength(local2, data.length, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -521,30 +577,30 @@ public class ScpTest extends BaseTestSupport {
Path localDir = scpRoot.resolve("local");
Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
- Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
- byte[] data = writeFile(local1, getCurrentTestName() + "\n");
- Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
+ Path local1 = localDir.resolve("file-1.txt");
+ byte[] data = writeFile(local1, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
+ Path localSub2 = localSubDir.resolve("file-2.txt");
Files.write(localSub2, data);
Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
scp.upload(localDir.toString() + File.separator + "*", remotePath, ScpClient.Option.Recursive);
- assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, 5000);
+ assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
- assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, 5000);
+ assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, TimeUnit.SECONDS.toMillis(5L));
Files.delete(local1);
Utils.deleteRecursive(localSubDir);
scp.download(remotePath + "/*", localDir);
- assertFileLength(local1, data.length, 5000);
+ assertFileLength(local1, data.length, TimeUnit.SECONDS.toMillis(5L));
assertFalse("Unexpected recursive local file: " + localSub2, Files.exists(localSub2));
Files.delete(local1);
scp.download(remotePath + "/*", localDir, ScpClient.Option.Recursive);
- assertFileLength(local1, data.length, 5000);
- assertFileLength(localSub2, data.length, 5000);
+ assertFileLength(local1, data.length, TimeUnit.SECONDS.toMillis(5L));
+ assertFileLength(localSub2, data.length, TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
}
@@ -570,14 +626,14 @@ public class ScpTest extends BaseTestSupport {
Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
// convert everything to seconds since this is the SCP timestamps granularity
long lastMod = TimeUnit.MILLISECONDS.toSeconds(Files.getLastModifiedTime(localSubDir).toMillis() - TimeUnit.DAYS.toMillis(1));
- Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
- byte[] data = writeFile(local1, getCurrentTestName() + "\n");
+ Path local1 = localDir.resolve("file-1.txt");
+ byte[] data = writeFile(local1, getClass().getName() + "#" + getCurrentTestName() + System.getProperty("line.separator"));
File lclFile1 = local1.toFile();
lclFile1.setLastModified(lastMod);
lclFile1.setExecutable(true, true);
lclFile1.setWritable(false, false);
- Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
+ Path localSub2 = localSubDir.resolve("file-2.txt");
Files.write(localSub2, data);
File lclSubFile2 = localSub2.toFile();
lclSubFile2.setLastModified(lastMod);
@@ -587,25 +643,25 @@ public class ScpTest extends BaseTestSupport {
scp.upload(localDir.toString() + File.separator + "*", remotePath, ScpClient.Option.Recursive, ScpClient.Option.PreserveAttributes);
Path remote1 = remoteDir.resolve(local1.getFileName());
- assertFileLength(remote1, data.length, 5000);
+ assertFileLength(remote1, data.length, TimeUnit.SECONDS.toMillis(5L));
File remFile1 = remote1.toFile();
assertLastModifiedTimeEquals(remFile1, lastMod);
Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
Path remoteSub2 = remoteSubDir.resolve(localSub2.getFileName());
- assertFileLength(remoteSub2, data.length, 5000);
+ assertFileLength(remoteSub2, data.length, TimeUnit.SECONDS.toMillis(5L));
File remSubFile2 = remoteSub2.toFile();
assertLastModifiedTimeEquals(remSubFile2, lastMod);
Utils.deleteRecursive(localDir);
- Files.createDirectories(localDir);
+ assertHierarchyTargetFolderExists(localDir);
scp.download(remotePath + "/*", localDir, ScpClient.Option.Recursive, ScpClient.Option.PreserveAttributes);
- assertFileLength(local1, data.length, 5000);
+ assertFileLength(local1, data.length, TimeUnit.SECONDS.toMillis(5L));
assertLastModifiedTimeEquals(lclFile1, lastMod);
- assertFileLength(localSub2, data.length, 5000);
+ assertFileLength(localSub2, data.length, TimeUnit.SECONDS.toMillis(5L));
assertLastModifiedTimeEquals(lclSubFile2, lastMod);
} finally {
client.stop();
@@ -629,7 +685,7 @@ public class ScpTest extends BaseTestSupport {
Utils.deleteRecursive(scpRoot);
Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
- Path remoteFile = remoteDir.resolve(getCurrentTestName() + ".txt");
+ Path remoteFile = remoteDir.resolve("file.txt");
String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
byte[] data = (getClass().getName() + "#" + getCurrentTestName()).getBytes(StandardCharsets.UTF_8);
scp.upload(data, remotePath, EnumSet.allOf(PosixFilePermission.class), null);
@@ -687,12 +743,12 @@ public class ScpTest extends BaseTestSupport {
target.delete();
assertFalse(target.exists());
sendFile(unixPath, fileName, data);
- assertFileLength(target, data.length(), 5000);
+ assertFileLength(target, data.length(), TimeUnit.SECONDS.toMillis(5L));
target.delete();
assertFalse(target.exists());
sendFile(unixDir, fileName, data);
- assertFileLength(target, data.length(), 5000);
+ assertFileLength(target, data.length(), TimeUnit.SECONDS.toMillis(5L));
sendFileError("target", ScpHelper.SCP_COMMAND_PREFIX, data);
@@ -705,7 +761,7 @@ public class ScpTest extends BaseTestSupport {
root.delete();
sendDir("target", ScpHelper.SCP_COMMAND_PREFIX, fileName, data);
- assertFileLength(target, data.length(), 5000);
+ assertFileLength(target, data.length(), TimeUnit.SECONDS.toMillis(5L));
} finally {
session.disconnect();
}
@@ -721,7 +777,7 @@ public class ScpTest extends BaseTestSupport {
byte[] expected = (getClass().getName() + "#" + getCurrentTestName()).getBytes(StandardCharsets.UTF_8);
Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
- String fileName = getCurrentTestName() + ".txt";
+ String fileName = "file.txt";
Path remoteFile = remoteDir.resolve(fileName);
String mode = ScpHelper.getOctalPermissions(EnumSet.of(
PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_WRITE,
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
index 02f2068..aee7420 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
@@ -147,9 +147,9 @@ public class SftpFileSystemTest extends BaseTestSupport {
Path parentPath = targetPath.getParent();
Path clientFolder = lclSftp.resolve("client");
- String remFilePath = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve(getCurrentTestName() + ".txt"));
+ String remFilePath = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve("file.txt"));
Path file = fs.getPath(remFilePath);
- Files.createDirectories(file.getParent());
+ assertHierarchyTargetFolderExists(file.getParent());
Files.write(file, (getCurrentTestName() + "\n").getBytes(StandardCharsets.UTF_8));
Map<String, Object> attrs = Files.readAttributes(file, "posix:*");
@@ -183,10 +183,10 @@ public class SftpFileSystemTest extends BaseTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path rootNative = targetPath.resolve("root").toAbsolutePath();
Utils.deleteRecursive(rootNative);
- Files.createDirectories(rootNative);
+ assertHierarchyTargetFolderExists(rootNative);
try(FileSystem fs = FileSystems.newFileSystem(URI.create("root:" + rootNative.toUri().toString() + "!/"), null)) {
- Path dir = Files.createDirectories(fs.getPath("test/foo"));
+ Path dir = assertHierarchyTargetFolderExists(fs.getPath("test/foo"));
System.out.println("Created " + dir);
}
}
@@ -341,9 +341,9 @@ public class SftpFileSystemTest extends BaseTestSupport {
Path parentPath = targetPath.getParent();
Path clientFolder = lclSftp.resolve("client");
- String remFile1Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve(getCurrentTestName() + "-1.txt"));
+ String remFile1Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve("file-1.txt"));
Path file1 = fs.getPath(remFile1Path);
- Files.createDirectories(file1.getParent());
+ assertHierarchyTargetFolderExists(file1.getParent());
String expected="Hello world: " + getCurrentTestName();
{
@@ -352,9 +352,9 @@ public class SftpFileSystemTest extends BaseTestSupport {
assertEquals("Mismatched read test data", expected, buf);
}
- String remFile2Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve(getCurrentTestName() + "-2.txt"));
+ String remFile2Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve("file-2.txt"));
Path file2 = fs.getPath(remFile2Path);
- String remFile3Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve(getCurrentTestName() + "-3.txt"));
+ String remFile3Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve("file-3.txt"));
Path file3 = fs.getPath(remFile3Path);
try {
Files.move(file2, file3);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5da0d1a8/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
index 81d1525..d39a6f3 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
@@ -113,23 +113,115 @@ public class SftpTest extends AbstractSftpClientTestSupport {
}
@Test
- public void testOpen() throws Exception {
+ public void testNormalizeRemoteRootValues() throws Exception {
+ try(SshClient client = SshClient.setUpDefaultClient()) {
+ client.start();
+
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ try(SftpClient sftp = session.createSftpClient()) {
+ StringBuilder sb = new StringBuilder(Long.SIZE + 1);
+ String expected = sftp.canonicalPath("/");
+ for (int i = 0; i < Long.SIZE; i++) {
+ if (sb.length() > 0) {
+ sb.setLength(0);
+ }
+
+ for (int j = 1; j <= i; j++) {
+ sb.append('/');
+ }
+
+ String remotePath = sb.toString();
+ String actual = sftp.canonicalPath(remotePath);
+ assertEquals("Mismatched roots for " + remotePath.length() + " slashes", expected, actual);
+ }
+ }
+ } finally {
+ client.stop();
+ }
+ }
+ }
+
+ @Test
+ public void testNormalizeRemotePathsValues() throws Exception {
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
+
+ Path testFile = assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
+
+ String file = Utils.resolveRelativeRemotePath(parentPath, testFile);
+ String[] comps = GenericUtils.split(file, '/');
try(SshClient client = SshClient.setUpDefaultClient()) {
client.start();
+ Factory<? extends Random> factory = client.getRandomFactory();
+ Random rnd = factory.create();
try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
session.addPasswordIdentity(getCurrentTestName());
session.auth().verify(5L, TimeUnit.SECONDS);
- Path targetPath = detectTargetFolder().toPath();
- Path parentPath = targetPath.getParent();
- Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
- Path clientFolder = lclSftp.resolve("client");
- Path testFile = clientFolder.resolve(getCurrentTestName() + ".txt");
- String file = Utils.resolveRelativeRemotePath(parentPath, testFile);
+ try(SftpClient sftp = session.createSftpClient()) {
+ StringBuilder sb = new StringBuilder(file.length() + comps.length);
+ String expected = sftp.canonicalPath(file);
+ for (int i = 0; i < file.length(); i++) {
+ if (sb.length() > 0) {
+ sb.setLength(0);
+ }
+
+ sb.append(comps[0]);
+ for (int j = 1; j < comps.length; j++) {
+ String name = comps[j];
+ slashify(sb, rnd);
+ sb.append(name);
+ }
+ slashify(sb, rnd);
+
+ if (rnd.random(Byte.SIZE) < (Byte.SIZE / 2)) {
+ sb.append('.');
+ }
+
+ String remotePath = sb.toString();
+ String actual = sftp.canonicalPath(remotePath);
+ assertEquals("Mismatched canonical value for " + remotePath, expected, actual);
+ }
+ }
+ } finally {
+ client.stop();
+ }
+ }
+ }
+
+ private static int slashify(StringBuilder sb, Random rnd) {
+ int slashes = 1 /* at least one slash */ + rnd.random(Byte.SIZE);
+ for (int k=0; k < slashes; k++) {
+ sb.append('/');
+ }
+
+ return slashes;
+ }
+
+ @Test
+ public void testOpen() throws Exception {
+ Path targetPath = detectTargetFolder().toPath();
+ Path parentPath = targetPath.getParent();
+ Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
+ Path clientFolder = lclSftp.resolve("client");
+ Path testFile = clientFolder.resolve("file.txt");
+ String file = Utils.resolveRelativeRemotePath(parentPath, testFile);
+
+ File javaFile = testFile.toFile();
+ assertHierarchyTargetFolderExists(javaFile.getParentFile());
+
+ try(SshClient client = SshClient.setUpDefaultClient()) {
+ client.start();
+
+ try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
- File javaFile = testFile.toFile();
- assertHierarchyTargetFolderExists(javaFile.getParentFile());
javaFile.createNewFile();
javaFile.setWritable(false, false);
javaFile.setReadable(false, false);
@@ -249,10 +341,9 @@ public class SftpTest extends AbstractSftpClientTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
Path parentPath = targetPath.getParent();
- Path clientFolder = lclSftp.resolve("client");
+ Path clientFolder = assertHierarchyTargetFolderExists(lclSftp).resolve("client");
String dir = Utils.resolveRelativeRemotePath(parentPath, clientFolder);
try(SftpClient sftp = session.createSftpClient()) {
@@ -349,9 +440,8 @@ public class SftpTest extends AbstractSftpClientTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
- Path target = lclSftp.resolve(getCurrentTestName() + ".txt");
+ Path target = assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), target);
final int NUM_ITERATIONS=10;
@@ -376,9 +466,8 @@ public class SftpTest extends AbstractSftpClientTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
- Path localPath = lclSftp.resolve(getCurrentTestName() + ".txt");
+ Path localPath = assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), localPath);
String data = getCurrentTestName();
String extraData = "@" + getClass().getSimpleName();
@@ -425,35 +514,10 @@ public class SftpTest extends AbstractSftpClientTestSupport {
}
@Test
- public void testRealPath() throws Exception {
- ChannelSftp c = (ChannelSftp) session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
- c.connect();
-
- try {
- URI url = getClass().getClassLoader().getResource(SshClient.class.getName().replace('.', '/') + ".class").toURI();
- URI base = new File(System.getProperty("user.dir")).getAbsoluteFile().toURI();
- String path = new File(base.relativize(url).getPath()).getParent() + "/";
- path = path.replace('\\', '/');
- String real = c.realpath(path);
- System.out.println(real);
- try {
- real = c.realpath(path + "/foobar");
- System.out.println(real);
- fail("Expected SftpException");
- } catch (com.jcraft.jsch.SftpException e) {
- // ok
- }
- } finally {
- c.disconnect();
- }
- }
-
- @Test
public void testRename() throws Exception {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
Path parentPath = targetPath.getParent();
Path clientFolder = assertHierarchyTargetFolderExists(lclSftp.resolve("client"));
@@ -466,15 +530,15 @@ public class SftpTest extends AbstractSftpClientTestSupport {
session.auth().verify(5L, TimeUnit.SECONDS);
try(SftpClient sftp = session.createSftpClient()) {
- Path file1 = clientFolder.resolve(getCurrentTestName() + "-1.txt");
+ Path file1 = clientFolder.resolve("file-1.txt");
String file1Path = Utils.resolveRelativeRemotePath(parentPath, file1);
try (OutputStream os = sftp.write(file1Path, SftpClient.MIN_WRITE_BUFFER_SIZE)) {
os.write((getCurrentTestName() + "\n").getBytes(StandardCharsets.UTF_8));
}
- Path file2 = clientFolder.resolve(getCurrentTestName() + "-2.txt");
+ Path file2 = clientFolder.resolve("file-2.txt");
String file2Path = Utils.resolveRelativeRemotePath(parentPath, file2);
- Path file3 = clientFolder.resolve(getCurrentTestName() + "-3.txt");
+ Path file3 = clientFolder.resolve("file-3.txt");
String file3Path = Utils.resolveRelativeRemotePath(parentPath, file3);
try {
sftp.rename(file2Path, file3Path);
@@ -507,10 +571,9 @@ public class SftpTest extends AbstractSftpClientTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
byte[] data = (getClass().getName() + "#" + getCurrentTestName()).getBytes(StandardCharsets.UTF_8);
- Path srcFile = lclSftp.resolve("src.txt");
+ Path srcFile = assertHierarchyTargetFolderExists(lclSftp).resolve("src.txt");
Files.write(srcFile, data, IoUtils.EMPTY_OPEN_OPTIONS);
Path parentPath = targetPath.getParent();
@@ -661,12 +724,11 @@ public class SftpTest extends AbstractSftpClientTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
Path parentPath = targetPath.getParent();
- Path clientFolder = lclSftp.resolve("client");
+ Path clientFolder = assertHierarchyTargetFolderExists(lclSftp).resolve("client");
String dir = Utils.resolveRelativeRemotePath(parentPath, clientFolder);
- String file = dir + "/" + getCurrentTestName() + ".txt";
+ String file = dir + "/" + "file.txt";
sftp.mkdir(dir);
@@ -759,10 +821,9 @@ public class SftpTest extends AbstractSftpClientTestSupport {
Path targetPath = detectTargetFolder().toPath();
Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
Utils.deleteRecursive(lclSftp);
- Files.createDirectories(lclSftp);
Path parentPath = targetPath.getParent();
- Path sourcePath = lclSftp.resolve(getCurrentTestName() + ".txt");
+ Path sourcePath = assertHierarchyTargetFolderExists(lclSftp).resolve("src.txt");
String remSrcPath = Utils.resolveRelativeRemotePath(parentPath, sourcePath);
Path linkPath = lclSftp.resolve("link-" + sourcePath.getFileName());
String remLinkPath = Utils.resolveRelativeRemotePath(parentPath, linkPath);