root/trunk/lib/Perlbal/Plugin/Vpaths.pm

Revision 706, 3.0 kB (checked in by marksmith, 2 years ago)

don't print debugging anymore

Line 
1###########################################################################
2# plugin to use with selectors to select by path
3#
4# this will not play well with the Vhosts plugin or any other selector
5# behavior plugins.
6#
7# this has also not been optimized for huge volume sites.
8###########################################################################
9
10package Perlbal::Plugin::Vpaths;
11
12use strict;
13use warnings;
14no  warnings qw(deprecated);
15
16our %Services;  # service_name => $svc
17
18# when "LOAD" directive loads us up
19sub load {
20    my $class = shift;
21
22    Perlbal::register_global_hook('manage_command.vpath', sub {
23        my $mc = shift->parse(qr/^vpath\s+(?:(\w+)\s+)?(\S+)\s*=\s*(\w+)$/,
24                              "usage: VPATH [<service>] <path regex> = <dest_service>");
25        my ($selname, $regex, $target) = $mc->args;
26        unless ($selname ||= $mc->{ctx}{last_created}) {
27            return $mc->err("omitted service name not implied from context");
28        }
29
30        my $ss = Perlbal->service($selname);
31        return $mc->err("Service '$selname' is not a selector service")
32            unless $ss && $ss->{role} eq "selector";
33
34        my $cregex = qr/$regex/;
35        return $mc->err("invalid regular expression: '$regex'")
36            unless $cregex;
37
38        $ss->{extra_config}->{_vpaths} ||= [];
39        push @{$ss->{extra_config}->{_vpaths}}, [ $cregex, $target ];
40 
41        return $mc->ok;
42    });
43    return 1;
44}
45
46# unload our global commands, clear our service object
47sub unload {
48    my $class = shift;
49
50    Perlbal::unregister_global_hook('manage_command.vpath');
51    unregister($class, $_) foreach (values %Services);
52    return 1;
53}
54
55# called when we're being added to a service
56sub register {
57    my ($class, $svc) = @_;
58    unless ($svc && $svc->{role} eq "selector") {
59        die "You can't load the vpath plugin on a service not of role selector.\n";
60    }
61
62    $svc->selector(\&vpath_selector);
63    $svc->{extra_config}->{_vpaths} = [];
64
65    $Services{"$svc"} = $svc;
66    return 1;
67}
68
69# called when we're no longer active on a service
70sub unregister {
71    my ($class, $svc) = @_;
72    $svc->selector(undef);
73    delete $Services{"$svc"};
74    return 1;
75}
76
77# call back from Service via ClientHTTPBase's event_read calling service->select_new_service(Perlbal::ClientHTTPBase)
78sub vpath_selector {
79    my Perlbal::ClientHTTPBase $cb = shift;
80
81    my $req = $cb->{req_headers};
82    return $cb->_simple_response(404, "Not Found (no reqheaders)") unless $req;
83
84    my $uri = $req->request_uri;
85    my $maps = $cb->{service}{extra_config}{_vpaths} ||= {};
86
87    # iterate down the list of paths, find any matches
88    foreach my $row (@$maps) {
89        next unless $uri =~ /$row->[0]/;
90
91        my $svc_name = $row->[1];
92        my $svc = $svc_name ? Perlbal->service($svc_name) : undef;
93        unless ($svc) {
94            $cb->_simple_response(404, "Not Found ($svc_name not a defined service)");
95            return 1;
96        }
97
98        $svc->adopt_base_client($cb);
99        return 1;
100    }
101
102    return 0;
103}
104
1051;
Note: See TracBrowser for help on using the browser.