line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Perlbal::Plugin::UrlGroup; |
2
|
3
|
|
|
3
|
|
785144
|
use strict; |
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
101
|
|
3
|
3
|
|
|
3
|
|
15
|
use warnings; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
159
|
|
4
|
3
|
|
|
3
|
|
23
|
no warnings qw(deprecated); |
|
3
|
|
|
|
|
11
|
|
|
3
|
|
|
|
|
103
|
|
5
|
|
|
|
|
|
|
|
6
|
3
|
|
|
3
|
|
14
|
use URI::Escape; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
5884
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our %Services; # service_name => $svc |
11
|
|
|
|
|
|
|
my $manage_command = 'manage_command.group'; |
12
|
|
|
|
|
|
|
my $manage_command_regex = 'manage_command.group_regex'; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
my $group_regex = ''; |
15
|
|
|
|
|
|
|
my $group_postfix = ''; |
16
|
|
|
|
|
|
|
my %url_group; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# when "LOAD" directive loads us up |
19
|
|
|
|
|
|
|
sub load { |
20
|
3
|
|
|
3
|
0
|
285
|
my $class = shift; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Perlbal::register_global_hook($manage_command_regex, sub { |
23
|
4
|
|
|
4
|
|
659
|
my $mc = shift->parse(qr/^group_regex\s+(\S+)\s*=\s*(\w+)$/, |
24
|
|
|
|
|
|
|
"usage: GROUP_REGEX = "); |
25
|
4
|
|
|
|
|
103
|
($group_regex,$group_postfix) = $mc->args; |
26
|
4
|
|
|
|
|
31
|
$url_group{$group_regex} = $group_postfix; |
27
|
4
|
|
|
|
|
14
|
return $mc->ok; |
28
|
3
|
|
|
|
|
23
|
}); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
Perlbal::register_global_hook($manage_command, sub { |
31
|
8
|
|
|
8
|
|
1274
|
my $mc = shift->parse(qr/^group\s+(?:(\w+)\s+)?(\S+)\s*=\s*(\w+)$/, |
32
|
|
|
|
|
|
|
"usage: GROUP [] = "); |
33
|
8
|
|
|
|
|
190
|
my ($selname, $host, $target) = $mc->args; |
34
|
8
|
50
|
33
|
|
|
94
|
unless ($selname ||= $mc->{ctx}{last_created}) { |
35
|
0
|
|
|
|
|
0
|
return $mc->err("omitted service name not implied from context"); |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
8
|
|
|
|
|
31
|
my $ss = Perlbal->service($selname); |
39
|
8
|
50
|
33
|
|
|
78
|
return $mc->err("Service '$selname' is not a selector service") |
40
|
|
|
|
|
|
|
unless $ss && $ss->{role} eq "selector"; |
41
|
|
|
|
|
|
|
|
42
|
8
|
|
|
|
|
17
|
$host = lc $host; |
43
|
8
|
50
|
|
|
|
37
|
return $mc->err("invalid host pattern: '$host'") |
44
|
|
|
|
|
|
|
unless $host =~ /^[\w\-\_\.\*\;\:\\]+$/; |
45
|
|
|
|
|
|
|
|
46
|
8
|
100
|
|
|
|
31
|
$ss->{extra_config}->{_use_wild_card} = 1 if $host =~ /\*/; |
47
|
|
|
|
|
|
|
|
48
|
8
|
|
50
|
|
|
25
|
$ss->{extra_config}->{_groups} ||= {}; |
49
|
8
|
|
|
|
|
36
|
$ss->{extra_config}->{_groups}{$host} = $target; |
50
|
|
|
|
|
|
|
|
51
|
8
|
|
|
|
|
23
|
return $mc->ok; |
52
|
3
|
|
|
|
|
30
|
}); |
53
|
3
|
|
|
|
|
67
|
return 1; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# unload our global commands, clear our service object |
57
|
|
|
|
|
|
|
sub unload { |
58
|
0
|
|
|
0
|
0
|
0
|
my $class = shift; |
59
|
|
|
|
|
|
|
|
60
|
0
|
|
|
|
|
0
|
Perlbal::unregister_global_hook($manage_command); |
61
|
0
|
|
|
|
|
0
|
Perlbal::unregister_global_hook($manage_command_regex); |
62
|
0
|
|
|
|
|
0
|
unregister($class, $_) foreach (values %Services); |
63
|
0
|
|
|
|
|
0
|
return 1; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# called when we're being added to a service |
67
|
|
|
|
|
|
|
sub register { |
68
|
3
|
|
|
3
|
0
|
105726
|
my ($class, $svc) = @_; |
69
|
3
|
50
|
33
|
|
|
89
|
unless ($svc && $svc->{role} eq "selector") { |
70
|
0
|
|
|
|
|
0
|
die "You can't load the url_group plugin on a service not of role selector.\n"; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
3
|
|
|
|
|
22
|
$svc->selector(\&url_group_selector); |
74
|
3
|
|
|
|
|
42
|
$svc->{extra_config}->{_groups} = {}; |
75
|
|
|
|
|
|
|
|
76
|
3
|
|
|
|
|
15
|
$Services{"$svc"} = $svc; |
77
|
3
|
|
|
|
|
59
|
return 1; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# called when we're no longer active on a service |
81
|
|
|
|
|
|
|
sub unregister { |
82
|
0
|
|
|
0
|
0
|
0
|
my ($class, $svc) = @_; |
83
|
0
|
|
|
|
|
0
|
$svc->selector(undef); |
84
|
0
|
|
|
|
|
0
|
delete $Services{"$svc"}; |
85
|
0
|
|
|
|
|
0
|
return 1; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# call back from Service via ClientHTTPBase's event_read calling service->select_new_service(Perlbal::ClientHTTPBase) |
89
|
|
|
|
|
|
|
sub url_group_selector { |
90
|
36
|
|
|
36
|
0
|
843532
|
my Perlbal::ClientHTTPBase $cb = shift; |
91
|
|
|
|
|
|
|
|
92
|
36
|
|
|
|
|
93
|
my $req = $cb->{req_headers}; |
93
|
|
|
|
|
|
|
|
94
|
36
|
50
|
|
|
|
147
|
return $cb->_simple_response(404, "Not Found (no reqheaders)") unless $req; |
95
|
|
|
|
|
|
|
|
96
|
36
|
|
|
|
|
174
|
my $vhost = $req->header("Host"); |
97
|
36
|
|
|
|
|
389
|
my $uri = $req->request_uri; |
98
|
36
|
|
50
|
|
|
317
|
my $maps = $cb->{service}{extra_config}{_groups} ||= {}; |
99
|
|
|
|
|
|
|
|
100
|
36
|
|
|
|
|
111
|
$vhost =~ s/:\d+$//; |
101
|
|
|
|
|
|
|
|
102
|
36
|
|
|
|
|
66
|
my $target; |
103
|
36
|
50
|
|
|
|
170
|
if ( $cb->{service}{extra_config}{_use_wild_card} ) { |
104
|
36
|
|
|
|
|
136
|
for my $host_org (keys %$maps) { |
105
|
92
|
|
|
|
|
362
|
(my $host_name = $host_org) =~ s/\*/.+/g; |
106
|
|
|
|
|
|
|
|
107
|
92
|
100
|
|
|
|
239
|
if ( $vhost eq $host_name ) { |
108
|
14
|
|
|
|
|
31
|
$target = $maps->{$host_org}; |
109
|
14
|
|
|
|
|
36
|
last; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
78
|
100
|
|
|
|
2155
|
if ($vhost =~ /^$host_name$/) { |
113
|
22
|
|
|
|
|
89
|
$target = $maps->{$host_org}; |
114
|
|
|
|
|
|
|
# do more loop. |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
} else { |
118
|
0
|
|
|
|
|
0
|
$target = $maps->{$vhost}; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
36
|
|
|
|
|
210
|
my $chk_uri = URI::Escape::uri_unescape($uri); |
122
|
|
|
|
|
|
|
# query¤Ï̵»ë |
123
|
36
|
|
|
|
|
347
|
$chk_uri =~ s/\?.+$//g; |
124
|
|
|
|
|
|
|
|
125
|
36
|
50
|
|
|
|
87
|
if ( $target ) { |
126
|
36
|
|
|
|
|
60
|
my $dest_service; |
127
|
36
|
|
|
|
|
118
|
for my $regex ( keys %url_group ) { |
128
|
44
|
100
|
|
|
|
720
|
if ( $chk_uri =~ /$regex/ ) { |
129
|
20
|
|
|
|
|
49
|
$dest_service = $target.$url_group{$regex}; |
130
|
20
|
|
|
|
|
40
|
last; |
131
|
|
|
|
|
|
|
} |
132
|
24
|
|
|
|
|
63
|
$dest_service = $target; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
36
|
|
50
|
|
|
267
|
my $svc = Perlbal->service($dest_service) || undef; |
136
|
36
|
50
|
|
|
|
460
|
unless ($svc) { |
137
|
0
|
|
|
|
|
0
|
$cb->_simple_response(404, "Not Found (no configured url_group's dest_service)"); |
138
|
0
|
|
|
|
|
0
|
return 1; |
139
|
|
|
|
|
|
|
} else { |
140
|
36
|
|
|
|
|
183
|
$svc->adopt_base_client($cb); |
141
|
36
|
|
|
|
|
89074
|
return 0; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
} else { |
144
|
0
|
|
|
|
|
|
$cb->_simple_response(404, "Not Found (no configured url_group's vhost name)"); |
145
|
0
|
|
|
|
|
|
return 1; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
1; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
__END__ |