--- jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteAdapter.java	(revision 466585)
+++ jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteAdapter.java	(revision 519369)
@@ -51,6 +51,10 @@
 final class CoyoteAdapter
     implements Adapter {
 
+    protected static final boolean ALLOW_BACKSLASH = Boolean.valueOf(
+            System.getProperty(
+                    "org.apache.coyote.tomcat4.CoyoteAdapter.ALLOW_BACKSLASH",
+                    "false")).booleanValue();
 
     // -------------------------------------------------------------- Constants
 
@@ -440,8 +444,12 @@
             return "/";
 
         // Normalize the slashes and add leading slash if necessary
-        if (normalized.indexOf('\\') >= 0)
-            normalized = normalized.replace('\\', '/');
+        if (normalized.indexOf('\\') >= 0) {
+            if ( ALLOW_BACKSLASH )
+                normalized = normalized.replace('\\', '/');
+            else 
+                return null;
+        }
         if (!normalized.startsWith("/"))
             normalized = "/" + normalized;
 
@@ -564,8 +572,12 @@
         // Replace '\' with '/'
         // Check for null byte
         for (pos = start; pos < end; pos++) {
-            if (b[pos] == (byte) '\\')
-                b[pos] = (byte) '/';
+            if (b[pos] == (byte) '\\') {
+                if (ALLOW_BACKSLASH)
+                    b[pos] = (byte) '/';
+                else 
+                    return false;
+            }
             if (b[pos] == (byte) 0)
                 return false;
         }
--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/CoyoteAdapter.java	(revision 466608)
+++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/CoyoteAdapter.java	(revision 507117)
@@ -50,6 +50,8 @@
  {
     private static Log log = LogFactory.getLog(CoyoteAdapter.class);
 
+    protected static final boolean ALLOW_BACKSLASH = 
+        Boolean.valueOf(System.getProperty("org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH", "false")).booleanValue();
     // -------------------------------------------------------------- Constants
 
 
@@ -226,8 +228,8 @@
                 req.getURLDecoder().convert(decodedURI, false);
             } catch (IOException ioe) {
                 res.setStatus(400);
-                res.setMessage("Invalid URI");
-                throw ioe;
+                res.setMessage("Invalid URI: " + ioe.getMessage());
+                return false;
             }
             // Normalization
             if (!normalize(req.decodedURI())) {
@@ -515,8 +517,13 @@
         // Replace '\' with '/'
         // Check for null byte
         for (pos = start; pos < end; pos++) {
-            if (b[pos] == (byte) '\\')
-                b[pos] = (byte) '/';
+            if (b[pos] == (byte) '\\') {
+                if (ALLOW_BACKSLASH) {
+                    b[pos] = (byte) '/';
+                } else {
+                    return false;
+                }
+            }
             if (b[pos] == (byte) 0)
                 return false;
         }
--- jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/buf/UDecoder.java	(revision 481614)
+++ jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/buf/UDecoder.java	(revision 507117)
@@ -30,6 +30,9 @@
  */
 public final class UDecoder {
     
+    protected static final boolean ALLOW_ENCODED_SLASH = 
+        Boolean.valueOf(System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "false")).booleanValue();
+    
     public UDecoder() 
     {
     }
@@ -63,6 +66,8 @@
 	// idx will be the smallest positive inxes ( first % or + )
 	if( idx2 >= 0 && idx2 < idx ) idx=idx2;
 	if( idx < 0 ) idx=idx2;
+    
+	boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
 
 	for( int j=idx; j<end; j++, idx++ ) {
 	    if( buff[ j ] == '+' && query) {
@@ -81,6 +86,9 @@
 		
 		j+=2;
 		int res=x2c( b1, b2 );
+                if (noSlash && (res == '/')) {
+                    throw new CharConversionException( "noSlash");
+                }
 		buff[idx]=(byte)res;
 	    }
 	}
@@ -122,7 +130,8 @@
 	
 	if( idx2 >= 0 && idx2 < idx ) idx=idx2; 
 	if( idx < 0 ) idx=idx2;
-
+    
+	boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
 	for( int j=idx; j<cend; j++, idx++ ) {
 	    if( buff[ j ] == '+' && query ) {
 		buff[idx]=( ' ' );
@@ -141,6 +150,9 @@
 		
 		j+=2;
 		int res=x2c( b1, b2 );
+		if (noSlash && (res == '/')) {
+		    throw new CharConversionException( "noSlash");
+            	}
 		buff[idx]=(char)res;
 	    }
 	}
