File Coverage

blib/lib/URI/_server.pm
Criterion Covered Total %
statement 115 116 99.1
branch 68 74 91.8
condition 29 29 100.0
subroutine 14 15 93.3
pod 8 8 100.0
total 234 242 96.6


line stmt bran cond sub pod time code
1             package URI::_server;
2              
3 47     47   18758 use strict;
  47         73  
  47         1362  
4 47     47   156 use warnings;
  47         58  
  47         1751  
5              
6 47     47   171 use parent 'URI::_generic';
  47         56  
  47         271  
7              
8 47     47   2360 use URI::Escape qw(uri_unescape);
  47         68  
  47         64483  
9              
10             our $VERSION = '5.35';
11              
12             sub _uric_escape {
13 876     876   1412 my($class, $str) = @_;
14 876 100       5521 if ($str =~ m,^((?:$URI::scheme_re:)?)//([^/?\#]*)(.*)$,os) {
15 517         1626 my($scheme, $host, $rest) = ($1, $2, $3);
16 517 100       1225 my $ui = $host =~ s/(.*@)// ? $1 : "";
17 517 100       969 my $port = $host =~ s/(:\d+)\z// ? $1 : "";
18 517 100       860 if (_host_escape($host)) {
19 5         10 $str = "$scheme//$ui$host$port$rest";
20             }
21             }
22 876         2441 return $class->SUPER::_uric_escape($str);
23             }
24              
25             sub _host_escape {
26 555     555   647 return if URI::HAS_RESERVED_SQUARE_BRACKETS and $_[0] !~ /[^$URI::uric]/;
27 549 100       4724 return if !URI::HAS_RESERVED_SQUARE_BRACKETS and $_[0] !~ /[^$URI::uric4host]/;
28 6         8 eval {
29 6         809 require URI::_idna;
30 6         16 $_[0] = URI::_idna::encode($_[0]);
31             };
32 6 100       14 return 0 if $@;
33 5         10 return 1;
34             }
35              
36             sub as_iri {
37 15     15 1 2522 my $self = shift;
38 15         43 my $str = $self->SUPER::as_iri;
39 15 100       46 if ($str =~ /\bxn--/) {
40 5 50       82 if ($str =~ m,^((?:$URI::scheme_re:)?)//([^/?\#]*)(.*)$,os) {
41 5         15 my($scheme, $host, $rest) = ($1, $2, $3);
42 5 50       13 my $ui = $host =~ s/(.*@)// ? $1 : "";
43 5 50       9 my $port = $host =~ s/(:\d+)\z// ? $1 : "";
44 5         21 require URI::_idna;
45 5         10 $host = URI::_idna::decode($host);
46 5         12 $str = "$scheme//$ui$host$port$rest";
47             }
48             }
49 15         53 return $str;
50             }
51              
52             sub userinfo
53             {
54 136     136 1 477 my $self = shift;
55 136         278 my $old = $self->authority;
56              
57 136 100       235 if (@_) {
58 39         47 my $new = $old;
59 39 50       60 $new = "" unless defined $new;
60 39         122 $new =~ s/.*@//; # remove old stuff
61 39         55 my $ui = shift;
62 39 100       61 if (defined $ui) {
63 35         357 $ui =~ s/([^$URI::uric4user])/ URI::Escape::escape_char($1)/ego;
  16         31  
64 35         67 $new = "$ui\@$new";
65             }
66 39         69 $self->authority($new);
67             }
68 136 100 100     742 return undef if !defined($old) || $old !~ /(.*)@/;
69 107         257 return $1;
70             }
71              
72             sub host
73             {
74 510     510 1 4732 my $self = shift;
75 510         1093 my $old = $self->authority;
76 510 100       859 if (@_) {
77 39         63 my $tmp = $old;
78 39 100       64 $tmp = "" unless defined $tmp;
79 39 100       116 my $ui = ($tmp =~ /(.*@)/) ? $1 : "";
80 39 100       135 my $port = ($tmp =~ /(:\d+)$/) ? $1 : "";
81 39         63 my $new = shift;
82 39 100       79 $new = "" unless defined $new;
83 39 100       70 if (length $new) {
84 38         55 $new =~ s/[@]/%40/g; # protect @
85 38 100 100     195 if ($new =~ /^[^:]*:\d*\z/ || $new =~ /]:\d*\z/) {
86 5 50       27 $new =~ s/(:\d*)\z// || die "Assert";
87 5         9 $port = $1;
88             }
89 38 100 100     141 $new = "[$new]" if $new =~ /:/ && $new !~ /^\[/; # IPv6 address
90 38         76 _host_escape($new);
91             }
92 39         106 $self->authority("$ui$new$port");
93             }
94 510 100       887 return undef unless defined $old;
95 431         723 $old =~ s/.*@//;
96 431         815 $old =~ s/:\d+$//; # remove the port
97 431         607 $old =~ s{^\[(.*)\]$}{$1}; # remove brackets around IPv6 (RFC 3986 3.2.2)
98 431         930 return uri_unescape($old);
99             }
100              
101             sub ihost
102             {
103 5     5 1 8 my $self = shift;
104 5         12 my $old = $self->host(@_);
105 5 100       17 if ($old =~ /(^|\.)xn--/) {
106 3         16 require URI::_idna;
107 3         7 $old = URI::_idna::decode($old);
108             }
109 5         17 return $old;
110             }
111              
112             sub _port
113             {
114 552     552   622 my $self = shift;
115 552         909 my $old = $self->authority;
116 552 100       956 if (@_) {
117 61         80 my $new = $old;
118 61         181 $new =~ s/:\d*$//;
119 61         85 my $port = shift;
120 61 100       142 $new .= ":$port" if defined $port;
121 61         132 $self->authority($new);
122             }
123 552 100 100     1876 return $1 if defined($old) && $old =~ /:(\d*)$/;
124 438         649 return;
125             }
126              
127             sub port
128             {
129 132     132 1 2519 my $self = shift;
130 132         366 my $port = $self->_port(@_);
131 132 100 100     528 $port = $self->default_port if !defined($port) || $port eq "";
132 132         330 $port;
133             }
134              
135             sub host_port
136             {
137 10     10 1 20 my $self = shift;
138 10         25 my $old = $self->authority;
139 10 100       20 $self->host(shift) if @_;
140 10 50       18 return undef unless defined $old;
141 10         37 $old =~ s/.*@//; # zap userinfo
142 10         18 $old =~ s/:$//; # empty port should be treated the same a no port
143 10 100       32 $old .= ":" . $self->port unless $old =~ /:\d+$/;
144 10         20 $old;
145             }
146              
147              
148 0     0 1 0 sub default_port { undef }
149              
150             sub canonical
151             {
152 410     410 1 461 my $self = shift;
153 410         798 my $other = $self->SUPER::canonical;
154 410   100     794 my $host = $other->host || "";
155 410         731 my $port = $other->_port;
156 410         577 my $uc_host = $host =~ /[A-Z]/;
157 410   100     781 my $def_port = defined($port) && ($port eq "" ||
158             $port == $self->default_port);
159             # strip leading zeros from non-default ports (e.g. 08080 -> 8080)
160 410   100     1238 my $norm_port = !$def_port && defined($port) && $port ne "" && $port =~ /^0\d/;
161 410 100 100     1285 if ($uc_host || $def_port || $norm_port) {
      100        
162 35 100       90 $other = $other->clone if $other == $self;
163 35 100       203 $other->host(lc $host) if $uc_host;
164 35 100       75 $other->port(undef) if $def_port;
165 35 100       80 $other->_port(int($port)) if $norm_port;
166             }
167 410         790 $other;
168             }
169              
170             1;