added WebDavServer class to webdav frontend

This commit is contained in:
Sebastian Stenzel
2016-01-25 16:13:21 +01:00
parent e23baa33f9
commit 9052e7995f
8 changed files with 161 additions and 83 deletions
+11
View File
@@ -66,6 +66,17 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- DI -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
@@ -19,7 +19,7 @@ import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
import org.cryptomator.filesystem.Folder;
import org.cryptomator.filesystem.jackrabbit.FileSystemResourceLocatorFactory;
class WebDavServlet extends AbstractWebdavServlet {
public class WebDavServlet extends AbstractWebdavServlet {
private static final long serialVersionUID = -6632687979352625020L;
@@ -0,0 +1,13 @@
package org.cryptomator.webdav.server;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component
public interface WebDavComponent {
WebDavServer getServer();
}
@@ -0,0 +1,98 @@
package org.cryptomator.webdav.server;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.filesystem.Folder;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class WebDavServer {
private static final Logger LOG = LoggerFactory.getLogger(WebDavServer.class);
private static final String LOCALHOST = SystemUtils.IS_OS_WINDOWS ? "::1" : "localhost";
private static final int MAX_PENDING_REQUESTS = 200;
private static final int MAX_THREADS = 200;
private static final int MIN_THREADS = 4;
private static final int THREAD_IDLE_SECONDS = 20;
private final Server server;
private final ServerConnector localConnector;
private final ContextHandlerCollection servletCollection;
private final WebDavServletContextFactory servletContextFactory;
@Inject
public WebDavServer(WebDavServletContextFactory servletContextFactory) {
final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(MAX_PENDING_REQUESTS);
final ThreadPool tp = new QueuedThreadPool(MAX_THREADS, MIN_THREADS, THREAD_IDLE_SECONDS, queue);
this.server = new Server(tp);
this.localConnector = new ServerConnector(server);
this.servletCollection = new ContextHandlerCollection();
this.servletContextFactory = servletContextFactory;
localConnector.setHost(LOCALHOST);
server.setConnectors(new Connector[] {localConnector});
server.setHandler(servletCollection);
}
public void setPort(int port) {
if (server.isStopped()) {
localConnector.setPort(port);
} else {
throw new IllegalStateException("Cannot change port of running server.");
}
}
public int getPort() {
return localConnector.getLocalPort();
}
public synchronized void start() {
try {
server.start();
LOG.info("Cryptomator is running on port {}", getPort());
} catch (Exception ex) {
throw new RuntimeException("Server couldn't be started", ex);
}
}
public boolean isRunning() {
return server.isRunning();
}
public synchronized void stop() {
try {
server.stop();
} catch (Exception ex) {
LOG.error("Server couldn't be stopped", ex);
}
}
public ServletContextHandler addServlet(Folder root, String contextPath) {
final URI uri;
try {
uri = new URI("http", null, LOCALHOST, getPort(), contextPath, null, null);
} catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
ServletContextHandler handler = servletContextFactory.create(uri, root);
servletCollection.addHandler(handler);
servletCollection.mapContexts();
return handler;
}
}
@@ -6,33 +6,37 @@
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.webdav.jackrabbitservlet;
package org.cryptomator.webdav.server;
import java.net.URI;
import java.util.EnumSet;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.DispatcherType;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.filesystem.Folder;
import org.cryptomator.webdav.filters.AcceptRangeFilter;
import org.cryptomator.webdav.filters.LoggingHttpFilter;
import org.cryptomator.webdav.filters.MacChunkedPutCompatibilityFilter;
import org.cryptomator.webdav.filters.UriNormalizationFilter;
import org.cryptomator.webdav.filters.UriNormalizationFilter.ResourceTypeChecker;
import org.cryptomator.webdav.filters.UriNormalizationFilter.ResourceTypeChecker.ResourceType;
import org.cryptomator.webdav.jackrabbitservlet.WebDavServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WebDavServletContextFactory {
@Singleton
class WebDavServletContextFactory {
private static final Logger LOG = LoggerFactory.getLogger(WebDavServletContextFactory.class);
private static final String WILDCARD = "/*";
@Inject
public WebDavServletContextFactory() {
}
/**
* Creates a new Jetty ServletContextHandler, that can be be added to a servletCollection as follows:
*
@@ -65,9 +69,6 @@ public class WebDavServletContextFactory {
if (SystemUtils.IS_OS_MAC_OSX) {
servletContext.addFilter(MacChunkedPutCompatibilityFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));
}
if (LOG.isDebugEnabled()) {
servletContext.addFilter(LoggingHttpFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));
}
return servletContext;
}
@@ -1,65 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 2016 Sebastian Stenzel and others.
* This file is licensed under the terms of the MIT license.
* See the LICENSE.txt file for more info.
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.webdav.jackrabbitservlet;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.cryptomator.filesystem.FileSystem;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
class FileSystemBasedWebDavServer {
private final Server server;
private final ServerConnector localConnector;
private final ContextHandlerCollection servletCollection;
public FileSystemBasedWebDavServer(FileSystem fileSystem) {
final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(10);
final ThreadPool tp = new QueuedThreadPool(4, 1, 1, queue);
server = new Server(tp);
localConnector = new ServerConnector(server);
localConnector.setHost("localhost");
localConnector.setPort(8080);
servletCollection = new ContextHandlerCollection();
final URI servletContextRoot1;
final URI servletContextRoot2;
try {
servletContextRoot1 = new URI("http", null, "localhost", 8080, "/foo/", null, null);
servletContextRoot2 = new URI("http", null, "localhost", 8080, "/bar/", null, null);
} catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
final WebDavServletContextFactory servletContextFactory = new WebDavServletContextFactory();
servletCollection.addHandler(servletContextFactory.create(servletContextRoot1, fileSystem));
servletCollection.addHandler(servletContextFactory.create(servletContextRoot2, fileSystem));
servletCollection.mapContexts();
server.setConnectors(new Connector[] {localConnector});
server.setHandler(servletCollection);
}
public void start() throws Exception {
server.start();
}
public void stop() throws Exception {
server.stop();
}
}
@@ -6,21 +6,31 @@
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.webdav.jackrabbitservlet;
package org.cryptomator.webdav.server;
import java.nio.ByteBuffer;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.cryptomator.filesystem.FileSystem;
import org.cryptomator.filesystem.WritableFile;
import org.cryptomator.filesystem.inmem.InMemoryFileSystem;
import org.cryptomator.webdav.filters.LoggingHttpFilter;
import org.eclipse.jetty.servlet.ServletContextHandler;
public class InMemoryWebDavServer {
public static void main(String[] args) throws Exception {
FileSystem fileSystem = setupFilesystem();
FileSystemBasedWebDavServer server = new FileSystemBasedWebDavServer(fileSystem);
WebDavServer server = DaggerWebDavComponent.create().getServer();
server.setPort(8080);
server.start();
FileSystem fileSystem = setupFilesystem();
ServletContextHandler servlet = server.addServlet(fileSystem, "/foo");
servlet.addFilter(LoggingHttpFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
servlet.start();
System.out.println("Server started. Press any key to stop it...");
System.in.read();
server.stop();
@@ -6,7 +6,7 @@
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.webdav.jackrabbitservlet;
package org.cryptomator.webdav.server;
import java.io.BufferedReader;
import java.io.IOException;
@@ -16,20 +16,30 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.Optional;
import javax.servlet.DispatcherType;
import org.cryptomator.filesystem.FileSystem;
import org.cryptomator.filesystem.nio.NioFileSystem;
import org.cryptomator.webdav.filters.LoggingHttpFilter;
import org.eclipse.jetty.servlet.ServletContextHandler;
public class NioWebDavServer {
private static final String PATH_TO_SERVE_PROPERTY = "pathToServe";
public static void main(String[] args) throws Exception {
FileSystem fileSystem = setupFilesystem();
FileSystemBasedWebDavServer server = new FileSystemBasedWebDavServer(fileSystem);
WebDavServer server = DaggerWebDavComponent.create().getServer();
server.setPort(8080);
server.start();
FileSystem fileSystem = setupFilesystem();
ServletContextHandler servlet = server.addServlet(fileSystem, "/foo");
servlet.addFilter(LoggingHttpFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
servlet.start();
System.out.println("Server started. Press any key to stop it...");
System.in.read();
server.stop();