You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2013/01/17 17:12:58 UTC

svn commit: r1434752 - in /tomcat/sandbox/rewrite/trunk: rewrite.xml src/main/java/org/apache/catalina/valves/rewrite/RewriteValve.java

Author: remm
Date: Thu Jan 17 16:12:58 2013
New Revision: 1434752

URL: http://svn.apache.org/viewvc?rev=1434752&view=rev
Log:
Improvements as suggested.

Modified:
    tomcat/sandbox/rewrite/trunk/rewrite.xml
    tomcat/sandbox/rewrite/trunk/src/main/java/org/apache/catalina/valves/rewrite/RewriteValve.java

Modified: tomcat/sandbox/rewrite/trunk/rewrite.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/rewrite/trunk/rewrite.xml?rev=1434752&r1=1434751&r2=1434752&view=diff
==============================================================================
Binary files - no diff available.

Modified: tomcat/sandbox/rewrite/trunk/src/main/java/org/apache/catalina/valves/rewrite/RewriteValve.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/rewrite/trunk/src/main/java/org/apache/catalina/valves/rewrite/RewriteValve.java?rev=1434752&r1=1434751&r2=1434752&view=diff
==============================================================================
--- tomcat/sandbox/rewrite/trunk/src/main/java/org/apache/catalina/valves/rewrite/RewriteValve.java (original)
+++ tomcat/sandbox/rewrite/trunk/src/main/java/org/apache/catalina/valves/rewrite/RewriteValve.java Thu Jan 17 16:12:58 2013
@@ -45,6 +45,7 @@ import org.apache.catalina.connector.Req
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.util.LifecycleSupport;
 import org.apache.catalina.valves.ValveBase;
+import org.apache.tomcat.util.buf.B2CConverter;
 import org.apache.tomcat.util.buf.CharChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.net.URL;
@@ -75,7 +76,7 @@ public class RewriteValve extends ValveB
      * Note: If the valve's container is a context, this will be relative to
      * /WEB-INF/.
      */
-    protected String resourcePath = "rewrite.properties";
+    protected String resourcePath = "rewrite.config";
 
     
     /**
@@ -85,11 +86,24 @@ public class RewriteValve extends ValveB
     
     
     /**
+     * enabled this component
+     */
+    protected boolean enabled = true;
+
+    /**
      * Maps to be used by the rules.
      */
     protected Map<String, RewriteMap> maps = new Hashtable<String, RewriteMap>();
     
     
+    public boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
     public void addLifecycleListener(LifecycleListener listener) {
         lifecycle.addLifecycleListener(listener);
     }
@@ -120,8 +134,7 @@ public class RewriteValve extends ValveB
                     container.getLogger().debug("Read configuration from: /WEB-INF/" + resourcePath);
                 }
             }
