NAME
Net::IMP::Base - base class to make writing of Net::IMP analyzers easier
SYNOPSIS
package myPlugin;
use base 'Net::IMP::Base';
use fields qw(... local fields ...);
# plugin methods
# sub new_factory ... - has default implementation
# sub cfg2str ... - has default implementation
# sub str2cfg ... - has default implementation
sub validate_cfg ... - needs to be implemented
# factory methods
sub INTERFACE ... - needs to be implemented
# sub get_interface .. - has default implementation using sub INTERFACE
# sub set_interface .. - has default implementation using sub INTERFACE
# sub new_analyzer ... - has default implementation
# analyzer methods
sub data ... - needs to be implemented
# sub poll_results ... - has default implementation
# sub set_callback ... - has default implementation
DESCRIPTION
Net::IMP::Base
is a class to make it easier to write IMP analyzers. It can not be used on its own but should be used as a base class in new analyzers.
It provides the following interface for the global plugin API as required for all Net::IMP plugins.
- cfg2str|str2cfg
-
These functions are used to convert a
%config
to or from a$string
. In this implementation the <$string> is a single line, encoded similar to the query_string in HTTP URLs.There is no need to re-implement this function unless you want to serialize the config into a different format.
- $class->validate_cfg(%config) -> @errors
-
This function is used to verify the config and thus should be re-implemented in each sub-package. It is expected to return a list of errors or an empty list if the config has no errors.
The only valid entry for %config in the implementation in this package is
eventlib
, which provides a way for analyzers to hook into the data providers event handling. If there are any other entries are left in%config
it will complain. Thus all arguments specific to the derived analyzer should be handled in a derivedvalidate_cfg
method and removed from%config
before calling the method in this base class. - $class->new_factory(%args)
-
This function is used to create a new factory class.
%args
will be saved into$factory-
{factory_args}> and later used when creating the analyzer. There is usually no need to re-implement this method.The only argument provided by some data providers to this base class is
eventlib
, which provides an interface to the data providers event handling. It must be defined as an object with the following API, so that analyzers can hook into it:- $ev->onread( filehandle,[ callback ])
-
Sets or removes callback for read events on filehandle.
- $ev->onwrite( filehandle,[ callback ])
-
Sets or removes callback for write events on filehandle.
- $ev->timer( after, callback, [ interval ])
-
Sets
callback
to be executed afterafter
seconds. Reschedules timer afterwards everyinterval
seconds ifinterval
is given. Returns object which must be preserved by the caller, the timer will be cancelled if the object gets undefined. - $ev->now
-
Returns the eventlibs idea of the current time.
If
eventlib
is not given some classes might refuse creation of the factory object.
The following methods are implemented on factory objects as required by Net::IMP:
- $factory->get_interface(@caller_if) => @plugin_if
-
This method provides an implementation of the
get_interface
API function. This implementation requires the implementation of a functionINTERFACE
like this:sub INTERFACE { return ( [ # require HTTP data types IMP_DATA_HTTP, # input data types/protocols [ IMP_PASS, IMP_LOG ] # output return types ],[ # we can handle stream data too if we use a suitable adaptor IMP_DATA_STREAM, [ IMP_PASS, IMP_LOG ], 'Net::IMP::Adaptor::STREAM2HTTP', ] )}
There is no need to re-implement method
get_interface
, butINTERFACE
should be implemented. If your plugin can handle any data types you can set the type toundef
in the interface description. - $factory->set_interface($want_if) => $new_factory
-
This method provides an implementation of the
set_interface
API function. This implementation requires the implementation ofINTERFACE
like described forget_interface
. There is no need to re-implement methodset_interface
, butINTERFACE
should be implemented. - $factory->new_analyzer(%args)
-
This method is called from
<$factory-
new_analyzer(%fargs)>> for creating the analyzer for a new pair of data streams.This implementation will create a new analyzer object based on the factory object, e.g. it will use %args for the fields in the analyzer but also provide access to the args given when creating the factory within field
factory_args
.If the interface required an adaptor it will wrap the newly created analyzer into the adaptor with
$analyzer = $adaptor_class->new($analyzer)
.Derived classes should handle (and remove) all local settings from
%args
and then call<$class-
SUPER::new_analyzer(%rest_args)>> to construct$analyzer
.This method might generate results already. This might be the case, if it needs to analyze only one direction (e.g. issue IMP_PASS with IMP_MAXOFFSET for the other direction) or if it needs to only intercept data but not deny or modify based on the data (e.g. issue IMP_PREPASS with IMP_MAXOFFSET).
Net::IMP::Base
supports only two elements in%args
, any other elements will cause an error:- meta
-
This will be stored in
$analyzer-
{meta}>. Usually used for storing context specific information from the application. Some modules (like Net::IMP::SessionLog) depend onmeta
providing a hash reference with specific entries. - cb
-
This is the callback and will be stored in
$analyzer-
{analyzer_cb}>. Callback should be specified as an array reference with[$sub,@args]
. Seeset_callback
method for more information.If you set the callback this way, you have to be prepared to handle calls to the callback immediatly, even if
new_analyzer
did not return yet. If you don't want this, useset_callback
after creating the analyzer instead.
The following methods are implemented on analyzer objects as required by Net::IMP:
- $analyzer->set_callback($sub,@args)
-
This will set the callback (
$analyzer-
{analyzer_cb}>). This method will be called from the user of the analyzer. The callback will be used withinrun_callback
and called with$sub->(@args,@results)
.If there are already collected results, the callback will be executed immediately. If you don't want this, remove these results upfront with
poll_results
. - $analyzer->poll_results
-
This will return the current
@results
and remove them from collected results. It will only be used from the caller of the analyzer if no callback is set. - $analyzer->data($dir,$data,$offset,$dtype)
-
This method should be defined for all analyzers. The implementation in this package will just croak.
- $analyzer->busy($dir,0|1)
-
This method sets direction $dir to busy. The analyzer should not propagate results for this direction until it gets unbusy again (e.g. will accumulate results for later). The exception are results which might help to solve the busy state, like IMP_DENY. Also, results not specific for this dir should still be delivered.
Also the following methods are defined for analyzers and can be used inside your own analyzer.
- $analyzer->add_results(@results)
-
This method adds new results to the list of collected results. Each result is an array reference, see Net::IMP for details.
It will usually be used in the analyzer from within the
data
method. - $analyzer->run_callback(@results)
-
Like
add_results
this will add new results to the list of collected results. Additionally it will propagate the results using the callback provided by the user of the analyzer. It will propagate all spooled results and new results given to this method.
AUTHOR
Steffen Ullrich <sullr@cpan.org>
COPYRIGHT
Copyright by Steffen Ullrich.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.