From 389c49d846c866e8e5702f73a4502581ced418f3 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sun, 27 Dec 2015 21:53:50 +0100 Subject: [PATCH] PUT and MKCOL support. Simplified paths (utilizing a servlet filter to make sure, directory paths always end on "/" while file paths don't). --- .../webdav/filters/AcceptRangeFilter.java | 38 +++++++++ .../webdav/filters/HttpFilter.java | 26 +++++++ .../filters/UriNormalizationFilter.java | 77 ++++++++++++++++++ .../webdav/jackrabbit/DavFile.java | 6 +- .../webdav/jackrabbit/DavFolder.java | 43 ++++++++-- .../webdav/jackrabbit/DavNode.java | 23 +++--- ...ocatorFactory.java => DavPathFactory.java} | 78 ++++++++++++++----- .../jackrabbit/FilesystemResourceFactory.java | 28 ++++--- .../webdav/jackrabbit/WebDavServlet.java | 2 +- .../jackrabbit/InMemoryWebDavServer.java | 7 ++ 10 files changed, 275 insertions(+), 53 deletions(-) create mode 100644 main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/AcceptRangeFilter.java create mode 100644 main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/HttpFilter.java create mode 100644 main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/UriNormalizationFilter.java rename main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/{IdentityLocatorFactory.java => DavPathFactory.java} (57%) diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/AcceptRangeFilter.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/AcceptRangeFilter.java new file mode 100644 index 000000000..34dff9d18 --- /dev/null +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/AcceptRangeFilter.java @@ -0,0 +1,38 @@ +package org.cryptomator.webdav.filters; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Adds an Accept-Range: bytes header to all GET requests. + */ +public class AcceptRangeFilter implements HttpFilter { + + private static final String METHOD_GET = "GET"; + private static final String HEADER_ACCEPT_RANGES = "Accept-Ranges"; + private static final String HEADER_ACCEPT_RANGE_VALUE = "bytes"; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // no-op + } + + @Override + public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + if (METHOD_GET.equalsIgnoreCase(request.getMethod())) { + response.addHeader(HEADER_ACCEPT_RANGES, HEADER_ACCEPT_RANGE_VALUE); + } + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // no-op + } + +} diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/HttpFilter.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/HttpFilter.java new file mode 100644 index 000000000..9f1d0797c --- /dev/null +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/HttpFilter.java @@ -0,0 +1,26 @@ +package org.cryptomator.webdav.filters; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +interface HttpFilter extends Filter { + + @Override + default void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { + doFilterHttp((HttpServletRequest) request, (HttpServletResponse) response, chain); + } else { + chain.doFilter(request, response); + } + } + + void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException; + +} diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/UriNormalizationFilter.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/UriNormalizationFilter.java new file mode 100644 index 000000000..785e8f1bf --- /dev/null +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/filters/UriNormalizationFilter.java @@ -0,0 +1,77 @@ +package org.cryptomator.webdav.filters; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +/** + * Depending on the HTTP method a "/" is added to or removed from the end of an URI. + * For example MKCOL creates a directory (ending on "/"), while PUT creates a file (not ending on "/"). + */ +public class UriNormalizationFilter implements HttpFilter { + + private static final String[] FILE_METHODS = {"PUT"}; + private static final String[] DIRECTORY_METHODS = {"MKCOL"}; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // no-op + } + + @Override + public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + if (ArrayUtils.contains(FILE_METHODS, request.getMethod().toUpperCase())) { + chain.doFilter(new FileUriRequest(request), response); + } else if (ArrayUtils.contains(DIRECTORY_METHODS, request.getMethod().toUpperCase())) { + chain.doFilter(new DirectoryUriRequest(request), response); + } else { + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + // no-op + } + + /** + * HTTP request, whose URI never ends on "/". + */ + private static class FileUriRequest extends HttpServletRequestWrapper { + + public FileUriRequest(HttpServletRequest request) { + super(request); + } + + @Override + public String getRequestURI() { + return StringUtils.removeEnd(super.getRequestURI(), "/"); + } + + } + + /** + * HTTP request, whose URI always ends on "/". + */ + private static class DirectoryUriRequest extends HttpServletRequestWrapper { + + public DirectoryUriRequest(HttpServletRequest request) { + super(request); + } + + @Override + public String getRequestURI() { + return StringUtils.appendIfMissing(super.getRequestURI(), "/"); + } + + } + +} diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFile.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFile.java index 3eb96adfa..12cbb1857 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFile.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFile.java @@ -17,7 +17,6 @@ import java.time.Instant; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavResource; import org.apache.jackrabbit.webdav.DavResourceIterator; -import org.apache.jackrabbit.webdav.DavResourceLocator; import org.apache.jackrabbit.webdav.DavSession; import org.apache.jackrabbit.webdav.io.InputContext; import org.apache.jackrabbit.webdav.io.OutputContext; @@ -25,11 +24,12 @@ import org.apache.jackrabbit.webdav.lock.LockManager; import org.cryptomator.filesystem.File; import org.cryptomator.filesystem.ReadableFile; import org.cryptomator.filesystem.WritableFile; +import org.cryptomator.webdav.jackrabbit.DavPathFactory.DavPath; class DavFile extends DavNode { - public DavFile(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, DavResourceLocator locator, File node) { - super(factory, lockManager, session, locator, node); + public DavFile(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, DavPath path, File node) { + super(factory, lockManager, session, path, node); } @Override diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFolder.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFolder.java index 132092699..29c0d5f61 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFolder.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavFolder.java @@ -9,6 +9,11 @@ package org.cryptomator.webdav.jackrabbit; import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; import java.time.Instant; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -17,7 +22,6 @@ import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavResource; import org.apache.jackrabbit.webdav.DavResourceIterator; import org.apache.jackrabbit.webdav.DavResourceIteratorImpl; -import org.apache.jackrabbit.webdav.DavResourceLocator; import org.apache.jackrabbit.webdav.DavSession; import org.apache.jackrabbit.webdav.io.InputContext; import org.apache.jackrabbit.webdav.io.OutputContext; @@ -27,11 +31,14 @@ import org.apache.jackrabbit.webdav.property.DefaultDavProperty; import org.apache.jackrabbit.webdav.property.ResourceType; import org.cryptomator.filesystem.File; import org.cryptomator.filesystem.Folder; +import org.cryptomator.filesystem.FolderCreateMode; +import org.cryptomator.filesystem.WritableFile; +import org.cryptomator.webdav.jackrabbit.DavPathFactory.DavPath; class DavFolder extends DavNode { - public DavFolder(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, DavResourceLocator locator, Folder folder) { - super(factory, lockManager, session, locator, folder); + public DavFolder(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, DavPath path, Folder folder) { + super(factory, lockManager, session, path, folder); properties.add(new ResourceType(ResourceType.COLLECTION)); properties.add(new DefaultDavProperty(DavPropertyName.ISCOLLECTION, 1)); } @@ -48,8 +55,30 @@ class DavFolder extends DavNode { @Override public void addMember(DavResource resource, InputContext inputContext) throws DavException { - // TODO Auto-generated method stub + if (resource instanceof DavFolder) { + addMemberFolder((DavFolder) resource); + } else if (resource instanceof DavFile) { + addMemberFile((DavFile) resource, inputContext.getInputStream()); + } else { + throw new IllegalArgumentException("Unsupported resource type: " + resource.getClass().getName()); + } + } + private void addMemberFolder(DavFolder memberFolder) { + node.folder(memberFolder.getDisplayName()).create(FolderCreateMode.FAIL_IF_PARENT_IS_MISSING); + } + + private void addMemberFile(DavFile memberFile, InputStream inputStream) { + try (ReadableByteChannel src = Channels.newChannel(inputStream); WritableFile dst = node.file(memberFile.getDisplayName()).openWritable()) { + ByteBuffer buf = ByteBuffer.allocate(1337); + while (src.read(buf) != -1) { + buf.flip(); + dst.write(buf); + buf.clear(); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } } @Override @@ -60,14 +89,12 @@ class DavFolder extends DavNode { } private DavFolder getMemberFolder(Folder memberFolder) { - final String subFolderResourcePath = locator.getResourcePath() + memberFolder.name() + '/'; - final DavResourceLocator subFolderLocator = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), subFolderResourcePath); + final DavPath subFolderLocator = path.getChild(memberFolder.name() + '/'); return factory.createFolder(memberFolder, subFolderLocator, session); } private DavFile getMemberFile(File memberFile) { - final String subFolderResourcePath = locator.getResourcePath() + memberFile.name(); - final DavResourceLocator subFolderLocator = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), subFolderResourcePath); + final DavPath subFolderLocator = path.getChild(memberFile.name()); return factory.createFile(memberFile, subFolderLocator, session); } diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavNode.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavNode.java index 340f0654d..3a1179e9d 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavNode.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavNode.java @@ -14,7 +14,6 @@ import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; -import org.apache.commons.io.FilenameUtils; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavResource; import org.apache.jackrabbit.webdav.DavResourceLocator; @@ -31,6 +30,7 @@ import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; import org.apache.jackrabbit.webdav.property.DavPropertySet; import org.apache.jackrabbit.webdav.property.PropEntry; import org.cryptomator.filesystem.Node; +import org.cryptomator.webdav.jackrabbit.DavPathFactory.DavPath; abstract class DavNode implements DavResource { @@ -41,15 +41,15 @@ abstract class DavNode implements DavResource { protected final FilesystemResourceFactory factory; protected final LockManager lockManager; protected final DavSession session; - protected final DavResourceLocator locator; + protected final DavPath path; protected final T node; protected final DavPropertySet properties; - public DavNode(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, DavResourceLocator locator, T node) { + public DavNode(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, DavPath path, T node) { this.factory = factory; this.lockManager = lockManager; this.session = session; - this.locator = locator; + this.path = path; this.node = node; this.properties = new DavPropertySet(); } @@ -76,17 +76,17 @@ abstract class DavNode implements DavResource { @Override public DavResourceLocator getLocator() { - return locator; + return path; } @Override public String getResourcePath() { - return locator.getResourcePath(); + return path.getResourcePath(); } @Override public String getHref() { - return locator.getHref(this.isCollection()); + return path.getHref(); } @Override @@ -157,16 +157,15 @@ abstract class DavNode implements DavResource { @Override public DavResource getCollection() { - if (locator.isRootLocation()) { + if (path.isRootLocation()) { return null; } - final String parentResource = FilenameUtils.getPathNoEndSeparator(locator.getResourcePath()); - final DavResourceLocator parentLocator = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), parentResource); + final DavPath parentPath = path.getParent(); try { - return factory.createResource(parentLocator, session); + return factory.createResource(parentPath, session); } catch (DavException e) { - throw new IllegalStateException("Unable to get parent resource with path " + parentLocator.getResourcePath(), e); + throw new IllegalStateException("Unable to get parent resource with path " + parentPath, e); } } diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/IdentityLocatorFactory.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavPathFactory.java similarity index 57% rename from main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/IdentityLocatorFactory.java rename to main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavPathFactory.java index ca0895db6..86fc03709 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/IdentityLocatorFactory.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/DavPathFactory.java @@ -19,45 +19,78 @@ import org.apache.jackrabbit.webdav.util.EncodeUtil; /** * A LocatorFactory constructing Locators, whose {@link DavResourceLocator#getResourcePath() resourcePath} and {@link DavResourceLocator#getRepositoryPath() repositoryPath} are equal. * These paths will be plain, case-sensitive, absolute, unencoded Strings with Unix-style path separators. + * + * Paths ending on "/" are treated as directory paths and all others as file paths. */ -class IdentityLocatorFactory implements DavLocatorFactory { +class DavPathFactory implements DavLocatorFactory { private final String pathPrefix; - public IdentityLocatorFactory(URI contextRootUri) { + public DavPathFactory(URI contextRootUri) { this.pathPrefix = StringUtils.removeEnd(contextRootUri.toString(), "/"); } @Override - public DavResourceLocator createResourceLocator(String prefix, String href) { + public DavPath createResourceLocator(String prefix, String href) { final String fullPrefix = StringUtils.removeEnd(prefix, "/"); final String remainingHref = StringUtils.removeStart(href, fullPrefix); final String unencodedRemaingingHref = EncodeUtil.unescape(remainingHref); - assert unencodedRemaingingHref.startsWith("/"); - return new IdentityLocator(unencodedRemaingingHref); + return new DavPath(unencodedRemaingingHref); } @Override - public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String resourcePath) { - assert resourcePath.startsWith("/"); - return new IdentityLocator(resourcePath); + public DavPath createResourceLocator(String prefix, String workspacePath, String resourcePath) { + return createResourceLocator(prefix, workspacePath, resourcePath, true); } @Override - public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String path, boolean isResourcePath) { - assert path.startsWith("/"); - return new IdentityLocator(path); + public DavPath createResourceLocator(String prefix, String workspacePath, String path, boolean isResourcePath) { + return new DavPath(path); } - private class IdentityLocator implements DavResourceLocator { + public class DavPath implements DavResourceLocator { private final String absPath; - private IdentityLocator(String absPath) { + private DavPath(String absPath) { assert absPath.startsWith("/"); this.absPath = FilenameUtils.normalize(absPath, true); } + /** + * @return true if the path ends on "/". + */ + public boolean isDirectory() { + return absPath.endsWith("/"); + } + + /** + * @return Parent DavPath or null if this is the root node. + */ + public DavPath getParent() { + if (isRootLocation()) { + return null; + } else { + final String parentPath = FilenameUtils.getFullPath(FilenameUtils.normalizeNoEndSeparator(absPath, true)); + return createResourceLocator(getPrefix(), getWorkspacePath(), parentPath); + } + } + + /** + * Get the path of a child resource, consisting of curren path + child path. + * If the child path ends on "/", the returned DavPath will be a directory path. + * + * @return Child path + */ + public DavPath getChild(String relativeChildPath) { + if (isDirectory()) { + final String absChildPath = absPath + StringUtils.removeStart(relativeChildPath, "/"); + return createResourceLocator(getPrefix(), getWorkspacePath(), absChildPath); + } else { + throw new UnsupportedOperationException("Can only resolve subpaths of a path representing a directory"); + } + } + @Override public String getPrefix() { return pathPrefix; @@ -88,13 +121,20 @@ class IdentityLocatorFactory implements DavLocatorFactory { return false; } + /** + * @see #getHref(boolean) + */ + public String getHref() { + return getHref(isDirectory()); + } + @Override public String getHref(boolean isCollection) { final String encodedResourcePath = EncodeUtil.escapePath(absPath); if (isRootLocation()) { return pathPrefix + "/"; } else { - assert isCollection ? encodedResourcePath.endsWith("/") : true; + assert isCollection ? isDirectory() : true; return pathPrefix + encodedResourcePath; } } @@ -105,8 +145,8 @@ class IdentityLocatorFactory implements DavLocatorFactory { } @Override - public DavLocatorFactory getFactory() { - return IdentityLocatorFactory.this; + public DavPathFactory getFactory() { + return DavPathFactory.this; } @Override @@ -116,7 +156,7 @@ class IdentityLocatorFactory implements DavLocatorFactory { @Override public String toString() { - return "Locator: " + absPath + " (Prefix: " + pathPrefix + ")"; + return "[" + pathPrefix + "]" + absPath; } @Override @@ -126,8 +166,8 @@ class IdentityLocatorFactory implements DavLocatorFactory { @Override public boolean equals(Object obj) { - if (obj instanceof IdentityLocator) { - final IdentityLocator other = (IdentityLocator) obj; + if (obj instanceof DavPath) { + final DavPath other = (DavPath) obj; final boolean samePrefix = this.getPrefix() == null && other.getPrefix() == null || this.getPrefix().equals(other.getPrefix()); final boolean sameRelativeCleartextPath = this.absPath == null && other.absPath == null || this.absPath.equals(other.absPath); return samePrefix && sameRelativeCleartextPath; diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/FilesystemResourceFactory.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/FilesystemResourceFactory.java index 5811264e2..c1869c98e 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/FilesystemResourceFactory.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/FilesystemResourceFactory.java @@ -26,6 +26,7 @@ import org.cryptomator.filesystem.File; import org.cryptomator.filesystem.FileSystem; import org.cryptomator.filesystem.Folder; import org.cryptomator.filesystem.Node; +import org.cryptomator.webdav.jackrabbit.DavPathFactory.DavPath; class FilesystemResourceFactory implements DavResourceFactory { @@ -47,22 +48,29 @@ class FilesystemResourceFactory implements DavResourceFactory { @Override public DavResource createResource(DavResourceLocator locator, DavSession session) throws DavException { - final String path = locator.getResourcePath(); - if (path.endsWith("/")) { - Folder folder = this.resolve(path, FOLDER); - return createFolder(folder, locator, session); + if (locator instanceof DavPath) { + return createResource((DavPath) locator, session); } else { - File file = this.resolve(path, FILE); - return createFile(file, locator, session); + throw new IllegalArgumentException("Unsupported locator type " + locator.getClass().getName()); } } - DavFolder createFolder(Folder folder, DavResourceLocator locator, DavSession session) { - return new DavFolder(this, lockManager, session, locator, folder); + private DavResource createResource(DavPath path, DavSession session) throws DavException { + if (path.isDirectory()) { + Folder folder = this.resolve(path.getResourcePath(), FOLDER); + return createFolder(folder, path, session); + } else { + File file = this.resolve(path.getResourcePath(), FILE); + return createFile(file, path, session); + } } - public DavFile createFile(File file, DavResourceLocator locator, DavSession session) { - return new DavFile(this, lockManager, session, locator, file); + DavFolder createFolder(Folder folder, DavPath path, DavSession session) { + return new DavFolder(this, lockManager, session, path, folder); + } + + DavFile createFile(File file, DavPath path, DavSession session) { + return new DavFile(this, lockManager, session, path, file); } private T resolve(String path, Class expectedNodeType) { diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/WebDavServlet.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/WebDavServlet.java index 533479601..2dc991484 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/WebDavServlet.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbit/WebDavServlet.java @@ -28,7 +28,7 @@ public class WebDavServlet extends AbstractWebdavServlet { public WebDavServlet(URI contextRootUri, FileSystem filesystem) { davSessionProvider = new DavSessionProviderImpl(); - davLocatorFactory = new IdentityLocatorFactory(contextRootUri); + davLocatorFactory = new DavPathFactory(contextRootUri); davResourceFactory = new FilesystemResourceFactory(filesystem); } diff --git a/main/jackrabbit-filesystem-adapter/src/test/java/org/cryptomator/webdav/jackrabbit/InMemoryWebDavServer.java b/main/jackrabbit-filesystem-adapter/src/test/java/org/cryptomator/webdav/jackrabbit/InMemoryWebDavServer.java index 9d27c643b..2e5397540 100644 --- a/main/jackrabbit-filesystem-adapter/src/test/java/org/cryptomator/webdav/jackrabbit/InMemoryWebDavServer.java +++ b/main/jackrabbit-filesystem-adapter/src/test/java/org/cryptomator/webdav/jackrabbit/InMemoryWebDavServer.java @@ -11,13 +11,18 @@ package org.cryptomator.webdav.jackrabbit; import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; +import java.util.EnumSet; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import javax.servlet.DispatcherType; + import org.cryptomator.filesystem.FileSystem; import org.cryptomator.filesystem.FolderCreateMode; import org.cryptomator.filesystem.WritableFile; import org.cryptomator.filesystem.inmem.InMemoryFileSystem; +import org.cryptomator.webdav.filters.AcceptRangeFilter; +import org.cryptomator.webdav.filters.UriNormalizationFilter; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -52,6 +57,8 @@ public class InMemoryWebDavServer { final ServletContextHandler servletContext = new ServletContextHandler(servletCollection, "/", ServletContextHandler.SESSIONS); final ServletHolder servletHolder = new ServletHolder("InMemory-WebDAV-Servlet", new WebDavServlet(servletContextRootUri, inMemoryFileSystem)); servletContext.addServlet(servletHolder, "/*"); + servletContext.addFilter(AcceptRangeFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); + servletContext.addFilter(UriNormalizationFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); servletCollection.mapContexts(); server.setConnectors(new Connector[] {localConnector});