The context path at which the webdav servlet is run must be /*. That is, a web.xml entry like the following does not work: <servlet-mapping> <servlet-name>webdavsf</servlet-name> <url-pattern>/dav/*</url-pattern> </servlet-mapping> This is tested on 5.5.17 This is unfortunate if you want to have one WAR file containing some other servlets and a dav area with content autogenerated by the servlets. I have made patches to "webdav servlet" on SourceForge, which is derived from the apache code and has the same problem. My patches seem to fix it, and I suspect that very similar patches would fix the original version. I am not a dav expert though, and I haven't tested it on the original version, nor any locking etc. So the patches described bel There seem to be two reasons for this requirement for /* instead of, say /dav/* (1) The internal path generated for a null entry is wrong. This can be fixed by removing the following lines from getRelativePath() [in DefaultServlet]: if (result == null) result = (String) request.getAttribute( Globals.INCLUDE_SERVLET_PATH_ATTR); and if (result == null) { result = request.getServletPath(); } I don't see how these lines could ever help in the WebDav context, though I am not an expert in dav, and they may be important in some other use of DefaultServlet. The second required modification that I posted for "webdav servlet" on sourceforge has already been fixed (or something equivalent) in 5.5.17., so you should be able to ignore that.
This is actually a Micorosft problem, and it is du to the implementation of the MS Client, which requests some information against the root "/", regardles of the resource and the real root of WebDAV. To solve this problem, I am using a simple Filter to filter the MS WebDAV requests: /** * The webdav interceptor blocks some FrontPage requests and determinate the encoding of the underlying request * */ public class WebdavInterceptor implements Filter { public static final String MICROSOFT_PROTOCOL_AGENT = "Microsoft Data Access Internet Publishing Provider Protocol Discovery"; /** Creates a new instance of LoginInterceptor */ public WebdavInterceptor() { } public void init(javax.servlet.FilterConfig filterConfig) throws javax.servlet.ServletException { } public void destroy() { } /** Filter some invalid calls from the Microsoft WebDAV clients (Windows 2000, Windows XP and Office 2003) */ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; String path = request.getServletPath(); if (path != null) { if (path.endsWith("/index.jsp")) { // a very strange microsoft webdav handling... (because of the front page extensions!) // Microsoft (protocol discoverer) is asking the root of the server // whether it can handles a WebDAV, so we have to catch it here. Unfortunately we can't // redirect the root URL ("/") to a servlet, because we will intercept any other // path handling... String agent = request.getHeader("user-agent"); if (MICROSOFT_PROTOCOL_AGENT.equals(agent)) { HttpServletResponse response = (HttpServletResponse) servletResponse; response.addHeader("DAV", "1,2"); response.addHeader("Allow", "OPTIONS, TRACE, PROPFIND"); response.addHeader("MS-AUTHOR-VIA", "DAV"); return; } } // block, front page and m$ office extensions requests... if (path.startsWith("/_vti") || path.startsWith("/MSOffice")) { ((HttpServletResponse)servletResponse).setStatus (HttpServletResponse.SC_NOT_FOUND); return; } } request.setCharacterEncoding(WebdavServlet.getEnconding(request)); filterChain.doFilter(servletRequest, servletResponse); } } Please note, that the root "/" is mapped to "/index.jsp", this is the standard welcome file whithin my container. Thus the filter is mapped to: <filter-mapping> <filter-name>webdavFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> and also to the WebDAV Servlet: <filter-mapping> <filter-name>webdavFilter</filter-name> <servlet-name>webdav</servlet-name> </filter-mapping> The WebDAV servket should map additionaly the following paths: <servlet-mapping> <servlet-name>webdav</servlet-name> <url-pattern>/_vti_inf.html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>webdav</servlet-name> <url-pattern>/_vti_bin/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>webdav</servlet-name> <url-pattern>/MSOffice/*</url-pattern> </servlet-mapping> I hope, this helps you. My WebDAV root is for instance "/webdav/*", and it works within a container togther with a web application. Regards Peter
Peter, thank you for posting the filter: I like it as a nice, clean solution to an unfortunate (but non-Tomcat) problem. Andrew, thank you for posting your suggestions: the second one is good and as you've noted, it's already been implemented. I hope Peter's filter works well for you. I'm going to link to it from the actual WebdavServlet class JavaDoc as well.