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