-
-
Notifications
You must be signed in to change notification settings - Fork 972
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
some Windows WebDAV compatibility fixes
- Loading branch information
Sebastian Stenzel
committed
Feb 29, 2016
1 parent
be4dab2
commit a6c99c2
Showing
6 changed files
with
200 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
...end-webdav/src/main/java/org/cryptomator/frontend/webdav/WindowsCompatibilityServlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package org.cryptomator.frontend.webdav; | ||
|
||
import java.io.IOException; | ||
import java.util.EnumSet; | ||
|
||
import javax.servlet.DispatcherType; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.cryptomator.frontend.webdav.filters.LoopbackFilter; | ||
import org.eclipse.jetty.servlet.ServletContextHandler; | ||
import org.eclipse.jetty.servlet.ServletHolder; | ||
|
||
/** | ||
* The server needs to respond to requests to the root resource, because Windows is stupid. | ||
*/ | ||
public class WindowsCompatibilityServlet extends HttpServlet { | ||
|
||
private static final String ROOT_PATH = "/"; | ||
|
||
@Override | ||
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
resp.addHeader("DAV", "1, 2"); | ||
resp.addHeader("MS-Author-Via", "DAV"); | ||
// resp.addHeader("Allow", "OPTIONS, GET, HEAD, POST, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, PUT, DELETE, MOVE, LOCK, UNLOCK"); | ||
resp.setStatus(HttpServletResponse.SC_NO_CONTENT); | ||
} | ||
|
||
public static ServletContextHandler createServletContextHandler() { | ||
final ServletContextHandler servletContext = new ServletContextHandler(null, ROOT_PATH, ServletContextHandler.NO_SESSIONS); | ||
final ServletHolder servletHolder = new ServletHolder(ROOT_PATH, WindowsCompatibilityServlet.class); | ||
servletContext.addServlet(servletHolder, ROOT_PATH); | ||
servletContext.addFilter(LoopbackFilter.class, ROOT_PATH, EnumSet.of(DispatcherType.REQUEST)); | ||
return servletContext; | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
...frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/filters/LoopbackFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package org.cryptomator.frontend.webdav.filters; | ||
|
||
import java.io.IOException; | ||
import java.net.InetAddress; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.FilterConfig; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
/** | ||
* Blocks all requests from external hosts. | ||
*/ | ||
public class LoopbackFilter implements HttpFilter { | ||
|
||
@Override | ||
public void init(FilterConfig filterConfig) throws ServletException { | ||
// no-op | ||
} | ||
|
||
@Override | ||
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) | ||
throws IOException, ServletException { | ||
if (InetAddress.getByName(request.getRemoteAddr()).isLoopbackAddress()) { | ||
chain.doFilter(request, response); | ||
} else { | ||
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Can only access drive from localhost."); | ||
} | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
// no-op | ||
} | ||
|
||
} |
49 changes: 49 additions & 0 deletions
49
...webdav/src/test/java/org/cryptomator/frontend/webdav/WindowsCompatibilityServletTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 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.frontend.webdav; | ||
|
||
import java.io.IOException; | ||
|
||
import javax.servlet.Servlet; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.eclipse.jetty.servlet.ServletHolder; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
import org.mockito.Mockito; | ||
|
||
|
||
public class WindowsCompatibilityServletTest { | ||
|
||
@Test | ||
public void testFactory() throws ServletException { | ||
ServletHolder[] holders = WindowsCompatibilityServlet.createServletContextHandler().getServletHandler().getServlets(); | ||
Assert.assertEquals(1, holders.length); | ||
ServletHolder holder = holders[0]; | ||
|
||
Servlet servlet = holder.getServlet(); | ||
Assert.assertTrue(servlet instanceof WindowsCompatibilityServlet); | ||
} | ||
|
||
@Test | ||
public void testResponse() throws IOException, ServletException { | ||
final WindowsCompatibilityServlet servlet = new WindowsCompatibilityServlet(); | ||
final HttpServletRequest request = Mockito.mock(HttpServletRequest.class); | ||
final HttpServletResponse response = Mockito.mock(HttpServletResponse.class); | ||
|
||
servlet.doOptions(request, response); | ||
|
||
Mockito.verify(response).addHeader("MS-Author-Via", "DAV"); | ||
Mockito.verify(response).addHeader("DAV", "1, 2"); | ||
Mockito.verify(response).setStatus(204); | ||
} | ||
|
||
} |
70 changes: 70 additions & 0 deletions
70
...tend-webdav/src/test/java/org/cryptomator/frontend/webdav/filters/LoopbackFilterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 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.frontend.webdav.filters; | ||
|
||
import java.io.IOException; | ||
import java.net.InetAddress; | ||
import java.util.Arrays; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Assume; | ||
import org.junit.Before; | ||
import org.junit.experimental.theories.DataPoints; | ||
import org.junit.experimental.theories.Theories; | ||
import org.junit.experimental.theories.Theory; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.Mockito; | ||
|
||
@RunWith(Theories.class) | ||
public class LoopbackFilterTest { | ||
|
||
@DataPoints | ||
public static final Iterable<String> HOST_NAMES = Arrays.asList("127.0.0.1", "0::1", "1.2.3.4", "google.com"); | ||
|
||
private LoopbackFilter filter; | ||
private FilterChain chain; | ||
private HttpServletRequest request; | ||
private HttpServletResponse response; | ||
|
||
@Before | ||
public void setup() { | ||
filter = new LoopbackFilter(); | ||
chain = Mockito.mock(FilterChain.class); | ||
request = Mockito.mock(HttpServletRequest.class); | ||
response = Mockito.mock(HttpServletResponse.class); | ||
} | ||
|
||
@Theory | ||
public void testWithLoopbackAddress(String hostname) throws IOException, ServletException { | ||
Assume.assumeTrue(InetAddress.getByName(hostname).isLoopbackAddress()); | ||
Mockito.when(request.getRemoteAddr()).thenReturn(hostname); | ||
|
||
filter.doFilter(request, response, chain); | ||
Mockito.verify(chain).doFilter(request, response); | ||
} | ||
|
||
@Theory | ||
public void testWithExternalAddress(String hostname) throws IOException, ServletException { | ||
Assume.assumeFalse(InetAddress.getByName(hostname).isLoopbackAddress()); | ||
Mockito.when(request.getRemoteAddr()).thenReturn(hostname); | ||
|
||
filter.doFilter(request, response, chain); | ||
|
||
ArgumentCaptor<Integer> statusCode = ArgumentCaptor.forClass(Integer.class); | ||
Mockito.verify(response).sendError(statusCode.capture(), Mockito.anyString()); | ||
Assert.assertEquals(405, statusCode.getValue().intValue()); | ||
} | ||
|
||
} |