Class ParameterLimitValve

All Implemented Interfaces:
MBeanRegistration, Contained, JmxEnabled, Lifecycle, Valve

public class ParameterLimitValve extends ValveBase
This is a concrete implementation of ValveBase that allows alternative values for the Connector attributes maxParameterCount, maxPartCount and maxPartHeaderSize to be applied to a request. The features of this implementation include:
  • URL-specific parameter limits that can be defined using regular expressions
  • Configurable through Tomcat's server.xml or context.xml
  • URL-specific parameter limits may optionally be defined in a parameter_limit.config file. When present, it must be placed in the Host configuration folder or in the WEB-INF folder of the web application. Without this file the valve can be configured dynamically using the management operations.

The default limit, specified by Connector's value, applies to all requests unless a more specific URL pattern is matched. URL patterns and their corresponding limits can be configured via a regular expression mapping through the urlPatternLimits attribute.

The Valve checks each incoming request and enforces the appropriate limit. If several patterns match a request, the first matching pattern in configuration order is applied. If a request exceeds the allowed number of parameters, a 400 Bad Request response is returned.

Example, configuration in context.xml:


<Context>
    <Valve className="org.apache.catalina.valves.ParameterLimitValve"/>
</Context>

and in parameter_limit.config:

/api/.*=150
/admin/.*=50
/upload/.*=30,5,1024

The configuration allows for flexible control over different sections of your application, such as applying higher limits for API endpoints and stricter limits for admin areas.

If a single integer is provided, it is used for maxParameterCount.

If three integers are provided, they are applied to maxParameterCount, maxPartCount and maxPartHeaderSize respectively.

  • Constructor Details

    • ParameterLimitValve

      public ParameterLimitValve()
      Construct a new ParameterLimitValve instance.
  • Method Details

    • getResourcePath

      public String getResourcePath()
      Returns the relative path to the configuration file.
      Returns:
      the relative path to the configuration file
    • setResourcePath

      public void setResourcePath(String resourcePath)
      Set the relative path to the configuration file.
      Parameters:
      resourcePath - the relative path to the configuration file
    • initInternal

      protected void initInternal() throws LifecycleException
      Description copied from class: LifecycleBase
      Subclasses implement this method to perform any instance initialisation required.
      Overrides:
      initInternal in class ValveBase
      Throws:
      LifecycleException - If the initialisation fails
    • startInternal

      protected void startInternal() throws LifecycleException
      Description copied from class: ValveBase
      Start this component and implement the requirements of LifecycleBase.startInternal().
      Overrides:
      startInternal in class ValveBase
      Throws:
      LifecycleException - if this component detects a fatal error that prevents this component from being used
    • setUrlPatternLimits

      public void setUrlPatternLimits(String urlPatternConfig)
      Set the mapping of URL patterns to their corresponding parameter limits from a string containing the configuration. The new limits replace any previously configured limits. The limits are only applied if the complete configuration is parsed successfully. If parsing fails, the exception is propagated and any previously configured limits are left unchanged.
      Parameters:
      urlPatternConfig - The URL pattern to parameter limit mappings
    • setUrlPatternLimits

      public void setUrlPatternLimits(BufferedReader reader)
      Set the mapping of URL patterns to their corresponding parameter limits. The input should be provided line by line, where each line contains a pattern and a limit, separated by the last '='. The parsed limits are added after any previously configured limits. If a parsed pattern has the same regular expression as an already configured pattern, its limit replaces the previous one at the original position, preserving the configuration order used to select the matching pattern. The same applies to a pattern repeated within the input. The parsed limits are only applied if the complete input is parsed successfully. If parsing fails, the exception is propagated and any previously configured limits are left unchanged. If a read error occurs, it is logged and the input read so far is discarded without modifying the configured limits.

      Example:

      /api/.*=50
      /api======/.*=150
      /urlEncoded%20api=2
      # This is a comment
      
      Parameters:
      reader - A BufferedReader containing URL pattern to parameter limit mappings, with each pair on a separate line.
    • stopInternal

      protected void stopInternal() throws LifecycleException
      Description copied from class: ValveBase
      Stop this component and implement the requirements of LifecycleBase.stopInternal().
      Overrides:
      stopInternal in class ValveBase
      Throws:
      LifecycleException - if this component detects a fatal error that prevents this component from being used
    • invoke

      public void invoke(Request request, Response response) throws IOException, ServletException

      Perform request processing as required by this Valve.

      An individual Valve MAY perform the following actions, in the specified order:

      • Examine and/or modify the properties of the specified Request and Response.
      • Examine the properties of the specified Request, completely generate the corresponding Response, and return control to the caller.
      • Examine the properties of the specified Request and Response, wrap either or both of these objects to supplement their functionality, and pass them on.
      • If the corresponding Response was not generated (and control was not returned), call the next Valve in the pipeline (if there is one) by executing getNext().invoke().
      • Examine, but not modify, the properties of the resulting Response (which was created by a subsequently invoked Valve or Container).

      A Valve MUST NOT do any of the following things:

      • Change request properties that have already been used to direct the flow of processing control for this request (for instance, trying to change the virtual host to which a Request should be sent from a pipeline attached to a Host or Context in the standard implementation).
      • Create a completed Response AND pass this Request and Response on to the next Valve in the pipeline.
      • Consume bytes from the input stream associated with the Request, unless it is completely generating the response, or wrapping the request before passing it on.
      • Modify the HTTP headers included with the Response after the getNext().invoke() method has returned.
      • Perform any actions on the output stream associated with the specified Response after the getNext().invoke() method has returned.

      Checks if any of the defined patterns matches the URI of the request and if it does, enforces the parameter limit of the first matching pattern in configuration order. Then invoke the next Valve in the sequence.

      Parameters:
      request - The servlet request to be processed
      response - The servlet response to be created
      Throws:
      IOException - if an input/output error occurs, or is thrown by a subsequently invoked Valve, Filter, or Servlet
      ServletException - if a servlet error occurs, or is thrown by a subsequently invoked Valve, Filter, or Servlet