From b6c40fdd51a95566c7ea0e6c155c7432e3351268 Mon Sep 17 00:00:00 2001 From: markt Date: Mon, 10 Aug 2009 18:23:17 +0000 Subject: [PATCH] Add filtering of Comet events to the request filters Based on a patch provided by Xie Xiaodong as part of GSOC2009. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@802882 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/filters/RemoteAddrFilter.java | 31 +++++++-- .../apache/catalina/filters/RemoteHostFilter.java | 30 +++++++-- .../org/apache/catalina/filters/RequestFilter.java | 73 +++++++++++++++------- 3 files changed, 103 insertions(+), 31 deletions(-) diff --git a/java/org/apache/catalina/filters/RemoteAddrFilter.java b/java/org/apache/catalina/filters/RemoteAddrFilter.java index c81ce9bba..3b8edc769 100644 --- a/java/org/apache/catalina/filters/RemoteAddrFilter.java +++ b/java/org/apache/catalina/filters/RemoteAddrFilter.java @@ -26,6 +26,8 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import org.apache.catalina.CometEvent; +import org.apache.catalina.CometFilterChain; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -54,12 +56,13 @@ public final class RemoteAddrFilter /** * Extract the desired request property, and pass it (along with the - * specified request and response objects) to the protected - * process() method to perform the actual filtering. - * This method must be implemented by a concrete subclass. + * specified request and response objects and associated filter chain) to + * the protected process() method to perform the actual + * filtering. * - * @param request The servlet request to be processed + * @param request The servlet request to be processed * @param response The servlet response to be created + * @param chain The filter chain for this request * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs @@ -71,7 +74,25 @@ public final class RemoteAddrFilter process(request.getRemoteAddr(), request, response, chain); } - + + /** + * Extract the desired request property, and pass it (along with the comet + * event and filter chain) to the protected process() method + * to perform the actual filtering. + * + * @param event The comet event to be processed + * @param chain The filter chain for this event + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + @Override + public void doFilterEvent(CometEvent event, CometFilterChain chain) + throws IOException, ServletException { + processCometEvent(event.getHttpServletRequest().getRemoteHost(), + event, chain); + } + protected Log getLogger() { return log; } diff --git a/java/org/apache/catalina/filters/RemoteHostFilter.java b/java/org/apache/catalina/filters/RemoteHostFilter.java index 8244c380a..9b5deb427 100644 --- a/java/org/apache/catalina/filters/RemoteHostFilter.java +++ b/java/org/apache/catalina/filters/RemoteHostFilter.java @@ -26,6 +26,8 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import org.apache.catalina.CometEvent; +import org.apache.catalina.CometFilterChain; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -55,12 +57,13 @@ public final class RemoteHostFilter /** * Extract the desired request property, and pass it (along with the - * specified request and response objects) to the protected - * process() method to perform the actual filtering. - * This method must be implemented by a concrete subclass. + * specified request and response objects and associated filter chain) to + * the protected process() method to perform the actual + * filtering. * - * @param request The servlet request to be processed + * @param request The servlet request to be processed * @param response The servlet response to be created + * @param chain The filter chain for this request * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs @@ -72,8 +75,27 @@ public final class RemoteHostFilter process(request.getRemoteHost(), request, response, chain); } + + /** + * Extract the desired request property, and pass it (along with the comet + * event and filter chain) to the protected process() method + * to perform the actual filtering. + * + * @param event The comet event to be processed + * @param chain The filter chain for this event + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + @Override + public void doFilterEvent(CometEvent event, CometFilterChain chain) + throws IOException, ServletException { + processCometEvent(event.getHttpServletRequest().getRemoteHost(), + event, chain); + } protected Log getLogger() { return log; } + } diff --git a/java/org/apache/catalina/filters/RequestFilter.java b/java/org/apache/catalina/filters/RequestFilter.java index 98f7231a6..ff12fd258 100644 --- a/java/org/apache/catalina/filters/RequestFilter.java +++ b/java/org/apache/catalina/filters/RequestFilter.java @@ -30,6 +30,9 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; +import org.apache.catalina.CometEvent; +import org.apache.catalina.CometFilter; +import org.apache.catalina.CometFilterChain; import org.apache.tomcat.util.res.StringManager; /** @@ -67,7 +70,7 @@ import org.apache.tomcat.util.res.StringManager; */ public abstract class RequestFilter - extends FilterBase { + extends FilterBase implements CometFilter { // ----------------------------------------------------- Class Variables @@ -253,44 +256,70 @@ public abstract class RequestFilter ServletResponse response, FilterChain chain) throws IOException, ServletException { - // Check the deny patterns, if any + if (isAllowed(property)) { + chain.doFilter(request, response); + } else { + if (isHttpServletResponse(response)) { + ((HttpServletResponse) response) + .sendError(HttpServletResponse.SC_FORBIDDEN); + } else { + sendErrorWhenNotHttp(response); + } + } + } + + /** + * Perform the filtering that has been configured for this Filter, matching + * against the specified request property. + * + * @param property The property to check against the allow/deny rules + * @param event The comet event to be filtered + * @param chain The comet filter chain + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + protected void processCometEvent(String property, CometEvent event, CometFilterChain chain) + throws IOException, ServletException { + HttpServletResponse response = event.getHttpServletResponse(); + + if (isAllowed(property)) { + chain.doFilterEvent(event); + } else { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + event.close(); + } + } + + /** + * Process the allow and deny rules for the provided property. + * + * @param property The property to test against the allow and deny lists + * @return true if this request should be allowed, + * false otherwise + */ + private boolean isAllowed(String property) { for (int i = 0; i < this.denies.length; i++) { if (this.denies[i].matcher(property).matches()) { - if (isHttpServletResponse(response)) { - ((HttpServletResponse) response) - .sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } else { - sendErrorWhenNotHttp(response); - return; - } + return false; } } - + // Check the allow patterns, if any for (int i = 0; i < this.allows.length; i++) { if (this.allows[i].matcher(property).matches()) { - chain.doFilter(request, response); - return; + return true; } } // Allow if denies specified but not allows if ((this.denies.length > 0) && (this.allows.length == 0)) { - chain.doFilter(request, response); - return; + return true; } // Deny this request - if (isHttpServletResponse(response)) { - ((HttpServletResponse) response) - .sendError(HttpServletResponse.SC_FORBIDDEN); - } else { - sendErrorWhenNotHttp(response); - } + return false; } - private void sendErrorWhenNotHttp(ServletResponse response) throws IOException { response.setContentType(PLAIN_TEXT_MIME_TYPE); -- 2.11.0