Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class DataDir {
@Deprecated
private static final String WORKSPACE_PROPERTY = "workspace";
public static final String ENV_VAR = "DEEPHAVEN_DATA_DIR";
public static final String WINDOWS_SEPARATOR = "\\";

private static final String DEFAULT_DATA_DIR = ".";

Expand Down
34 changes: 29 additions & 5 deletions server/src/main/java/io/deephaven/server/notebook/FilesystemStorageServiceGrpcImpl.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.google.rpc.Code;
import io.deephaven.configuration.Configuration;
import io.deephaven.configuration.DataDir;
import io.deephaven.extensions.barrage.util.GrpcUtil;
import io.deephaven.internal.log.LoggerFactory;
import io.deephaven.io.logger.Logger;
import io.deephaven.proto.backplane.grpc.CreateDirectoryRequest;
Expand Down Expand Up @@ -92,6 +91,11 @@ public class FilesystemStorageServiceGrpcImpl extends StorageServiceGrpc.Storage
*/
@Deprecated
private static final String REQUIRED_PATH_PREFIX = "/";
/**
* Although REQUIRED_PATH_PREFIX has been deprecated, it is still used; this constant is for the same forward slash,
* to detect situations where the UI path separator is different from the OS path separator (i.e. on Windows).
*/
private static final String LINUX_SEPARATOR = "/";

private final Path root = Paths.get(STORAGE_PATH).normalize();
private final SessionService sessionService;
Expand All @@ -114,14 +118,19 @@ public FilesystemStorageServiceGrpcImpl(
}

private Path resolveOrThrow(String incomingPath) {
if (incomingPath.startsWith(File.separator)) {
String resolveDetails = "\nOriginal incoming path is: " + incomingPath;
resolveDetails = resolveDetails + "\nFile separator is: " + File.separator;
incomingPath = maybeReplaceFileSeparators(incomingPath);
while (incomingPath.startsWith(REQUIRED_PATH_PREFIX)) {
incomingPath = incomingPath.substring(1);
}
Path resolved = root.resolve(incomingPath).normalize();

if (resolved.startsWith(root)) {
return resolved;
}
throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, "Invalid path: " + incomingPath);
throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, "Invalid path: " + incomingPath
+ "." + resolveDetails);
}

private void requireNotRoot(Path path, String message) {
Expand All @@ -130,6 +139,20 @@ private void requireNotRoot(Path path, String message) {
}
}

/**
* On Windows systems, we need to replace backslashes with forward slashes for the Web UI
*
* @param path Path String that may need to be modified
* @return Original path on non-Windows systems, or path with backslashes replaced with slashes on Windows systems.
*/
private String maybeReplaceFileSeparators(final String path) {
if (File.separator.equals(DataDir.WINDOWS_SEPARATOR)) {
return path.replace(DataDir.WINDOWS_SEPARATOR, LINUX_SEPARATOR);
} else {
return path;
}
}

@Override
public void listItems(
@NotNull final ListItemsRequest request,
Expand All @@ -148,8 +171,9 @@ public void listItems(
}
BasicFileAttributes attrs = Files.readAttributes(p, BasicFileAttributes.class);
boolean isDirectory = attrs.isDirectory();
String relativePath = maybeReplaceFileSeparators(root.relativize(p).toString());
ItemInfo.Builder info = ItemInfo.newBuilder()
.setPath(REQUIRED_PATH_PREFIX + root.relativize(p));
.setPath(REQUIRED_PATH_PREFIX + relativePath);
if (isDirectory) {
info.setType(ItemType.DIRECTORY);
} else {
Expand All @@ -172,7 +196,7 @@ private static PathMatcher createPathFilter(String filterGlob) {
if (filterGlob.contains("**")) {
throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, "Bad glob, only single `*`s are supported");
}
if (filterGlob.contains(File.separator)) {
if (filterGlob.contains(File.separator) || filterGlob.contains(LINUX_SEPARATOR)) {
throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT,
"Bad glob, only the same directory can be checked");
}
Expand Down
16 changes: 12 additions & 4 deletions server/src/main/java/io/deephaven/server/runner/MainHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import io.deephaven.util.process.ProcessEnvironment;
import org.jetbrains.annotations.NotNull;
import org.slf4j.bridge.SLF4JBridgeHandler;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -63,6 +63,14 @@ private static void bootstrapFromFile(Path configFile) throws IOException {
}
}

// Spaces in the paths are tedious on Windows
private static String maybeRemoveSpaces(final String pathToCheck) {
if (pathToCheck == null) {
return null;
}
return (File.separator.equals(DataDir.WINDOWS_SEPARATOR)) ? pathToCheck.replace(" ", "") : pathToCheck;
}

@VisibleForTesting
public static void bootstrapProjectDirectories() throws IOException {
final String applicationName =
Expand All @@ -72,9 +80,9 @@ public static void bootstrapProjectDirectories() throws IOException {
final dev.dirs.ProjectDirectories defaultDirectories =
dev.dirs.ProjectDirectories.from("io", "Deephaven Data Labs", applicationName);

final Path cacheDir = CacheDir.getOrSet(defaultDirectories.cacheDir);
final Path configDir = ConfigDir.getOrSet(defaultDirectories.configDir);
final Path dataDir = DataDir.getOrSet(defaultDirectories.dataDir);
final Path cacheDir = CacheDir.getOrSet(maybeRemoveSpaces(defaultDirectories.cacheDir));
final Path configDir = ConfigDir.getOrSet(maybeRemoveSpaces(defaultDirectories.configDir));
final Path dataDir = DataDir.getOrSet(maybeRemoveSpaces(defaultDirectories.dataDir));

Files.createDirectories(cacheDir);
Files.createDirectories(dataDir);
Expand Down
Loading