-        }
-        if (is == null) {
+        } else if (getContainer() instanceof Host) {
             String resourceName = getHostConfigPath(resourcePath);
             File file = new File(getConfigBase(), resourceName);
             try {
@@ -154,7 +167,7 @@ public class RewriteValve extends ValveB
             return;
         }
         
-        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is, B2CConverter.UTF_8));
 
         try {
             parse(reader);
@@ -266,205 +279,213 @@ public class RewriteValve extends ValveB
     public void invoke(Request request, Response response)
         throws IOException, ServletException {
 
-        if (rules == null || rules.length == 0) {
+        if (!getEnabled() || rules == null || rules.length == 0) {
             getNext().invoke(request, response);
             return;
         }
         
         if (invoked.get() == Boolean.TRUE) {
-            getNext().invoke(request, response);
-            invoked.set(null);
+            try {
+                getNext().invoke(request, response);
+            } finally {
+                invoked.set(null);
+            }
             return;
         }
         
-        Resolver resolver = new ResolverImpl(request);
-        
-        invoked.set(Boolean.TRUE);
-        
-        // As long as MB isn't a char sequence or affiliated, this has to be
-        // converted to a string
-        MessageBytes urlMB = context ? request.getRequestPathMB() : request.getDecodedRequestURIMB();
-        urlMB.toChars();
-        CharSequence url = urlMB.getCharChunk();
-        CharSequence host = request.getServerName();
-        boolean rewritten = false;
-        boolean done = false;
-        for (int i = 0; i < rules.length; i++) {
-            CharSequence test = (rules[i].isHost()) ? host : url;
-            CharSequence newtest = rules[i].evaluate(test, resolver);
-            if (newtest != null && !test.equals(newtest.toString())) {
-                if (container.getLogger().isDebugEnabled()) {
-                    container.getLogger().debug("Rewrote " + test + " as " + newtest
-                            + " with rule pattern " + rules[i].getPatternString());
-                }
-                if (rules[i].isHost()) {
-                    host = newtest;
-                } else {
-                    url = newtest;
+        try {
+
+            Resolver resolver = new ResolverImpl(request);
+
+            invoked.set(Boolean.TRUE);
+
+            // As long as MB isn't a char sequence or affiliated, this has to be
+            // converted to a string
+            MessageBytes urlMB = context ? request.getRequestPathMB() : request.getDecodedRequestURIMB();
+            urlMB.toChars();
+            CharSequence url = urlMB.getCharChunk();
+            CharSequence host = request.getServerName();
+            boolean rewritten = false;
+            boolean done = false;
+            for (int i = 0; i < rules.length; i++) {
+                RewriteRule rule = rules[i];
+                CharSequence test = (rule.isHost()) ? host : url;
+                CharSequence newtest = rule.evaluate(test, resolver);
+                if (newtest != null && !test.equals(newtest.toString())) {
+                    if (container.getLogger().isDebugEnabled()) {
+                        container.getLogger().debug("Rewrote " + test + " as " + newtest
+                                + " with rule pattern " + rule.getPatternString());
+                    }
+                    if (rule.isHost()) {
+                        host = newtest;
+                    } else {
+                        url = newtest;
+                    }
+                    rewritten = true;
                 }
-                rewritten = true;
-            }
 
-            // Final reply
+                // Final reply
 
-            // - forbidden
-            if (rules[i].isForbidden() && newtest != null) {
-                response.sendError(HttpServletResponse.SC_FORBIDDEN);
-                done = true;
-                break;
-            }
-            // - gone
-            if (rules[i].isGone() && newtest != null) {
-                response.sendError(HttpServletResponse.SC_GONE);
-                done = true;
-                break;
-            }
-            // - redirect (code)
-            if (rules[i].isRedirect() && newtest != null) {
-                // append the query string to the url if there is one and it hasn't been rewritten
-                String queryString = request.getQueryString();
-                StringBuffer urlString = new StringBuffer(url);
-                if (queryString != null && queryString.length() > 0) {
-                    int index = urlString.indexOf("?");
-                    if (index != -1) {
-                        // if qsa is specified append the query
-                        if (rules[i].isQsappend()) {
-                            urlString.append('&');
+                // - forbidden
+                if (rule.isForbidden() && newtest != null) {
+                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                    done = true;
+                    break;
+                }
+                // - gone
+                if (rule.isGone() && newtest != null) {
+                    response.sendError(HttpServletResponse.SC_GONE);
+                    done = true;
+                    break;
+                }
+                // - redirect (code)
+                if (rule.isRedirect() && newtest != null) {
+                    // append the query string to the url if there is one and it hasn't been rewritten
+                    String queryString = request.getQueryString();
+                    StringBuffer urlString = new StringBuffer(url);
+                    if (queryString != null && queryString.length() > 0) {
+                        int index = urlString.indexOf("?");
+                        if (index != -1) {
+                            // if qsa is specified append the query
+                            if (rule.isQsappend()) {
+                                urlString.append('&');
+                                urlString.append(queryString);
+                            }
+                            // if the ? is the last character delete it, its only purpose was to
+                            // prevent the rewrite module from appending the query string
+                            else if (index == urlString.length() - 1) {
+                                urlString.deleteCharAt(index);
+                            }
+                        } else {
+                            urlString.append('?');
                             urlString.append(queryString);
                         }
-                        // if the ? is the last character delete it, its only purpose was to
-                        // prevent the rewrite module from appending the query string
-                        else if (index == urlString.length() - 1) {
-                            urlString.deleteCharAt(index);
+                    }
+                    // Insert the context if
+                    // 1. this valve is associated with a context
+                    // 2. the url starts with a leading slash
+                    // 3. the url isn't absolute
+                    if (context && urlString.charAt(0) == '/' && !hasScheme(urlString)) {
+                        urlString.insert(0, request.getContext().getEncodedPath());
+                    }
+                    response.sendRedirect(urlString.toString());
+                    response.setStatus(rule.getRedirectCode());
+                    done = true;
+                    break;
+                }
+
+                // Reply modification
+
+                // - cookie
+                if (rule.isCookie() && newtest != null) {
+                    Cookie cookie = new Cookie(rule.getCookieName(), 
+                            rule.getCookieResult());
+                    cookie.setDomain(rule.getCookieDomain());
+                    cookie.setMaxAge(rule.getCookieLifetime());
+                    cookie.setPath(rule.getCookiePath());
+                    cookie.setSecure(rule.isCookieSecure());
+                    cookie.setHttpOnly(rule.isCookieHttpOnly());
+                    response.addCookie(cookie);
+                }
+                // - env (note: this sets a request attribute)
+                if (rule.isEnv() && newtest != null) {
+                    for (int j = 0; j < rule.getEnvSize(); j++) {
+                        request.setAttribute(rule.getEnvName(j), rule.getEnvResult(j));
+                    }
+                }
+                // - content type (note: this will not force the content type, use a filter
+                //   to do that)
+                if (rule.isType() && newtest != null) {
+                    request.setContentType(rule.getTypeValue());
+                }
+                // - qsappend
+                if (rule.isQsappend() && newtest != null) {
+                    String queryString = request.getQueryString();
+                    String urlString = url.toString();
+                    if (urlString.indexOf('?') != -1 && queryString != null) {
+                        url = urlString + "&" + queryString;
+                    }
+                }
+
+                // Control flow processing
+
+                // - chain (skip remaining chained rules if this one does not match)
+                if (rule.isChain() && newtest == null) {
+                    for (int j = i; j < rules.length; j++) {
+                        if (!rules[j].isChain()) {
+                            i = j;
+                            break;
                         }
-                    } else {
-                        urlString.append('?');
-                        urlString.append(queryString);
                     }
+                    continue;
                 }
-                // Insert the context if
-                // 1. this valve is associated with a context
-                // 2. the url starts with a leading slash
-                // 3. the url isn't absolute
-                if (context && urlString.charAt(0) == '/' && !hasScheme(urlString)) {
-                    urlString.insert(0, request.getContext().getEncodedPath());
-                }
-                response.sendRedirect(urlString.toString());
-                response.setStatus(rules[i].getRedirectCode());
-                done = true;
-                break;
-            }
-            
-            // Reply modification
-
-            // - cookie
-            if (rules[i].isCookie() && newtest != null) {
-                Cookie cookie = new Cookie(rules[i].getCookieName(), 
-                        rules[i].getCookieResult());
-                cookie.setDomain(rules[i].getCookieDomain());
-                cookie.setMaxAge(rules[i].getCookieLifetime());
-                cookie.setPath(rules[i].getCookiePath());
-                cookie.setSecure(rules[i].isCookieSecure());
-                cookie.setHttpOnly(rules[i].isCookieHttpOnly());
-                response.addCookie(cookie);
-            }
-            // - env (note: this sets a request attribute)
-            if (rules[i].isEnv() && newtest != null) {
-                for (int j = 0; j < rules[i].getEnvSize(); j++) {
-                    request.setAttribute(rules[i].getEnvName(j), rules[i].getEnvResult(j));
-                }
-            }
-            // - content type (note: this will not force the content type, use a filter
-            //   to do that)
-            if (rules[i].isType() && newtest != null) {
-                request.setContentType(rules[i].getTypeValue());
-            }
-            // - qsappend
-            if (rules[i].isQsappend() && newtest != null) {
-                String queryString = request.getQueryString();
-                String urlString = url.toString();
-                if (urlString.indexOf('?') != -1 && queryString != null) {
-                    url = urlString + "&" + queryString;
-                }
-            }
-            
-            // Control flow processing
-            
-            // - chain (skip remaining chained rules if this one does not match)
-            if (rules[i].isChain() && newtest == null) {
-                for (int j = i; j < rules.length; j++) {
-                    if (!rules[j].isChain()) {
-                        i = j;
-                        break;
-                    }
-                }
-                continue;
-            }
-            // - last (stop rewriting here)
-            if (rules[i].isLast() && newtest != null) {
-                break;
-            }
-            // - next (redo again)
-            if (rules[i].isNext() && newtest != null) {
-                i = 0;
-                continue;
-            }
-            // - skip (n rules)
-            if (newtest != null) {
-                i += rules[i].getSkip();
-            }
-            
-        }
-        
-        if (rewritten) {
-            if (!done) {
-                // See if we need to replace the query string
-                String urlString = url.toString();
-                String queryString = null;
-                int queryIndex = urlString.indexOf('?');
-                if (queryIndex != -1) {
-                    queryString = urlString.substring(queryIndex+1);
-                    urlString = urlString.substring(0, queryIndex);
-                }
-                // Set the new URL
-                CharChunk chunk = request.getCoyoteRequest().requestURI().getCharChunk();
-                chunk.recycle();
-                if (context) {
-                    chunk.append(request.getContextPath());
-                }
-                chunk.append(urlString);
-                request.getCoyoteRequest().requestURI().toChars();
-                // Set the new Query if there is one
-                if (queryString != null) {
-                    request.getCoyoteRequest().queryString().setString(null);
-                    chunk = request.getCoyoteRequest().queryString().getCharChunk();
-                    chunk.recycle();
-                    chunk.append(queryString);
-                    request.getCoyoteRequest().queryString().toChars();
+                // - last (stop rewriting here)
+                if (rule.isLast() && newtest != null) {
+                    break;
                 }
-                // Set the new host if it changed
-                if (!host.equals(request.getServerName())) {
-                    request.getCoyoteRequest().serverName().setString(null);
-                    chunk = request.getCoyoteRequest().serverName().getCharChunk();
-                    chunk.recycle();
-                    chunk.append(host.toString());
-                    request.getCoyoteRequest().serverName().toChars();
+                // - next (redo again)
+                if (rule.isNext() && newtest != null) {
+                    i = 0;
+                    continue;
+                }
+                // - skip (n rules)
+                if (newtest != null) {
+                    i += rule.getSkip();
                 }
-                request.getMappingData().recycle();
-                // Reinvoke the whole request recursively
-                try {
-                    request.getConnector().getProtocolHandler().getAdapter().service
+
+            }
+
+            if (rewritten) {
+                if (!done) {
+                    // See if we need to replace the query string
+                    String urlString = url.toString();
+                    String queryString = null;
+                    int queryIndex = urlString.indexOf('?');
+                    if (queryIndex != -1) {
+                        queryString = urlString.substring(queryIndex+1);
+                        urlString = urlString.substring(0, queryIndex);
+                    }
+                    // Set the new URL
+                    CharChunk chunk = request.getCoyoteRequest().requestURI().getCharChunk();
+                    chunk.recycle();
+                    if (context) {
+                        chunk.append(request.getContextPath());
+                    }
+                    chunk.append(urlString);
+                    request.getCoyoteRequest().requestURI().toChars();
+                    // Set the new Query if there is one
+                    if (queryString != null) {
+                        request.getCoyoteRequest().queryString().setString(null);
+                        chunk = request.getCoyoteRequest().queryString().getCharChunk();
+                        chunk.recycle();
+                        chunk.append(queryString);
+                        request.getCoyoteRequest().queryString().toChars();
+                    }
+                    // Set the new host if it changed
+                    if (!host.equals(request.getServerName())) {
+                        request.getCoyoteRequest().serverName().setString(null);
+                        chunk = request.getCoyoteRequest().serverName().getCharChunk();
+                        chunk.recycle();
+                        chunk.append(host.toString());
+                        request.getCoyoteRequest().serverName().toChars();
+                    }
+                    request.getMappingData().recycle();
+                    // Reinvoke the whole request recursively
+                    try {
+                        request.getConnector().getProtocolHandler().getAdapter().service
                         (request.getCoyoteRequest(), response.getCoyoteResponse());
-                } catch (Exception e) {
-                    // This doesn't actually happen in the Catalina adapter implementation
+                    } catch (Exception e) {
+                        // This doesn't actually happen in the Catalina adapter implementation
+                    }
                 }
+            } else {
+                getNext().invoke(request, response);
             }
-        } else {
-            getNext().invoke(request, response);
+
+        } finally {
+            invoked.set(null);
         }
         
-        invoked.set(null);
-        
     }
     
     



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org