瀏覽代碼

added WebDavServer class to webdav frontend

Sebastian Stenzel 9 年之前
父節點
當前提交
9052e7995f

+ 11 - 0
main/frontend-webdav/pom.xml

@@ -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>

+ 1 - 1
main/frontend-webdav/src/main/java/org/cryptomator/webdav/jackrabbitservlet/WebDavServlet.java

@@ -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;
 

+ 13 - 0
main/frontend-webdav/src/main/java/org/cryptomator/webdav/server/WebDavComponent.java

@@ -0,0 +1,13 @@
+package org.cryptomator.webdav.server;
+
+import javax.inject.Singleton;
+
+import dagger.Component;
+
+@Singleton
+@Component
+public interface WebDavComponent {
+
+	WebDavServer getServer();
+
+}

+ 98 - 0
main/frontend-webdav/src/main/java/org/cryptomator/webdav/server/WebDavServer.java

@@ -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;
+	}
+
+}

+ 10 - 9
main/frontend-webdav/src/main/java/org/cryptomator/webdav/jackrabbitservlet/WebDavServletContextFactory.java

@@ -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;
 	}
 

+ 0 - 65
main/frontend-webdav/src/test/java/org/cryptomator/webdav/jackrabbitservlet/FileSystemBasedWebDavServer.java

@@ -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();
-	}
-
-}

+ 13 - 3
main/frontend-webdav/src/test/java/org/cryptomator/webdav/jackrabbitservlet/InMemoryWebDavServer.java

@@ -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 {
+		WebDavServer server = DaggerWebDavComponent.create().getServer();
+		server.setPort(8080);
+		server.start();
+
 		FileSystem fileSystem = setupFilesystem();
-		FileSystemBasedWebDavServer server = new FileSystemBasedWebDavServer(fileSystem);
+		ServletContextHandler servlet = server.addServlet(fileSystem, "/foo");
+		servlet.addFilter(LoggingHttpFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
+		servlet.start();
 
-		server.start();
 		System.out.println("Server started. Press any key to stop it...");
 		System.in.read();
 		server.stop();

+ 13 - 3
main/frontend-webdav/src/test/java/org/cryptomator/webdav/jackrabbitservlet/NioWebDavServer.java

@@ -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 {
+		WebDavServer server = DaggerWebDavComponent.create().getServer();
+		server.setPort(8080);
+		server.start();
+
 		FileSystem fileSystem = setupFilesystem();
-		FileSystemBasedWebDavServer server = new FileSystemBasedWebDavServer(fileSystem);
+		ServletContextHandler servlet = server.addServlet(fileSystem, "/foo");
+		servlet.addFilter(LoggingHttpFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
+		servlet.start();
 
-		server.start();
 		System.out.println("Server started. Press any key to stop it...");
 		System.in.read();
 		server.stop();