The sample blacklisting plugin included in the Traffic Server SDK
is blacklist_1.c
. This plugin checks every incoming
HTTP client request against a list of blacklisted web sites. If the
client requests a blacklisted site, then the plugin returns an
Access forbidden
message to the client.
The flow of HTTP
processing with the blacklist plugin is illustrated in the figure titled “Blacklist Plugin”. This example also contains a
simple configuration management interface. It can read a list of
blacklisted sites from a file (blacklist.txt
) that
can be updated by a Traffic Server administrator. When the configuration
file is updated, Traffic Server sends an event to the plugin that wakes
it up to do some work.
You create the static parent continuation in the mandatory
INKPluginInit
function. This parent continuation
effectively is the plugin: the plugin
does work when this continuation receives an event from Traffic
Server. Traffic Server passes the event as an argument to the
continuation’s handler function. When you create continuations, you
must create and specify their handler functions.
You can specify an optional mutex lock when you create continuations. The mutex lock protects data shared by asynchronous processes. Because Traffic Server has a multi-threaded design, race conditions can occur if several threads try to access the same continuation’s data.
Here is how the static parent continuation is created in
blacklist-1.c
void INKPluginInit (int argc, const char *argv[]) { ... INKCont contp; contp = INKContCreate (blacklist_plugin, NULL); ... }
:
The handler function for the plugin is blacklist_plugin
, and the
mutex is null. The continuation handler function’s job is to handle
the events that are sent to it; accordingly, the blacklist_plugin
routine consists of a switch
statement that covers each of the events that might be sent to
it:
static int blacklist_plugin (INKCont contp, INKEvent event, void *edata) { INKHttpTxn txnp = (INKHttpTxn) edata; switch (event) { case INK_EVENT_HTTP_OS_DNS: handle_dns (txnp, contp); return 0; case INK_EVENT_HTTP_SEND_RESPONSE_HDR: handle_response (txnp); return 0; case INK_EVENT_MGMT_UPDATE: read_blacklist (); return 0; default: break; } return 0; }
When you write handler functions, you have to anticipate any
events that might be sent to the handler by hooks or by other
functions. In the Blacklist plugin, INK_EVENT_OS_DNS
is
sent because of the global hook established in
INKPluginInit
,
INK_EVENT_HTTP_SEND_RESPONSE_HDR
is sent because the
plugin contains a transaction hook (see Setting Up a Transaction Hook), and
INK_EVENT_MGMT_UPDATE
is sent by Traffic Manager whenever
there is a configuration change (see Setting Up UI Update Callbacks). It is good practice to have a
default case in your switch statements.