You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/06/04 12:51:32 UTC
svn commit: r1489385 [3/3] - in /tomcat/trunk:
java/org/apache/catalina/filters/ test/org/apache/catalina/filters/
webapps/docs/config/
Modified: tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletResponse.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletResponse.java?rev=1489385&r1=1489384&r2=1489385&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletResponse.java (original)
+++ tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletResponse.java Tue Jun 4 10:51:31 2013
@@ -19,7 +19,10 @@ package org.apache.catalina.filters;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
@@ -36,10 +39,66 @@ import org.apache.catalina.connector.Req
*/
public class TesterHttpServletResponse implements HttpServletResponse {
+ private PrintWriter pw;
+ private List<String> headerNames = new ArrayList<>();
+ private List<String> headerValues = new ArrayList<>();
+ private int status;
+
public TesterHttpServletResponse() {
// NOOP
}
+
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ if (pw == null) {
+ pw = new PrintWriter(new StringWriter());
+ }
+ return pw;
+ }
+
+
+ @Override
+ public String getHeader(String name) {
+ int index = headerNames.indexOf(name);
+ if (index != -1) {
+ return headerValues.get(index);
+ }
+ return null;
+ }
+
+
+ @Override
+ public void setHeader(String name, String value) {
+ int index = headerNames.indexOf(name);
+ if (index != -1) {
+ headerValues.set(index, value);
+ } else {
+ headerNames.add(name);
+ headerValues.add(value);
+ }
+ }
+
+
+ @Override
+ public void addHeader(String name, String value) {
+ headerNames.add(name);
+ headerValues.add(value);
+ }
+
+
+ @Override
+ public int getStatus() {
+ return status;
+ }
+
+
+ @Override
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+
public void setAppCommitted(
@SuppressWarnings("unused") boolean appCommitted) {/* NOOP */}
public boolean isAppCommitted() { return false; }
@@ -124,8 +183,6 @@ public class TesterHttpServletResponse i
@Override
public Locale getLocale() { return null; }
@Override
- public PrintWriter getWriter() throws IOException { return null; }
- @Override
public boolean isCommitted() { return false; }
@Override
public void reset() {/* NOOP */}
@@ -140,14 +197,10 @@ public class TesterHttpServletResponse i
@Override
public void setLocale(Locale locale) {/* NOOP */}
@Override
- public String getHeader(String name) { return null; }
- @Override
public Collection<String> getHeaderNames() { return null; }
@Override
public Collection<String> getHeaders(String name) { return null; }
public String getMessage() { return null; }
- @Override
- public int getStatus() { return -1; }
public void reset(@SuppressWarnings("unused") int status,
@SuppressWarnings("unused") String message) {/* NOOP */}
@Override
@@ -155,8 +208,6 @@ public class TesterHttpServletResponse i
@Override
public void addDateHeader(String name, long value) {/* NOOP */}
@Override
- public void addHeader(String name, String value) {/* NOOP */}
- @Override
public void addIntHeader(String name, int value) {/* NOOP */}
@Override
public boolean containsHeader(String name) { return false; }
@@ -188,11 +239,7 @@ public class TesterHttpServletResponse i
@Override
public void setDateHeader(String name, long value) {/* NOOP */}
@Override
- public void setHeader(String name, String value) {/* NOOP */}
- @Override
public void setIntHeader(String name, int value) {/* NOOP */}
- @Override
- public void setStatus(int status) {/* NOOP */}
/** @deprecated */
@Override
@Deprecated
Added: tomcat/trunk/test/org/apache/catalina/filters/TesterServletContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/filters/TesterServletContext.java?rev=1489385&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/filters/TesterServletContext.java (added)
+++ tomcat/trunk/test/org/apache/catalina/filters/TesterServletContext.java Tue Jun 4 10:51:31 2013
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.filters;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRegistration.Dynamic;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspConfigDescriptor;
+
+public class TesterServletContext implements ServletContext {
+
+ @Override
+ public String getContextPath() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public ServletContext getContext(String uripath) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public int getMajorVersion() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public int getMinorVersion() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public String getMimeType(String file) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Set<String> getResourcePaths(String path) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public URL getResource(String path) throws MalformedURLException {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String path) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path) {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public RequestDispatcher getNamedDispatcher(String name) {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Servlet getServlet(String name) throws ServletException {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Enumeration<Servlet> getServlets() {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Enumeration<String> getServletNames() {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void log(String msg) {
+ // NOOP
+ }
+
+ @Override
+ public void log(Exception exception, String msg) {
+ // NOOP
+ }
+
+ @Override
+ public void log(String message, Throwable throwable) {
+ // NOOP
+ }
+
+ @Override
+ public String getRealPath(String path) {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public String getServerInfo() {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void setAttribute(String name, Object object) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public String getServletContextName() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public int getEffectiveMajorVersion() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public int getEffectiveMinorVersion() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public boolean setInitParameter(String name, String value) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Dynamic addServlet(String servletName, String className) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Dynamic addServlet(String servletName, Servlet servlet) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Dynamic addServlet(String servletName,
+ Class<? extends Servlet> servletClass) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public <T extends Servlet> T createServlet(Class<T> c)
+ throws ServletException {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public ServletRegistration getServletRegistration(String servletName) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Map<String, ? extends ServletRegistration> getServletRegistrations() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ String filterName, String className) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ String filterName, Filter filter) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ String filterName, Class<? extends Filter> filterClass) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public <T extends Filter> T createFilter(Class<T> c)
+ throws ServletException {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public FilterRegistration getFilterRegistration(String filterName) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public SessionCookieConfig getSessionCookieConfig() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void setSessionTrackingModes(
+ Set<SessionTrackingMode> sessionTrackingModes) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void addListener(String className) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public <T extends EventListener> void addListener(T t) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void addListener(Class<? extends EventListener> listenerClass) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public <T extends EventListener> T createListener(Class<T> c)
+ throws ServletException {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public JspConfigDescriptor getJspConfigDescriptor() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public void declareRoles(String... roleNames) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ @Override
+ public String getVirtualServerName() {
+ throw new RuntimeException("Not implemented");
+ }
+
+}
Propchange: tomcat/trunk/test/org/apache/catalina/filters/TesterServletContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/webapps/docs/config/filter.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/filter.xml?rev=1489385&r1=1489384&r2=1489385&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/filter.xml (original)
+++ tomcat/trunk/webapps/docs/config/filter.xml Tue Jun 4 10:51:31 2013
@@ -98,6 +98,157 @@
</section>
+<section name="CORS Filter">
+ <subsection name="Introduction">
+ <p>This filter is an implementation of W3C's CORS (Cross-Origin Resource
+ Sharing) <a href="http://www.w3.org/TR/cors/">specification</a>, which is a
+ mechanism that enables cross-origin requests.</p>
+ <p>The filter works by adding required <code>Access-Control-*</code> headers
+ to HttpServletResponse object. The filter also protects against HTTP
+ response splitting. If request is invalid, or is not permitted, then request
+ is rejected with HTTP status code 403 (Forbidden). A
+ <a href="../images/cors-flowchart.png">flowchart</a> that
+ demonstrates request processing by this filter is available.</p>
+ <p>The minimal configuration required to use this filter is:</p>
+ <source>
+<filter>
+ <filter-name>CORSFilter</filter-name>
+ <filter-class>org.apache.catalina.filters.CORSFilter</filter-class>
+</filter>
+<filter-mapping>
+ <filter-name>CORSFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+</filter-mapping>
+ </source>
+ </subsection>
+ <subsection name="Filter Class Name">
+ <p>The filter class name for the CORS Filter is
+ <strong><code>org.apache.catalina.filters.CORSFilter</code></strong>.</p>
+ </subsection>
+ <subsection name="Initialisation parameters">
+ <p>The CORS Filter supports following initialisation parameters:</p>
+ <attributes>
+ <attribute name="cors.allowed.origins" required="false">
+ <p>A list of <a href="http://tools.ietf.org/html/rfc6454">origins</a>
+ that are allowed to access the resource. A <code>'*'</code> can be
+ specified to enable access to resource from any origin. Otherwise, a
+ whitelist of comma separated origins can be provided. Eg:
+ http://www.w3.org, https://www.apache.org.
+ <strong>Defaults:</strong> <code>*</code> (Any origin is allowed to
+ access the resource).</p>
+ </attribute>
+ <attribute name="cors.allowed.methods" required="false">
+ <p>A comma separated list of HTTP methods that can be used to access the
+ resource, using cross-origin requests. These are the methods which will
+ also be included as part of 'Access-Control-Allow-Methods' header in a
+ pre-flight response. Eg: <code>GET,POST</code>.
+ <strong>Defaults:</strong> <code>GET,POST,HEAD,OPTIONS</code></p>
+ </attribute>
+ <attribute name="cors.allowed.headers" required="false">
+ <p>A comma separated list of request headers that can be used when
+ making an actual request. These header will also be returned as part of
+ <code>'Access-Control-Allow-Headers'</code> header in a pre-flight
+ response. Eg: <code>Origin,Accept</code>. <strong>Defaults:</strong>
+ <code>Origin, Accept, X-Requested-With, Content-Type,
+ Access-Control-Request-Method, Access-Control-Request-Headers</code></p>
+ </attribute>
+ <attribute name="cors.exposed.headers" required="false">
+ <p>A comma separated list of headers other than the simple response
+ headers that browsers are allowed to access. These are the headers which
+ will also be included as part of 'Access-Control-Expose-Headers' header
+ in the pre-flight response. Eg:
+ <code>X-CUSTOM-HEADER-PING,X-CUSTOM-HEADER-PONG</code>.
+ <strong>Default:</strong> None. Non-simple headers are not exposed by
+ default.</p>
+ </attribute>
+ <attribute name="cors.preflight.maxage" required="false">
+ <p>The amount of seconds, browser is allowed to cache the result of the
+ pre-flight request. This will be included as part of
+ <code>'Access-Control-Max-Age'</code> header in the pre-flight response.
+ A negative value will prevent CORS Filter from adding this response
+ header from pre-flight response. <strong>Defaults:</strong>
+ <code>1800</code></p>
+ </attribute>
+ <attribute name="cors.support.credentials" required="false">
+ <p>A flag that indicates whether the resource supports user credentials.
+ This flag is exposed as part of
+ <code>'Access-Control-Allow-Credentials'</code> header in a pre-flight
+ response. It helps browser determine whether or not an actual request
+ can be made using credentials. <strong>Defaults:</strong>
+ <code>true</code></p>
+ </attribute>
+ <attribute name="cors.request.decorate" required="false">
+ <p>A flag to control if CORS specific attributes should be added to
+ HttpServletRequest object or not. <strong>Defaults:</strong>
+ <code>true</code></p>
+ </attribute>
+ </attributes>
+ <p>Here's an example of a more advanced configuration, that overrides
+ defaults:</p>
+ <source>
+<filter>
+ <filter-name>CORSFilter</filter-name>
+ <filter-class>org.apache.catalina.filters.CORSFilter</filter-class>
+ <init-param>
+ <param-name>cors.allowed.origins</param-name>
+ <param-value>*</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cors.allowed.methods</param-name>
+ <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cors.allowed.headers</param-name>
+ <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cors.exposed.headers</param-name>
+ <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cors.support.credentials</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cors.preflight.maxage</param-name>
+ <param-value>10</param-value>
+ </init-param>
+</filter>
+<filter-mapping>
+ <filter-name>CORS Filter</filter-name>
+ <url-pattern>/*</url-pattern>
+</filter-mapping>
+ </source>
+ </subsection>
+ <subsection name="CORS Filter and HttpServletRequest attributes">
+ <p>CORS Filter adds information about a request, in the HttpServletRequest
+ object, for consumption downstream. Following attributes are set, if
+ <code>cors.request.decorate</code> initialisation parameter is
+ <code>true</code>:</p>
+ <ul>
+ <li><strong>cors.isCorsRequest:</strong> Flag to determine if a request is
+ a CORS request.</li>
+ <li><strong>cors.request.origin:</strong> The Origin URL, i.e. the URL of
+ the page from where the request is originated.</li>
+ <li><strong>cors.request.type:</strong> Type of CORS request. Possible
+ values:
+ <ul>
+ <li><code>SIMPLE</code>: A request which is not preceded by a
+ pre-flight request.</li>
+ <li><code>ACTUAL</code>: A request which is preceded by a pre-flight
+ request.</li>
+ <li><code>PRE_FLIGHT</code>: A pre-flight request.</li>
+ <li><code>NOT_CORS</code>: A normal same-origin request.</li>
+ <li><code>INVALID_CORS</code>: A cross-origin request, which is
+ invalid.</li>
+ </ul>
+ </li>
+ <li><strong>cors.request.headers:</strong> Request headers sent as
+ 'Access-Control-Request-Headers' header, for a pre-flight request.
+ </li>
+ </ul>
+ </subsection>
+</section>
<section name="CSRF Prevention Filter">
@@ -525,6 +676,49 @@ FINE: Request "/docs/config/manager.html
</section>
+<section name="Failed Request Filter">
+
+ <subsection name="Introduction">
+
+ <p>This filter triggers parameters parsing in a request and rejects the
+ request if some parameters were skipped during parameter parsing because
+ of parsing errors or request size limitations (such as
+ <code>maxParameterCount</code> attribute in a
+ <a href="http.html">Connector</a>).
+ This filter can be used to ensure that none parameter values submitted by
+ client are lost.</p>
+
+ <p>Note that parameter parsing may consume the body of an HTTP request, so
+ caution is needed if the servlet protected by this filter uses
+ <code>request.getInputStream()</code> or <code>request.getReader()</code>
+ calls. In general the risk of breaking a web application by adding this
+ filter is not so high, because parameter parsing does check content type
+ of the request before consuming the request body.</p>
+
+ <p>Note, that for the POST requests to be parsed correctly, a
+ <code>SetCharacterEncodingFilter</code> filter must be configured above
+ this one. See CharacterEncoding page in the FAQ for details.</p>
+
+ <p>The request is rejected with HTTP status code 400 (Bad Request).</p>
+
+ </subsection>
+
+ <subsection name="Filter Class Name">
+
+ <p>The filter class name for the Failed Request Filter is
+ <strong><code>org.apache.catalina.filters.FailedRequestFilter</code>
+ </strong>.</p>
+
+ </subsection>
+
+ <subsection name="Initialisation parameters">
+
+ <p>The Failed Request Filter does not support any initialization parameters.</p>
+
+ </subsection>
+
+</section>
+
<section name="Remote Address Filter">
<subsection name="Introduction">
@@ -1265,52 +1459,6 @@ org.apache.catalina.filters.RequestDumpe
</section>
-
-<section name="Failed Request Filter">
-
- <subsection name="Introduction">
-
- <p>This filter triggers parameters parsing in a request and rejects the
- request if some parameters were skipped during parameter parsing because
- of parsing errors or request size limitations (such as
- <code>maxParameterCount</code> attribute in a
- <a href="http.html">Connector</a>).
- This filter can be used to ensure that none parameter values submitted by
- client are lost.</p>
-
- <p>Note that parameter parsing may consume the body of an HTTP request, so
- caution is needed if the servlet protected by this filter uses
- <code>request.getInputStream()</code> or <code>request.getReader()</code>
- calls. In general the risk of breaking a web application by adding this
- filter is not so high, because parameter parsing does check content type
- of the request before consuming the request body.</p>
-
- <p>Note, that for the POST requests to be parsed correctly, a
- <code>SetCharacterEncodingFilter</code> filter must be configured above
- this one. See CharacterEncoding page in the FAQ for details.</p>
-
- <p>The request is rejected with HTTP status code 400 (Bad Request).</p>
-
- </subsection>
-
- <subsection name="Filter Class Name">
-
- <p>The filter class name for the Failed Request Filter is
- <strong><code>org.apache.catalina.filters.FailedRequestFilter</code>
- </strong>.</p>
-
- </subsection>
-
- <subsection name="Initialisation parameters">
-
- <p>The Failed Request Filter does not support any initialization parameters.</p>
-
- </subsection>
-
-</section>
-
-
</body>
-
</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org