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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org