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
EVENT DESCRIPTION
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
EVENT DESCRIPTION
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.

Classes

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

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

select_pool($poolName)

Select L7Pool for processing current request.

select_node($url)

Select specific pool member identified by $url.

get_number_of_pool_members($poolName)

Get number of configured pool members for pool $poolName.

get_number_of_available_pool_members($poolName)

Get number of available pool members for pool $poolName.

L7::HTTPRequest

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()

Get client IP address as string.

get_client_port()

Get client TCP port number as integer value.

get_uri()

Get HTTP request URI for current request.

set_uri($uri)

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_query()

Get current query string.

set_query($query)

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

info This method should be used only in ON_REQUEST event function

get_method()

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

get_header($hdrName)

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_header($hdrName)

Remove HTTP request header with name $hdrName.

L7::HTTPResponse

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

get_header($hdrName)

Get HTTP response header $hdrName.

add_header($hdrName, $hdrValue)

Add HTTP response header $hdrName with value $hdrValue.

remove_header($hdrName)

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).

use_caching($flag)

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

Examples

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/mod_proxy.so
LoadModule proxy_module_http /opt/local/apache/2.2.15+dso/modules/mod_proxy_http.so
LoadModule proxy_module_ajp  /opt/local/apache/2.2.15+dso/modules/mod_proxy_ajp.so

# load mod_layer7 module
LoadModule layer7_module /opt/local/mod_layer7/0.1.0/modules/libmod_layer7.so

# 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://10.0.0.12:5090" ratio=1.0
  L7PoolMember "ajp://10.0.0.13:5090" ratio=1.0
  L7PoolMember "ajp://10.0.0.14:5090" ratio=0.5

  L7BalancingMethod "round-robin"
  L7PersistMethod   "cookie-insert"
</L7Pool>

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

<L7Pool "static-pool">
  L7PoolMember "http://10.0.0.20" ratio=1.2
  L7PoolMember "http://10.0.0.21" ratio=1.0
</L7Pool>

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

L7DefaultPool     "dynamic-pool"
L7PerlScript      "example1.pl"

# 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/file.pl
#
# See: http://layer7.sourceforge.net/config.html 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) {
        $context->select_pool("static-pool");
    } 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 ...
        $context->select_pool("fallback-pool");
    }
    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 SourceForge.net. Fast, secure and Free Open Source software downloads