Make webDAV fix filter more sophisticated. Eventual aim is to provide fixes tailored...
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 6 Jul 2009 22:20:11 +0000 (22:20 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 6 Jul 2009 22:20:11 +0000 (22:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@791634 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/filters/WebdavFixFilter.java

index 2afb04f..d56ff98 100644 (file)
@@ -40,15 +40,37 @@ import javax.servlet.http.HttpServletResponse;
  * 
  * Generally each different version of the MS client has a different set of
  * problems.
+ * <p>
  * TODO: Update this filter to recognise specific MS clients and apply the
  *       appropriate workarounds for that particular client
- *       
+ * <p>      
  * As a filter, this is configured in web.xml like any other Filter. You usually
  * want to map this filter to whatever your WebDAV servlet is mapped to.
+ * <p>
+ * In addition to the issues fixed by this Filter, the following issues have
+ * also been observed that cannot be fixed by this filter. Where possible the
+ * filter will add an message to the logs.
+ * <p>
+ * XP x64 SP2 (MiniRedir Version 3790
+ * <ul>
+ *   <li>Only connects to port 80</li>
+ *   <li>Requires an upper case context path</li>
+ *   <li>Unknown issue means it doesn't work</li>
+ * </ul>
  */
 
 public class WebdavFixFilter implements Filter {
 
+    private static final String LOG_MESSAGE_PREAMBLE =
+        "WebdavFixFilter: Detected client problem: ";
+
+    /* Start string for all versions */
+    private static final String UA_MINIDIR_START =
+        "Microsoft-WebDAV-MiniRedir";
+    /* XP 64-bit SP2 */
+    private static final String UA_MINIDIR_3790 =
+        "Microsoft-WebDAV-MiniRedir/5.2.3790";
+
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
     }
@@ -72,10 +94,30 @@ public class WebdavFixFilter implements Filter {
                HttpServletRequest httpRequest = ((HttpServletRequest) request);
                HttpServletResponse httpResponse = ((HttpServletResponse) response);
                String ua = httpRequest.getHeader("User-Agent");
-               if (ua != null && ua.contains("MiniRedir")) {
-                       httpResponse.sendRedirect(buildRedirect(httpRequest));
+               
+               if (ua == null || ua.length() == 0 ||
+                       !ua.startsWith(UA_MINIDIR_START)) {
+               // No UA or starts with non MS value
+                   // Hope everything just works...
+                   chain.doFilter(request, response);
+               } else if (ua.startsWith(UA_MINIDIR_3790)) {
+                   // XP 64-bit SP2
+                   // Check context path case
+                   if (!httpRequest.getContextPath().equals(
+                           httpRequest.getContextPath().toUpperCase())) {
+                       log(request,
+                               "XP-x64-SP2 expects context path to be upper case");
+                   }
+                   // Some other, as yet unknown issue means I can't get this client
+                   // to work 
+                   log(request, "XP-x64-SP2 is known not to work with WebDAV Servlet");
+                   
+                   chain.doFilter(request, response);
                } else {
-                       chain.doFilter(request, response);
+                   // Don't know which MS client it is - try the redirect with an
+                   // explicit port in the hope that it moves the client to a different
+                   // WebDAV implementation that works
+                       httpResponse.sendRedirect(buildRedirect(httpRequest));
                }               
        }
 
@@ -94,4 +136,9 @@ public class WebdavFixFilter implements Filter {
         return location.toString();
     }
 
+    private void log(ServletRequest request, String msg) {
+        StringBuilder builder = new StringBuilder(LOG_MESSAGE_PREAMBLE);
+        builder.append(msg);
+        request.getServletContext().log(builder.toString());
+    }
 }