The Scripting filter enables users to write custom filters for Repose using a variety of scripting languages. Custom filters can be used to perform arbitrary processing with access to the bindings described below.

General filter information

  • Name: scripting

  • Default Configuration: scripting.cfg.xml

  • Released: v8.0.0.0

  • Bundle: repose-filter-bundle

  • Schema

Prerequisites & Postconditions

Required Request Headers

This filter does not require any request headers.

Required Preceding Filters

This filter has no dependencies on other filters and can be placed wherever it is needed in the filter chain.

Request Headers Created

Changes to request headers vary based on configuration.

Request Body Changes

Changes to the request body varies based on configuration.

This filter is not strictly required by any other filters.

Response Body Changes

Changes to the response body varies based on configuration.

Response Headers Created

Changes to response headers vary based on configuration.

Response Status Codes

Changes to the response code varies based on configuration.

Supported Scripting Languages

  • Groovy

  • Javascript

  • Python

All supported languages are currently compilable.

An enumeration of all supported language names (e.g., python and jython) that will be accepted in configuration can be found in the XML schema linked on this page.

Bindings

Bindings are variables defined by the Scripting filter which can be used in scripts.

Currently supported bindings are detailed by the following table:

Binding Name Description

request

A HttpServletRequest object containing data associated with the current request. To allow for modification of the request, the request object will be wrapped with the Repose HttpServletRequestWrapper class. All methods on the HttpServletRequestWrapper class will be available in the script.

response

A HttpServletResponse object containing data associated with the current response. To allow for more powerful modification of the response, the response object will be wrapped with the Repose HttpServletResponseWrapper class. All methods on the HttpServletResponseWrapper class will be available in the script.

filterChain

A FilterChain object for passing the request and response to the next filter in the chain.

Invoking the doFilter method on the filterChain object is necessary to pass the request/response along. If doFilter is not invoked, the scripting filter will return the response object as-is up the filter chain. No later filter nor the origin service will have a chance to process the request.

Performance

The performance of this filter will vary depending on configuration.

For the simple task of adding a header to a request, this filter performs comparably to the Add Header Filter.

Scripts written in a compilable language as shown above will always be compiled. This should dramatically improve performance.

Examples

Add A Header Using Groovy

scripting.cfg.xml
<scripting xmlns="http://docs.openrepose.org/repose/scripting/v1.0"
           language="groovy"> (1)
    request.addHeader("foo", "bar") (2)

    // Call the next filter in the chain (3)
    filterChain.doFilter(request, response) (4)
</scripting>
1 Specifies that the scripting language being used is groovy.
2 The first line of the Groovy script. Adds a request header named foo with a value of bar.
3 Comments can be used in the scriptlet just like in the native language!
4 Passes the modified request and the response on to the next component in the filter chain.

Migrate Path Segments to Query Parameters Using Python

scripting.cfg.xml
<scripting xmlns="http://docs.openrepose.org/repose/scripting/v1.0"
           language="python"><![CDATA[ (1)
path = request.getRequestURI() (2)
pathSegments = path.strip("/").split("/") (3)
queryString = request.getQueryString() (4)

if len(pathSegments) >= 2: (5)
    if queryString is not None: (6)
      queryString = queryString + "&penultimate=" + pathSegments[len(pathSegments) - 2] + "&ultimate=" + pathSegments[len(pathSegments) - 1]
    else:
      queryString = "penultimate=" + pathSegments[len(pathSegments) - 2] + "&ultimate=" + pathSegments[len(pathSegments) - 1]

    request.setQueryString(queryString) (7)
    request.setRequestURI("/" + "/".join(pathSegments[-2:]))

filterChain.doFilter(request, response) (8)
]]></scripting> (9)
1 Specifies that the scripting language being used is python. Also opens the CDATA block.
2 The first line of the Python script. Gets the request URI from the request object.
3 Removes any leading or trailing / characters from the URI. Also splits the modified URI on the / character.
4 Gets the request query string from the request object.
5 For this specific example, we assert that there are at least two path segments. If not, no request mutations are performed.
6 This conditional block appends the last two path segments as query parameters.
7 Sets the modified query string and request URI on the request object.
8 Passes the modified request and the response on to the next component in the filter chain.
9 Terminates the CDATA block and the script.

Python support is provided via Jython which contains a dependency on Apache commons-compress. This dependency has a known vulnerability when reading zip files, and so it recommended not to read any zip files from the user.