Application Layer Switching Module for Apache

Control Scripts

Control scripts can be used for performing powerful traffic manipulation operations and advanced load balancing decisions. Control scripts are normal Perl sub-routines which are called at different phases of request processing cycle.

Request Processing Cycle

warning TODO: image of request processing cycle...

Event Functions

Server events
ON_STARTUP Triggered when server is starting up or after configurations are re-loaded
ON_SHUTDOWN Triggered when server is shutting down or before configurations are re-loaded
HTTP events
ON_REQUEST Triggered when HTTP request line and headers are received and processed before they are sent to server pool
ON_REQUEST_DATA Triggered when HTTP request body is being sent to server (may be triggered 0...N times)
ON_RESPONSE Triggered when HTTP response status line and headers are received and processed before they are sent to client
ON_RESPONSE_DATA Triggered when HTTP response body is being sent to the client (may be triggered 0...N times)
ON_LBFAILURE Triggered when selected pool member was unavailable, it is possible to send HTTP redirect or attempt to connect to other pool.


info Please use convienence routine L7::Runtime::OBJECTS(@_) to obtain handles to event functions objects. This method hides the Perl XS method call parameters from event functions. This is subject to change in future releases; propably event function specific methods like L7::Runtime::ON_REQUEST(@_), L7::Runtime::ON_RESPONSE(@_), ...


L7::Runtime object re-presents mod_layer runtime and provides access to configured items such as pools and pool members...


Select L7Pool for processing current request.


Select specific pool member identified by $url.


Get number of configured pool members for pool $poolName.


Get number of available pool members for pool $poolName.


L7::HTTPRequest object re-presents current HTTP request and provides access to common request properties such as URI and request headers. It is also possible to manipulate request properties within ON_REQUEST event function. Attempt to manipulate request properties in other event functions may fail silently, cause module to crash or simply have no actual effect.


Get client IP address as string.


Get client TCP port number as integer value.


Get HTTP request URI for current request.


Set HTTP request URI to value $uri. This can be used for request URI rewriting in ON_REQUEST event function before request is directed to L7Pool for processing.


Get current query string.


Set query string before request is passed to L7Pool for processing.

info This method should be used only in ON_REQUEST event function


Get current HTTP request method name (eg. "GET", "POST", ..).


Get HTTP request header $hdrName from current request properties.

set_header($hdrName, $hdrValue)

Set HTTP request header $hdrName to value $hdrValue.

add_header($hdrName, $hdrValue)

Add HTTP request header $hdrName with value $hdrValue.


Remove HTTP request header with name $hdrName.


warning TODO: document methods in L7::HTTPResponse object...


Get HTTP response header $hdrName.

add_header($hdrName, $hdrValue)

Add HTTP response header $hdrName with value $hdrValue.


Remove HTTP response header $hdrName before response is sent to client.

send_redirect($url[, $status])

Send HTTP redirect to location specified by $url. It is possible to specify HTTP status code used for redirect by giving optional $status parameter (default: 303).


Specify whether caching may or may not be used. Caching functionality is provided by mod_cache.


Example 1 - Select Pool

This example shows how control script can be used for selecting to which L7Pool current request is directed.

Apache Configuration


# load mod_proxy module(s) required for reverse proxy operations..
LoadModule proxy_module      /opt/local/apache/2.2.15+dso/modules/
LoadModule proxy_module_http /opt/local/apache/2.2.15+dso/modules/
LoadModule proxy_module_ajp  /opt/local/apache/2.2.15+dso/modules/

# load mod_layer7 module
LoadModule layer7_module /opt/local/mod_layer7/0.1.0/modules/

# Pool for web-application (tomcat)
# NOTE: first defined pool is default pool 
#       use L7DefaultPool to override/explicitely define default pool

<L7Pool "dynamic-pool">
  L7PoolMember "ajp://" ratio=1.0
  L7PoolMember "ajp://" ratio=1.0
  L7PoolMember "ajp://" ratio=0.5

  L7BalancingMethod "round-robin"
  L7PersistMethod   "cookie-insert"

# pool of normal HTTP servers for static content
# (eg. images, css files, ...)

<L7Pool "static-pool">
  L7PoolMember "" ratio=1.2
  L7PoolMember "" ratio=1.0

# You could also use mod_proxy_balancer pools
# <L7Pool "balancer-pool">
#  L7PoolMember "balancer://mycluster"
# </L7Pool>  
# <Proxy balancer://mycluster>
# BalancerMember
# BalancerMember
# </Proxy>

L7DefaultPool     "dynamic-pool"
L7PerlScript      ""

# define sub-routine names to be called on different 
# events during HTTP request processing cycle.
L7EventFunction ON_REQUEST   on_request
L7EventFunction ON_RESPONSE  on_response
L7EventFunction ON_LBFAILURE on_lbfailure
# L7EventFunction ON_STARTUP   on_startup
# L7EventFunction ON_SHUTDOWN  on_shutdown

Control Script


# -*-perl-*- 
# To use this file use configuration directive:
# L7PerlScript /path/to/this/
# See: for more details

use L7::Runtime;

# L7EventFunction ON_REQUEST on_request

sub on_request
    # obtain handle to context,request and response objects..
    # my ($context, $request, $response) = L7::Runtime::ON_REQUEST(@_);
    my ($context, $request, $response) = L7::Runtime::OBJECTS(@_);
    my $uri = $request->get_uri();
    # select 'static-pool' with criteria based on 
    # request URI..
    if (index($uri, "/static") >= 0) {
    } else {
        # use default pool (== dynamic pool)

    # you could do other things like...
    $request->add_header('X-Client-Address', $request->get_client_ip());
    $request->add_header('X-Client-Port',    $request->get_client_port());

# L7EventFunction ON_REQUEST on_response

sub on_response
    # obtain handle to context,request and response objects..
    # my ($context, $request, $response) = L7::Runtime::ON_RESPONSE(@_);
    my ($context, $request, $response) = L7::Runtime::OBJECTS(@_);

    # security by obscurity
    $response->set_header('Server', 'Acme-HTTP-Server');
    # ...

# L7EventFunction ON_LBFAILURE on_failure

sub on_lbfailure
    # obtain handle to context,request and response objects..
    # my ($context, $request, $response) = L7::Runtime::ON_LBFAILURE(@_);
    my ($context, $request, $response) = L7::Runtime::OBJECTS(@_);
    my $uri     = $request->get_uri();
    my $count   = $request->get_retry_count();
    $request->set_header('X-Layer7-LBFAILURE-URI', $uri);
    # warn "$$ : PERL($0) :: on_lbfailure() retry_count: $count - URI: $uri\n";
    if ($count > 1) {
        # change pool and retry ...
    return 0;

warning Use L7::Runtime::OBJECTS(@_) to obtain handles to event functions objects.

Example 2 - Request rewriting

This example shows hot to perform simple request rewriting ...

Apache Configuration


Control Script


Get mod_layer7 for Apache 2.x at Fast, secure and Free Open Source software downloads