File Coverage

blib/lib/POEx/URI.pm
Criterion Covered Total %
statement 208 229 90.8
branch 110 144 76.3
condition 28 48 58.3
subroutine 25 26 96.1
pod 14 14 100.0
total 385 461 83.5


line stmt bran cond sub pod time code
1             package POEx::URI;
2              
3 6     6   191104 use strict;
  6         17  
  6         336  
4 6     6   35 use warnings;
  6         14  
  6         273  
5              
6 6     6   5946 use URI::Escape qw(uri_unescape);
  6         10335  
  6         471  
7 6     6   5899 use URI::_server;
  6         184015  
  6         316  
8 6     6   77 use Carp;
  6         15  
  6         668  
9              
10 6     6   37 use vars qw( @ISA $VERSION );
  6         15  
  6         1026  
11             @ISA = qw(URI::_server);
12             $VERSION = '0.0301';
13              
14 6         71 use overload '@{}' => \&as_array,
15 6     6   38 fallback => 1;
  6         13  
16              
17             ##############################################
18             sub _init
19             {
20 31     31   21921 my( $class, $str, $scheme ) = @_;
21              
22 31 100       137 if( $str =~ m,^poe://[^/]+/[^/]+$, ) {
23 2         6 $str .= '/';
24             }
25 31 100       258 $str = "$scheme:$str" unless $str =~ /^\Q$scheme:/;
26              
27 31         159 return $class->SUPER::_init($str, $scheme);
28             }
29              
30             ##############################################
31 4     4 1 78 sub default_port { 603 }
32              
33             ##############################################
34             sub kernel
35             {
36 66     66 1 10306 my $self = shift;
37 66         259 my $old = $self->authority;
38 66 100       1229 if( @_ ) {
39 16         32 my $tmp = $old;
40 16 100       43 $tmp = "" unless defined $old;
41 16 50       53 my $ui = ($tmp =~ /(.*@)/) ? $1 : "";
42 16         25 my $new = shift;
43 16 100       128 $new = "" unless defined $new;
44 16 100       43 if (length $new) {
45 14         31 $new =~ s/[@]/%40/g; # protect @
46             }
47 16 100 66     88 if( $ui or length $new ) {
48 14         53 $self->authority( "$ui$new" );
49             }
50             else {
51 2         7 $self->authority( undef );
52             }
53             }
54 66 100       970 return undef unless defined $old;
55 41         72 $old =~ s/.*@//;
56 41         123 return uri_unescape($old);
57             }
58              
59              
60             ##############################################
61             sub path
62             {
63 283     283 1 3662 my $self = shift;
64 283         768 my $old = $self->SUPER::path;
65 283 100       3175 if( @_ ) {
66 54         80 my $new = shift;
67 54 100       216 if( $new =~ m,(.+)/(.+), ) {
68            
69 32         170 my $session = $1;
70 32         55 my $event = $2;
71 32         63 $session =~ s,^/+,,;
72 32         66 $session =~ s,/,%2F,g;
73 32         273 $new = join '/', $session, $event;
74             }
75 54         159 $self->SUPER::path( $new );
76             }
77 283         2361 return $old;
78             }
79              
80             ##############################################
81             sub path_segments
82             {
83 178     178 1 2173 my $self = shift;
84              
85 178         576 my @seg = $self->SUPER::path_segments;
86 178 100       11713 if( @_ ) {
87 49         105 my @new = @_;
88 49 100       134 shift @new if $new[0] eq '';
89 49 100       181 if( 2 <= @new ) {
90 43         65 my $event = pop @new;
91 43         147 @new = ( join( '/', @new ), $event );
92             }
93 49         209 $self->SUPER::path_segments( @new );
94             }
95 178         718 return @seg;
96             }
97              
98             ##############################################
99             sub session
100             {
101 48     48 1 1992 my $self = shift;
102 48         112 my @seg = $self->path_segments;
103 48 100 100     285 shift @seg if defined $seg[0] and $seg[0] eq '';
104 48         70 my $event;
105 48 100       116 if( 1==@seg ) { # only an event?
106 10         14 $event = $seg[0];
107 10         23 @seg = ();
108             }
109 48 100       116 if( @seg >= 2 ) { # session + event
110 35         57 $event = pop @seg;
111             }
112 48         147 my $old = join '/', @seg[0..$#seg];
113              
114 48 100       114 if( @_ ) {
115 14         26 my $new = shift;
116 14 100       38 $new = '' unless defined $new;
117 14 100       57 $self->path_segments( $new, (defined $event ? $event : '' ) );
118             }
119              
120 48         198 return $old;
121             }
122              
123             ##############################################
124             sub event
125             {
126 39     39 1 4676 my $self = shift;
127 39         103 my $old = ( $self->path_segments )[-1];
128 39 100       112 $old = '' unless defined $old;
129 39 100       100 if( @_ ) {
130 11         26 my @seg = $self->path_segments;
131 11         19 my $new = shift;
132 11 100       41 if( @seg >= 2 ) { # session/event
    50          
133 8   100     39 $seg[-1] = $new||'';
134             }
135             elsif( @seg ) { # session
136 0   0     0 push @seg, $new||'';
137             }
138             else { # nothing
139 3 50 66     14 if( $self->kernel and defined $new ) {
140 0         0 carp "It makes no sense to set an event without a session";
141             }
142 3   100     26 @seg = ('', $new||'');
143             }
144            
145 11         34 $self->path_segments( @seg );
146             }
147 39         117 return $old;
148             }
149              
150             ##############################################
151             sub _user
152             {
153 5     5   9 my $self = shift;
154 5         15 my $old = $self->userinfo;
155 5         123 $old =~ s/:.*$//;
156 5         16 return $old;
157             }
158             sub user
159             {
160 8     8 1 2113 my $self = shift;
161 8         24 my $old = $self->userinfo;
162 8         181 $old =~ s/:.*$//;
163              
164 8 100       28 if( @_ ) {
165 4         21 my $pw = $self->_password;
166 4         8 my $new = shift;
167 4         10 my $ui = $new;
168 4 100       16 if( defined $new ) {
    100          
169 2         6 $new =~ s/:/%3A/g;
170 2         3 $ui = $new;
171 2 50       9 $ui .= ":$pw" if( defined $pw );
172             }
173             elsif( defined $pw ) {
174 1         2 $ui = ":$pw";
175             }
176 4         13 $self->userinfo( $ui );
177             }
178              
179 8 100       377 $old =~ s/%3A/:/g if $old;
180 8         30 return $old;
181             }
182              
183             ##############################################
184             sub _password
185             {
186 4     4   8 my $self = shift;
187 4         13 my $old = $self->userinfo;
188 4 100       1355 undef( $old ) unless $old =~ s/^.*?://;
189 4         13 return $old;
190             }
191             sub password
192             {
193 9     9 1 2407 my $self = shift;
194 9         36 my $old = $self->userinfo;
195 9 100       250 undef( $old ) unless $old =~ s/^.*?://;
196              
197 9 100       45 if( @_ ) {
198 5         26 my $user = $self->_user;
199 5 50       21 $user = '' unless defined $user;
200 5         9 my $new = shift;
201 5 100       17 if( defined $new ) {
202 3         53 $new =~ s/:/%3A/g;
203 3         16 $self->userinfo( "$user:$new" );
204             }
205             else {
206 2         8 $self->userinfo( $user );
207             }
208             }
209 9 100       305 $old =~ s/%3A/:/g if $old;
210 9         29 return $old;
211             }
212              
213             ##############################################
214             sub _is_inet
215             {
216 29     29   41 my $kernel = shift;
217 29 100       98 return unless $kernel;
218 20 100       64 return 1 if $kernel =~ /:\d*$/;
219 17 50       42 return 1 if $kernel =~ /^\[[:0-9a-f]+\]$/i; # [IPv6]
220 17 100       40 return 1 if $kernel =~ /^\d+\.\d+\.\d+\.\d+/; # IPv4 dotted quad
221 16 50 33     199 return 1 if $kernel =~ /^[-\w.]+$/ and $kernel =~ /[.]/;
222             }
223              
224             sub canonical
225             {
226 29     29 1 1696 my( $self ) = @_;
227 29         167 my $other = $self->URI::_generic::canonical();
228              
229              
230 29         953 my $kernel = $self->kernel;
231 29 100       185 if( _is_inet( $kernel ) ) {
232 4 100       19 $other = $other->clone if $other == $self;
233 4         85 $other->kernel( lc $kernel );
234             }
235 29         287 my $port = $other->_port;
236 29 100 66     506 if( defined($port) && ($port eq "" || $port == $self->default_port) ) {
      66        
237 2 50       8 $other = $other->clone if $other == $self;
238 2         30 $other->port(undef);
239             }
240              
241 29 100       180 if( $other =~ m(poe:/[^/]) ) {
242 4 50       44 $other = $other->clone if $other == $self;
243 4         116 $$other =~ s(poe:/)(poe:);
244             }
245              
246 29         219 my @seg = $other->path_segments;
247 29 100       78 if( 2 < @seg ) {
248 21 100       68 $other = $other->clone if $other == $self;
249 21         426 $other->path_segments( @seg ); # enforce 2 segments
250             }
251              
252 29         136 return $other;
253             }
254              
255             ##############################################
256             sub fragment
257             {
258 0 0   0 1 0 return if 1==@_;
259 0         0 croak "->fragment() currently not supported";
260             }
261              
262             ##############################################
263             sub as_array
264             {
265 7     7 1 532 my $self = shift;
266 7         8 my $kid;
267 7 50 33     23 $kid = $POE::Kernel::poe_kernel->ID
268             if $POE::Kernel::poe_kernel and $POE::Kernel::poe_kernel->can('ID');
269 7         18 my $kernel = $self->kernel;
270 7         33 my $alias = $self->session;
271 7 50 33     25 if( $kernel and ( not $kid or $kernel ne $kid ) ) {
      66        
272 2         14 $alias = join '/', $self->scheme.':/', $kernel, $alias;
273             }
274              
275 7         147 my @ret = ( $alias, $self->event, $self->argument );
276              
277 7 100       63 return \@ret unless wantarray;
278 1         8 return @ret;
279             }
280              
281             ##############################################
282             sub argument
283             {
284 7     7 1 13 my $self = shift;
285 7         16 my $old = $self->_argument;
286 7 50       20 if( @_ ) {
287 0 0       0 if( 1==@_ ) {
288 0         0 my $new = shift;
289 0 0       0 unless( ref $new ) {
    0          
290 0         0 $self->query( $new );
291             }
292             elsif( 'ARRAY' eq ref $new ) {
293 0         0 $self->query_keywords( $new );
294             }
295             else {
296 0         0 $self->query_form( $new );
297             }
298             }
299             else {
300 0         0 $self->query_form( @_ );
301             }
302             }
303 7 50       26 return unless defined $old;
304 0         0 return $old;
305             }
306              
307             sub _argument
308             {
309 7     7   7 my $self = shift;
310 7         8 my $args;
311              
312 7         26 my $q = $self->query;
313 7 50       113 return unless defined $q;
314              
315 0 0       0 if( $q =~ /=/ ) {
316 0 0       0 return { map { s/\+/ /g; uri_unescape($_) }
  0         0  
  0         0  
317 0         0 map { /=/ ? split(/=/, $_, 2) : ($_ => '')}
318             split(/&/, $q)
319             };
320             }
321 0         0 return [ map { uri_unescape($_) } split(/\+/, $q, -1) ];
  0         0  
322             }
323              
324             ##############################################
325             sub abs
326             {
327 6     6 1 172 my $self = shift;
328 6   33     23 my $base = shift || croak "Missing base argument";
329              
330 6 50       51 $base = URI->new($base) unless ref $base;
331 6         14 $base = $base->canonical;
332 6         25 my $abs = $self->clone;
333              
334 6 50       45 $abs->scheme( $base->scheme ) unless $abs->scheme;
335 6         96 foreach my $part ( qw( event session authority ) ) {
336 18         56 my $f = $abs->$part;
337 18 100 100     112 next if defined $f and length $f;
338 9         25 $f = $base->$part;
339 9 50       76 next unless length $f;
340 9         25 $abs->$part( $base->$part );
341             }
342 6         232 return $abs;
343             }
344              
345             ##############################################
346             sub rel
347             {
348 3     3 1 56 my $self = shift;
349 3   33     7 my $base = shift || croak "Missing base argument";
350              
351 3         22 my $rel = $self->clone;
352 3 100       23 $base = URI->new($base) unless ref $base;
353              
354 3         34 my $scheme = $rel->scheme;
355 3         44 my $auth = $rel->canonical->authority;
356 3         32 my $session = $rel->session;
357 3         9 my $event = $rel->event;
358              
359 3 0 33     8 if (!defined($scheme) && !defined($auth)) {
360             # it is already relative
361 0         0 return $rel;
362             }
363              
364 3         8 my $bscheme = $base->scheme;
365 3         40 my $bauth = $base->canonical->authority;
366 3         29 my $bsession = $base->session;
367 3         5 my $bevent = $base->event;
368              
369 3         10 for ($bscheme, $bauth, $auth) {
370 9 50       18 $_ = '' unless defined
371             }
372              
373 3 100 66     16 unless ($scheme eq $bscheme && $auth eq $bauth) {
374             # different location, can't make it relative
375 1         4 return $rel;
376             }
377              
378             # Make it relative by eliminating scheme and authority
379 2         6 $rel->scheme(undef);
380 2         139 $rel->authority(undef);
381              
382 2         54 for ($session, $event, $bsession, $bevent) {
383 8 50       17 $_ = '' unless defined
384             }
385              
386 2 100       7 if( $bsession eq $session ) {
387 1         9 $rel->session(undef);
388             }
389 2 50       7 if( $bevent eq $event ) {
390 0         0 $rel->event(undef);
391             }
392              
393 2         16 return $rel;
394             }
395              
396             1;
397              
398             __END__