root/lang/perl/Perlbal-Plugin-UrlGroup/trunk/lib/Perlbal/Plugin/UrlGroup.pm @ 23333

Revision 23333, 5.4 kB (checked in by nekokak, 5 years ago)

fix usage.

Line 
1package Perlbal::Plugin::UrlGroup;
2use strict;
3use warnings;
4no  warnings qw(deprecated);
5
6use URI::Escape;
7
8our $VERSION = '0.02';
9
10our %Services;  # service_name => $svc
11my $manage_command = 'manage_command.group';
12my $manage_command_regex = 'manage_command.group_regex';
13my %url_group;
14
15# when "LOAD" directive loads us up
16sub load {
17    my $class = shift;
18
19    Perlbal::register_global_hook($manage_command_regex, sub {
20        my $mc = shift->parse(qr/^group_regex\s+(\S+)\s*=\s*(\w+)$/,
21                              "usage: GROUP_REGEX <regex> = <group_postfix>");
22        my ($group_regex,$group_postfix) = $mc->args;
23        $url_group{$group_regex} = $group_postfix;
24        return $mc->ok;
25    });
26
27    Perlbal::register_global_hook($manage_command, sub {
28        my $mc = shift->parse(qr/^group\s+(?:(\w+)\s+)?(\S+)\s*=\s*(\w+)$/,
29                              "usage: GROUP [<service>] <host_or_pattern> = <dest_service>");
30        my ($selname, $host, $target) = $mc->args;
31        unless ($selname ||= $mc->{ctx}{last_created}) {
32            return $mc->err("omitted service name not implied from context");
33        }
34
35        my $ss = Perlbal->service($selname);
36        return $mc->err("Service '$selname' is not a selector service")
37            unless $ss && $ss->{role} eq "selector";
38
39        $host = lc $host;
40        return $mc->err("invalid host pattern: '$host'")
41            unless $host =~ /^[\w\-\_\.\*\;\:]+$/;
42
43        $ss->{extra_config}->{_use_wild_card} = 1 if $host =~ /\*/;
44
45        $ss->{extra_config}->{_groups} ||= {};
46        $ss->{extra_config}->{_groups}{$host} = $target;
47
48        return $mc->ok;
49    });
50    return 1;
51}
52
53# unload our global commands, clear our service object
54sub unload {
55    my $class = shift;
56
57    Perlbal::unregister_global_hook($manage_command);
58    Perlbal::unregister_global_hook($$manage_command_regex);
59    unregister($class, $_) foreach (values %Services);
60    return 1;
61}
62
63# called when we're being added to a service
64sub register {
65    my ($class, $svc) = @_;
66    unless ($svc && $svc->{role} eq "selector") {
67        die "You can't load the url_group plugin on a service not of role selector.\n";
68    }
69
70    $svc->selector(\&url_group_selector);
71    $svc->{extra_config}->{_groups} = {};
72
73    $Services{"$svc"} = $svc;
74    return 1;
75}
76
77# called when we're no longer active on a service
78sub unregister {
79    my ($class, $svc) = @_;
80    $svc->selector(undef);
81    delete $Services{"$svc"};
82    return 1;
83}
84
85# call back from Service via ClientHTTPBase's event_read calling service->select_new_service(Perlbal::ClientHTTPBase)
86sub url_group_selector {
87    my Perlbal::ClientHTTPBase $cb = shift;
88
89    my $req = $cb->{req_headers};
90
91    return $cb->_simple_response(404, "Not Found (no reqheaders)") unless $req;
92
93    my $vhost = $req->header("Host");
94    my $uri = $req->request_uri;
95    my $maps = $cb->{service}{extra_config}{_groups} ||= {};
96
97    $vhost =~ s/:\d+$//;
98
99    my $target;
100    if ( $cb->{service}{extra_config}{_use_wild_card} ) {
101        for my $host_org (keys %$maps) {
102            (my $host_name = $host_org) =~ s/\*/.+/g;
103
104            if ( $vhost eq $host_name ) {
105                $target = $maps->{$host_org};
106                last;
107            }
108
109            if ($vhost =~ /^$host_name$/) {
110                $target = $maps->{$host_org};
111                # do more loop.
112            }
113        }
114    } else {
115        $target = $maps->{$vhost};
116    }
117
118    my $chk_uri = URI::Escape::uri_unescape($uri);
119    # query�����   $chk_uri =~ s/\?.+$//g;
120
121    if ( $target ) {
122        my $dest_service;
123        for my $regex ( keys %url_group ) {
124            if ( $chk_uri =~ /$regex/o ) {
125                $dest_service .= $target.$url_group{$regex};
126                last;
127            }
128            $dest_service = $target;
129        }
130
131        my $svc = Perlbal->service($dest_service) || undef;
132        unless ($svc) {
133            $cb->_simple_response(404, "Not Found (no configured url_group's dest_service)");
134            return 1;
135        } else {
136            $svc->adopt_base_client($cb);
137            return 0;
138        }
139    } else {
140        $cb->_simple_response(404, "Not Found (no configured url_group's vhost name)");
141        return 1;
142    }
143}
144
1451;
146
147__END__
148
149=head1 NAME
150
151Perlbal::Plugin::UrlGroup - let URL match it in regular expression
152
153=head1 SYNOPSIS
154
155    in your perlbal.conf:
156
157    LOAD UrlGroup
158    CREATE SERVICE http_server
159        SET listen          = 0.0.0.0:80
160        SET role            = selector
161        SET plugins         = UrlGroup
162        GROUP_REGEX .(jpg|gif|png|js|css|swf)$ = _static
163        GROUP_REGEX ^/app_s1/$ = _s1
164
165        GROUP example.com = example
166    ENABLE http_server
167   
168    CREATE SERVICE example
169        SET role            = reverse_proxy
170        SET pool            = example_pool
171        SET enable_reproxy  = true
172    ENABLE example
173   
174    CREATE SERVICE example_static
175        SET role            = reverse_proxy
176        SET pool            = example_static_pool
177        #SET enable_reproxy  = true
178    ENABLE example_static
179
180=head1 DESCRIPTION
181
182let URL match it in regular expression.
183
184=head1 BUGS AND LIMITATIONS
185
186No bugs have been reported.
187
188=head1 AUTHOR
189
190Atsushi Kobayashi  C<< <atsushi __at__ mobilefactory.jp> >>
191
192=head1 LICENCE AND COPYRIGHT
193
194Copyright (c) 2007, Atsushi Kobayashi C<< <atsushi __at__ mobilefactory.jp> >>. All rights reserved.
195
196This module is free software; you can redistribute it and/or
197modify it under the same terms as Perl itself. See L<perlartistic>.
198
Note: See TracBrowser for help on using the browser.