1Perlbal::Manual::PluginUss(e3r)Contributed Perl DocumentPaetrilobnal::Manual::Plugins(3)
2
3
4

NAME

6       Perlbal::Manual::Plugins - Creating and using plugins
7
8   VERSION
9       Perlbal 1.78.
10
11   DESCRIPTION
12       How to create and use Perlbal plugins.
13
14   How to use a plugin
15       Perlbal supports plugins through modules under "Perlbal::Plugin::*"
16       that implement a set of functions described further down this document.
17
18       Some of these plugins are shipped with Perlbal itself, while others can
19       be found on CPAN (you can also create your own plugin and have it
20       available only locally).
21
22       In order to use a plugin you first have to load it; on your Perlbal's
23       configuration file add something like:
24
25           Load MyPlugin
26
27       This loads plugin "Perlbal::Plugin::MyPlugin".
28
29       Each plugin will have its own way of being configured (some don't
30       require any configuration at all), so you'll have to refer to their
31       documentation (or code).
32
33       Typically (but not always), a plugin will allow you to set additional
34       parameters to a service; for instance:
35
36           LOAD MaxContentLength
37           CREATE SERVICE example
38               SET max_content_length  = 100000
39               SET plugins             = MaxContentLength
40
41       "max_content_length" is a parameter of
42       Perlbal::Plugin::MaxContentLength.
43
44       If you're worried that two plugins may have the same parameter, of if
45       you simply want to define those variables all in the same spot and thus
46       will be doing it outside of the plugin's context, you can use the more
47       verbose syntax:
48
49           SET my_service.my_plugin.my_variable = my_value
50
51       Notice that some plugins need to be stated service by service; hence,
52       this line:
53
54               SET plugins             = MaxContentLength
55
56       The "plugins" parameter (a list of strings separated by commas or
57       spaces) defines which plugins are acceptable for a service.
58
59       Troubleshooting
60
61       If you try to load a plugin and receive the following error message:
62
63           ERROR: Can't locate Perlbal/Plugin/MyPlugin.pm in @INC
64
65       That means that either the plugin isn't installed or perlbal couldn't
66       find it. (perhaps it is installed in a different version of perl other
67       than the one used to run perlbal?)
68
69   How to create a plugin
70       A Perlbal plugin consists in a package under the "Perlbal::Plugin"
71       namespace that implements a number of functions: "register",
72       "unregister", "load" and "unload".
73
74       These steps and functions (plus some helper functions you can define or
75       use) are described below.
76
77       PLEASE KEEP IN MIND: Perlbal is a single-process, asynchronous web
78       server. You must not do things in plugins which will cause it to block,
79       or no other requests can be served at the same time.
80
81       Creating a package
82
83       While there are many ways of creating a package, we'd recommend that
84       you use something to do it for you. A good option is Module::Starter.
85
86       (note: if you really want to, you can just create a file with your
87       package and use it; by using something like Module::Starter you're
88       making sure that several pitfalls are avoided, lots of basic rules are
89       followed and that your package can easily be made available as a
90       distribution that you can deploy on any machine - or, if you feel so
91       inclined, upload to CPAN - in a simple way)
92
93       Let's assume you want to create a plugin that checks requests for a
94       "X-Magic" header and, if present, add an header "X-Color" to the
95       response when serving a file. Let's assume your plugin will be called
96       "Perlbal::Plugin::ColorOfMagic".
97
98       Having installed Module::Starter, here's a command you can run that
99       will create your package for you:
100
101           $ module-starter --module=Perlbal::Plugin::ColorOfMagic --author="My name" --email=my@email.address
102
103       That should create a file tree that you can get better acquainted with
104       by reading Module::Starter's fine documentation. For this example, the
105       file you really need should now reside in
106       "lib/Perlbal/Plugin/ColorOfMagic.pm".
107
108       This file probably starts with something like the following:
109
110           package Perlbal::Plugin::ColorOfMagic;
111
112           use warnings;
113           use strict;
114
115       You'll have to add a few functions to this file. These are described
116       below.
117
118       (note: upon creating this package, some boilerplate documentation will
119       also be present on the file; you should revise it and even remove bits
120       that don't feel right for your plugin)
121
122       register
123
124       "register" is called when the plugin is being added to a service. This
125       is where you register your plugin's hooks, if required (see
126       Perlbal::Manual::Hooks for the list of existing hooks and further
127       documentation on how they work).
128
129       For the sake of our example ("Perlbal::Plugin::ColorOfMagic", see
130       above), what we want to do is register a hook that modifies the
131       response headers; that means we want a "modify_response_headers" hook.
132
133       Here's what you'd do:
134
135           sub register {
136               my ($class, $service) = @_;
137
138               my $my_hook_code = sub {
139
140                   my Perlbal::ClientHTTPBase $cp = shift;
141
142                   if ( $cp->{req_headers}->header('X-Magic') ) {
143                       $cp->{res_headers}->header( 'X-Color', 'Octarine' );
144                   }
145
146                   return 0;
147               };
148
149               $service->register_hook('ColorOfMagic','modify_response_headers', $my_hook_code);
150           }
151
152       Inside "register", we're calling "register_hook" to register our
153       "ColorOfMagic" "modify_response_headers" hook. Its code, that will run
154       "when we've set all the headers, and are about to serve a file" (see
155       Perlbal::Manual::Hooks), receives a Perlbal::ClientHTTPBase object (you
156       can see what kind of object your hook will receive on
157       Perlbal::Manual::Hooks). We're checking to see if "X-Magic" is defined
158       on the request and, if so, we're setting header "X-Color" on the
159       response to "Octarine".
160
161       Notice that the hook ends with "return 0". This is because returning a
162       true value means that you want to cancel the connection to the backend
163       and send the response to the client yourself.
164
165       unregister
166
167       "unregister" is called when the plugin is removed from a service. It's
168       a standard good practice to unregister your plugin's hooks here, like
169       so:
170
171           sub unregister {
172               my ($class, $service) = @_;
173               $service->unregister_hooks('ColorOfMagic');
174               return 1;
175           }
176
177       You can also use "unregister_hook" to unregister one single hook:
178
179           $service->unregister_hook('ColorOfMagic', 'modify_response_headers');
180
181       load
182
183       "load" is called when your plugin is loaded (or reloaded).
184
185       This is where you should perform your plugin's initialization, which
186       can go from setting up some variables to registering a management
187       command (to register commands see the documentation for
188       "manage_command" further down this document).
189
190           my $color;
191
192           sub load {
193               my $class = shift;
194
195               $color = 'Octarine';
196
197               return 1;
198           }
199
200       "load" must always be defined, but if you really don't need it you can
201       have it simply returning a true value:
202
203           sub load { return 1; }
204
205       unload
206
207       "unload" is called when your plugin is unloaded. This is where you
208       should perform any clean up tasks.
209
210       "unload" must always be defined, but if you really don't need it you
211       can have it simply returning a true value:
212
213           sub unload { return 1; }
214
215       Don't forget to call "unregister_global_hook" if you have registered
216       any (see the documentation for "manage_command" further down this
217       document and you'll see what we're talking about).
218
219       register vs. load
220
221       "load" is called when the plugin is loaded, while "register" is called
222       whenever the plugin is set for a service.
223
224       This means that you should use "load" for anything that is global, such
225       as registering a global hook, and you should use "register" for things
226       that are specific to a service, such as registering service hooks.
227
228       dumpconfig
229
230       "dumpconfig" is not required.
231
232       When managing Perlbal (see Perlbal::Manual::Management) you can send a
233       "dumpconfig" command that will result in a configuration dump.
234
235       Apart from the global configuration, each plugin that implements a
236       "dumpconfig" function will also have that function called.
237
238       "dumpconfig" should return an array of messages to be displayed.
239
240           sub dumpconfig {
241               my ($class, $service) = @_;
242
243               my @messages;
244
245               push @messages, "COLOROFMAGIC is $color";
246
247               return @messages;
248           }
249
250       Again, "dumpconfig" is not required, so implement it only if it makes
251       sense for your plugin.
252
253       Helper functions
254
255       add_tunable
256
257       Adding a tunable will allow you to set its value within each plugin:
258
259           LOAD MyPlugin
260           CREATE SERVICE my_service
261               SET my_new_parameter    = 42
262               SET plugins             = MyPlugin
263           ENABLE my_service
264
265       "add_tunable" can be used by plugins that want to add tunables so that
266       the config file can have more options for service settings.
267
268           sub load {
269
270               Perlbal::Service::add_tunable(
271                   my_new_parameter => {
272                       check_role => '*',
273                       check_type => 'int',
274                       des => "description of my new parameter",
275                       default => 0,
276                   },
277               );
278               return 1;
279
280           }
281
282       "check_role" defines for which roles the value can be set
283       ("reverse_proxy", "web_server", etc). A value of "*" mean that the
284       value can be set for any role.
285
286       The acceptable values for "check_type" are "enum", "regexp", "bool",
287       "int", "size", "file", "file_or_none" and "directory_or_none". An
288       Unknown check_type error message will be displayed whenever you try to
289       set a value that has an unknown "check_type".
290
291       "check_type" can also contain a code reference that will be used to
292       validate the type.
293
294           check_type => sub {
295               my $self  = shift;
296               my $val   = shift;
297               my $emesg = shift;
298
299               ...
300           },
301
302       This code reference should return a true or false value. If returning
303       false, the contents of $emesg (which is passed as a reference to the
304       function) will be used as the error message.
305
306       Here's a better explanation of the acceptable values for "check_type":
307
308       bool
309           Boolean value. Must be defined and will be checked as a Perl value.
310
311       directory_or_none
312           The value needs to be defined and the content must be an existing
313           directory (validated against perl's -d switch).
314
315       enum
316           An array reference containing the acceptable values:
317
318               check_type => [enum => ["yellow", "blue", "green"]],
319
320       file
321           A filename, validated against perl's -f switch.
322
323       file_or_none
324           A filename, validated against perl's -f switch, or the default
325           value.
326
327       int An integer value, validated against "/^\d+$/".
328
329       regexp
330           Regular expression.
331
332           The correct form of setting a regexp tunable is by setting it as an
333           array reference containing the type ("regexp"), the regular
334           expression and a message that can explain it:
335
336               check_type => ["regexp", qr/^\d+\.\d+\.\d+\.\d+:\d+$/, "Expecting IP:port of form a.b.c.d:port."],
337
338       size
339           A size, validated against "/^(\d+)[bkm]$/".
340
341       manage_command
342
343       Perlbal catches unknown configuration commands and tries to match them
344       against hooks in the form of "manage_command.*".
345
346       Let's say that you want to set a management command "time" that will
347       allow you to see what time it is on the server.
348
349           sub load {
350
351               Perlbal::register_global_hook('manage_command.time', sub {
352                   my $time = localtime time;
353
354                   return [ "It is now:", $time ];
355               });
356
357               return 1;
358
359           }
360
361       If you want to display a text message you should return an array
362       reference; each of the values will be printed with a trailing newline
363       character:
364
365           time
366           It is now:
367           Wed Dec  1 19:08:58 2010
368
369       If you need to parse additional parameters on your hook, you can use
370       "parse" and "args" on the Perlbal::ManageCommand object that your
371       function will receive:
372
373           my $mc = shift;
374
375           $mc->parse(qr/^time\s+(today|tomorrow)$/, "usage: TIME [today|tomorrow]");
376
377           my ($cmd, $choice) = $mc->args;
378
379       This would allow you to call your command with an argument that would
380       have to be one of "today" or "tomorrow".
381
382       register_setter
383
384       "register_setter" allows you to define parameters that can be set for
385       your plugin, using a syntax such as:
386
387           SET my_service.my_plugin.my_variable = my_value
388
389       For instance:
390
391           SET discworld.colorofmagic.color = 'Orange'
392
393       Here's how you'd configure a new setter, by using "register_setter"
394       inside "load":
395
396           my $color;
397
398           sub load {
399               $color = 'Octarine';
400
401               $svc->register_setter('ColorOfMagic', 'color', sub {
402                   my ($out, $what, $val) = @_;
403                   return 0 unless $what && $val;
404
405                   $color = $val;
406
407                   $out->("OK") if $out;
408
409                   return 1;
410               });
411
412               return 1;
413           }
414
415       selector
416
417       For plugins that will work with a "selector" service, sometimes you'll
418       want to override the "selector" itself.
419
420       You can do this in "register":
421
422           sub register {
423               my ($class, $svc) = @_;
424
425               $svc->selector(\&my_selector_function);
426
427       Don't forget to unregister your function on the way out:
428
429           sub unregister {
430               my ($class, $svc) = @_;
431               $svc->selector(undef);
432               return 1;
433           }
434
435       Your "selector" function receives a Perlbal::ClientHTTPBase object.
436
437           my Perlbal::ClientHTTPBase $cb = shift;
438
439       Inside your "selector" function you can set which service to forward
440       the request to like this:
441
442           my $service = Perlbal->service($service_name);
443           $service->adopt_base_client($cb);
444           return 1;
445
446       See Perlbal::Plugin::Vhosts or Perlbal::Plugin::Vpaths for examples on
447       how to do this.
448
449   Known plugins
450       The following is a list of known plugins:
451
452       •   Perlbal::Plugin::AccessControl (Perlbal core)
453
454           Basic access control based on IPs and Netmasks.
455
456       •   Perlbal::Plugin::Addheader
457
458           Add Headers to Perlbal webserver responses.
459
460       •   Perlbal::Plugin::AutoRemoveLeadingDir (Perlbal core)
461
462           Auto-removal of leading directory path components in the URL.
463
464       •   Perlbal::Plugin::BackendHeaders
465
466           See which backend served the request.
467
468       •   Perlbal::Plugin::Cgilike (Perlbal core)
469
470           Handle Perlbal requests with a Perl subroutine.
471
472       •   Perlbal::Plugin::EchoService (Perlbal core)
473
474           Simple plugin demonstrating how to create an add-on service for
475           Perlbal using the plugin infrastructure.
476
477       •   Perlbal::Plugin::ExpandSSL
478
479           Add a custom header according to the SSL of a service.
480
481       •   Perlbal::Plugin::FlvStreaming (Perlbal core)
482
483           Enable FLV streaming with reverse proxy.
484
485       •   Perlbal::Plugin::ForwardedFor
486
487           Rename the X-Forwarded-For header in Perlbal.
488
489       •   Perlbal::Plugin::Highpri (Perlbal core)
490
491           Makes some requests high priority.
492
493       •   Perlbal::Plugin::Include (Perlbal core)
494
495           Allows multiple, nesting configuration files.
496
497       •   Perlbal::Plugin::LazyCDN (Perlbal core)
498
499           Support for Content Delivery Networks.
500
501       •   Perlbal::Plugin::MaxContentLength (Perlbal core)
502
503           Reject large requests.
504
505       •   Perlbal::Plugin::NotModified (Perlbal core)
506
507           Automatic 304 Not Modified responses when clients send a
508           "If-Modified-Since" header.
509
510       •   Perlbal::Plugin::PSGI
511
512           PSGI web server on Perlbal.
513
514       •   Perlbal::Plugin::Palimg (Perlbal core)
515
516           Plugin that allows Perlbal to serve palette altered images.
517
518       •   Perlbal::Plugin::Queues (Perlbal core)
519
520           Simple queue length header inclusion plugin.
521
522       •   Perlbal::Plugin::Redirect (Perlbal core)
523
524           Plugin to do redirecting in Perlbal land.
525
526       •   Perlbal::Plugin::Stats (Perlbal core)
527
528           Basic Perlbal statistics gatherer.
529
530       •   Perlbal::Plugin::StickySessions
531
532           Session affinity for Perlbal.
533
534       •   Perlbal::Plugin::Throttle (Perlbal core)
535
536           Throttle connections from hosts that connect too frequently.
537
538       •   Perlbal::Plugin::TrustHeader
539
540           Remove untrusted headers.
541
542       •   Perlbal::Plugin::UrlGroup
543
544           Let URL match it in regular expression.
545
546       •   Perlbal::Plugin::Vhosts (Perlbal core)
547
548           Name-based virtual hosts.
549
550       •   Perlbal::Plugin::Vpaths (Perlbal core)
551
552           Select by path (selector role only).
553
554       •   Perlbal::Plugin::XFFExtras (Perlbal core)
555
556           Perlbal plugin that can optionally add an X-Forwarded-Port and/or
557           X-Forwarded-Proto header to reverse proxied requests.
558
559   SEE ALSO
560       Perlbal::Manual::Hooks, Perlbal::Manual::Internals.
561
562       There are sample configuration files under conf/; some of these are
563       examples on how to use and configure existing plugins: echoservice.conf
564       for Perlbal::Plugin::EchoService, virtual-hosts.conf for
565       Perlbal::Plugin::VHosts, etc.
566
567
568
569perl v5.32.1                      2021-01-25       Perlbal::Manual::Plugins(3)
Impressum