line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package URI; |
2
|
|
|
|
|
|
|
|
3
|
40
|
|
|
40
|
|
2145835
|
use strict; |
|
40
|
|
|
|
|
372
|
|
|
40
|
|
|
|
|
1185
|
|
4
|
40
|
|
|
40
|
|
196
|
use warnings; |
|
40
|
|
|
|
|
115
|
|
|
40
|
|
|
|
|
3258
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '5.19'; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
# 1=version 5.10 and earlier; 0=version 5.11 and later |
9
|
40
|
100
|
|
40
|
|
261
|
use constant HAS_RESERVED_SQUARE_BRACKETS => $ENV{URI_HAS_RESERVED_SQUARE_BRACKETS} ? 1 : 0; |
|
40
|
|
|
|
|
82
|
|
|
40
|
|
|
|
|
11907
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our ($ABS_REMOTE_LEADING_DOTS, $ABS_ALLOW_RELATIVE_SCHEME, $DEFAULT_QUERY_FORM_DELIMITER); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
my %implements; # mapping from scheme to implementor class |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Some "official" character classes |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $reserved = HAS_RESERVED_SQUARE_BRACKETS ? q(;/?:@&=+$,[]) : q(;/?:@&=+$,); |
18
|
|
|
|
|
|
|
our $mark = q(-_.!~*'()); #'; emacs |
19
|
|
|
|
|
|
|
our $unreserved = "A-Za-z0-9\Q$mark\E"; |
20
|
|
|
|
|
|
|
our $uric = quotemeta($reserved) . $unreserved . "%"; |
21
|
|
|
|
|
|
|
our $uric4host = $uric . ( HAS_RESERVED_SQUARE_BRACKETS ? '' : quotemeta( q([]) ) ); |
22
|
|
|
|
|
|
|
our $uric4user = quotemeta( q{!$'()*,;:._~%-+=%&} ) . "A-Za-z0-9" . ( HAS_RESERVED_SQUARE_BRACKETS ? quotemeta( q([]) ) : '' ); # RFC-3987: iuserinfo w/o UTF |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
our $scheme_re = '[a-zA-Z][a-zA-Z0-9.+\-]*'; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# These schemes don't have an IPv6+ address part. |
27
|
|
|
|
|
|
|
our $schemes_without_host_part_re = 'data|ldapi|urn|sqlite|sqlite3'; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# These schemes can have an IPv6+ authority part: |
30
|
|
|
|
|
|
|
# file, ftp, gopher, http, https, ldap, ldaps, mms, news, nntp, nntps, pop, rlogin, rtsp, rtspu, rsync, sip, sips, snews, |
31
|
|
|
|
|
|
|
# telnet, tn3270, ssh, sftp |
32
|
|
|
|
|
|
|
# (all DB URIs, i.e. cassandra, couch, couchdb, etc.), except 'sqlite:', 'sqlite3:'. Others? |
33
|
|
|
|
|
|
|
#MAINT: URI has no test coverage for DB schemes |
34
|
|
|
|
|
|
|
#MAINT: decoupling - perhaps let each class decide itself by defining a member function 'scheme_has_authority_part()'? |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
#MAINT: 'mailto:' needs special treatment for IPv* addresses / RFC 5321 (4.1.3). Until then: restore all '[', ']' |
37
|
|
|
|
|
|
|
# These schemes need fallback to previous (<= 5.10) encoding until a specific handler is available. |
38
|
|
|
|
|
|
|
our $fallback_schemes_re = 'mailto'; |
39
|
|
|
|
|
|
|
|
40
|
40
|
|
|
40
|
|
288
|
use Carp (); |
|
40
|
|
|
|
|
77
|
|
|
40
|
|
|
|
|
879
|
|
41
|
40
|
|
|
40
|
|
17242
|
use URI::Escape (); |
|
40
|
|
|
|
|
107
|
|
|
40
|
|
|
|
|
4259
|
|
42
|
|
|
|
|
|
|
|
43
|
845
|
|
|
845
|
|
53146
|
use overload ('""' => sub { ${$_[0]} }, |
|
845
|
|
|
|
|
4165
|
|
44
|
31
|
|
|
31
|
|
154
|
'==' => sub { _obj_eq(@_) }, |
45
|
1
|
|
|
1
|
|
1082
|
'!=' => sub { !_obj_eq(@_) }, |
46
|
40
|
|
|
|
|
438
|
fallback => 1, |
47
|
40
|
|
|
40
|
|
49072
|
); |
|
40
|
|
|
|
|
42190
|
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# Check if two objects are the same object |
50
|
|
|
|
|
|
|
sub _obj_eq { |
51
|
32
|
|
|
32
|
|
128
|
return overload::StrVal($_[0]) eq overload::StrVal($_[1]); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub new |
55
|
|
|
|
|
|
|
{ |
56
|
1213
|
|
|
1213
|
1
|
70639
|
my($class, $uri, $scheme) = @_; |
57
|
|
|
|
|
|
|
|
58
|
1213
|
50
|
|
|
|
3175
|
$uri = defined ($uri) ? "$uri" : ""; # stringify |
59
|
|
|
|
|
|
|
# Get rid of potential wrapping |
60
|
1213
|
|
|
|
|
2323
|
$uri =~ s/^<(?:URL:)?(.*)>$/$1/; # |
61
|
1213
|
|
|
|
|
1668
|
$uri =~ s/^"(.*)"$/$1/; |
62
|
1213
|
|
|
|
|
2738
|
$uri =~ s/^\s+//; |
63
|
1213
|
|
|
|
|
2123
|
$uri =~ s/\s+$//; |
64
|
|
|
|
|
|
|
|
65
|
1213
|
|
|
|
|
1466
|
my $impclass; |
66
|
1213
|
100
|
|
|
|
5071
|
if ($uri =~ m/^($scheme_re):/so) { |
67
|
922
|
|
|
|
|
2106
|
$scheme = $1; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
else { |
70
|
291
|
100
|
66
|
|
|
1890
|
if (($impclass = ref($scheme))) { |
|
|
100
|
|
|
|
|
|
71
|
11
|
|
|
|
|
50
|
$scheme = $scheme->scheme; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
elsif ($scheme && $scheme =~ m/^($scheme_re)(?::|$)/o) { |
74
|
136
|
|
|
|
|
383
|
$scheme = $1; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
$impclass ||= implementor($scheme) || |
78
|
1213
|
|
66
|
|
|
4065
|
do { |
|
|
|
66
|
|
|
|
|
79
|
|
|
|
|
|
|
require URI::_foreign; |
80
|
|
|
|
|
|
|
$impclass = 'URI::_foreign'; |
81
|
|
|
|
|
|
|
}; |
82
|
|
|
|
|
|
|
|
83
|
1213
|
|
|
|
|
3533
|
return $impclass->_init($uri, $scheme); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
sub new_abs |
88
|
|
|
|
|
|
|
{ |
89
|
1
|
|
|
1
|
1
|
402
|
my($class, $uri, $base) = @_; |
90
|
1
|
|
|
|
|
4
|
$uri = $class->new($uri, $base); |
91
|
1
|
|
|
|
|
8
|
$uri->abs($base); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _init |
96
|
|
|
|
|
|
|
{ |
97
|
1211
|
|
|
1211
|
|
1888
|
my $class = shift; |
98
|
1211
|
|
|
|
|
2151
|
my($str, $scheme) = @_; |
99
|
|
|
|
|
|
|
# find all funny characters and encode the bytes. |
100
|
1211
|
|
|
|
|
3031
|
$str = $class->_uric_escape($str); |
101
|
1211
|
50
|
66
|
|
|
5349
|
$str = "$scheme:$str" unless $str =~ /^$scheme_re:/o || |
102
|
|
|
|
|
|
|
$class->_no_scheme_ok; |
103
|
1211
|
|
|
|
|
2554
|
my $self = bless \$str, $class; |
104
|
1211
|
|
|
|
|
3905
|
$self; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
#-- Version: 5.11+ |
109
|
|
|
|
|
|
|
# Since the complete URI will be percent-encoded including '[' and ']', |
110
|
|
|
|
|
|
|
# we selectively unescape square brackets from the authority/host part of the URI. |
111
|
|
|
|
|
|
|
# Derived modules that implement _uric_escape() should take this into account |
112
|
|
|
|
|
|
|
# if they do not rely on URI::_uric_escape(). |
113
|
|
|
|
|
|
|
# No unescaping is performed for the userinfo@ part of the authority part. |
114
|
|
|
|
|
|
|
sub _fix_uric_escape_for_host_part { |
115
|
1211
|
|
|
1211
|
|
1439
|
return if HAS_RESERVED_SQUARE_BRACKETS; |
116
|
1205
|
100
|
|
|
|
3057
|
return if $_[0] !~ /%/; |
117
|
73
|
100
|
|
|
|
719
|
return if $_[0] =~ m{^(?:$URI::schemes_without_host_part_re):}os; |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# until a scheme specific handler is available, fall back to previous behavior of v5.10 (i.e. 'mailto:') |
120
|
69
|
100
|
|
|
|
466
|
if ($_[0] =~ m{^(?:$URI::fallback_schemes_re):}os) { |
121
|
10
|
|
|
|
|
26
|
$_[0] =~ s/\%5B/[/gi; |
122
|
10
|
|
|
|
|
23
|
$_[0] =~ s/\%5D/]/gi; |
123
|
10
|
|
|
|
|
16
|
return; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
59
|
100
|
|
|
|
765
|
if ($_[0] =~ m{^((?:$URI::scheme_re:)?)//([^/?\#]+)(.*)$}os) { |
127
|
44
|
|
|
|
|
148
|
my $orig = $2; |
128
|
44
|
|
|
|
|
276
|
my ($user, $host) = $orig =~ /^(.*@)?([^@]*)$/; |
129
|
44
|
|
100
|
|
|
204
|
$user ||= ''; |
130
|
44
|
100
|
|
|
|
190
|
my $port = $host =~ s/(:\d+)$// ? $1 : ''; |
131
|
|
|
|
|
|
|
#MAINT: die() here if scheme indicates TCP/UDP and port is out of range [0..65535] ? |
132
|
44
|
|
|
|
|
190
|
$host =~ s/\%5B/[/gi; |
133
|
44
|
|
|
|
|
126
|
$host =~ s/\%5D/]/gi; |
134
|
44
|
|
|
|
|
701
|
$_[0] =~ s/\Q$orig\E/$user$host$port/; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub _uric_escape |
140
|
|
|
|
|
|
|
{ |
141
|
1211
|
|
|
1211
|
|
2130
|
my($class, $str) = @_; |
142
|
1211
|
|
|
|
|
3105
|
$str =~ s*([^$uric\#])* URI::Escape::escape_char($1) *ego; |
|
255
|
|
|
|
|
505
|
|
143
|
1211
|
|
|
|
|
2462
|
_fix_uric_escape_for_host_part( $str ); |
144
|
1211
|
|
|
|
|
2662
|
utf8::downgrade($str); |
145
|
1211
|
|
|
|
|
2284
|
return $str; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my %require_attempted; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub implementor |
151
|
|
|
|
|
|
|
{ |
152
|
1202
|
|
|
1202
|
0
|
2194
|
my($scheme, $impclass) = @_; |
153
|
1202
|
100
|
66
|
|
|
6022
|
if (!$scheme || $scheme !~ /\A$scheme_re\z/o) { |
154
|
144
|
|
|
|
|
716
|
require URI::_generic; |
155
|
144
|
|
|
|
|
591
|
return "URI::_generic"; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
1058
|
|
|
|
|
2252
|
$scheme = lc($scheme); |
159
|
|
|
|
|
|
|
|
160
|
1058
|
50
|
|
|
|
1781
|
if ($impclass) { |
161
|
|
|
|
|
|
|
# Set the implementor class for a given scheme |
162
|
0
|
|
|
|
|
0
|
my $old = $implements{$scheme}; |
163
|
0
|
|
|
|
|
0
|
$impclass->_init_implementor($scheme); |
164
|
0
|
|
|
|
|
0
|
$implements{$scheme} = $impclass; |
165
|
0
|
|
|
|
|
0
|
return $old; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
1058
|
|
|
|
|
1843
|
my $ic = $implements{$scheme}; |
169
|
1058
|
100
|
|
|
|
3991
|
return $ic if $ic; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# scheme not yet known, look for internal or |
172
|
|
|
|
|
|
|
# preloaded (with 'use') implementation |
173
|
105
|
|
|
|
|
216
|
$ic = "URI::$scheme"; # default location |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# turn scheme into a valid perl identifier by a simple transformation... |
176
|
105
|
|
|
|
|
239
|
$ic =~ s/\+/_P/g; |
177
|
105
|
|
|
|
|
178
|
$ic =~ s/\./_O/g; |
178
|
105
|
|
|
|
|
175
|
$ic =~ s/\-/_/g; |
179
|
|
|
|
|
|
|
|
180
|
40
|
|
|
40
|
|
42421
|
no strict 'refs'; |
|
40
|
|
|
|
|
145
|
|
|
40
|
|
|
|
|
63516
|
|
181
|
|
|
|
|
|
|
# check we actually have one for the scheme: |
182
|
105
|
100
|
|
|
|
147
|
unless (@{"${ic}::ISA"}) { |
|
105
|
|
|
|
|
5051
|
|
183
|
101
|
50
|
|
|
|
333
|
if (not exists $require_attempted{$ic}) { |
184
|
|
|
|
|
|
|
# Try to load it |
185
|
101
|
|
|
|
|
181
|
my $_old_error = $@; |
186
|
101
|
|
|
|
|
5264
|
eval "require $ic"; |
187
|
101
|
50
|
66
|
|
|
1173
|
die $@ if $@ && $@ !~ /Can\'t locate.*in \@INC/; |
188
|
101
|
|
|
|
|
341
|
$@ = $_old_error; |
189
|
|
|
|
|
|
|
} |
190
|
101
|
100
|
|
|
|
160
|
return undef unless @{"${ic}::ISA"}; |
|
101
|
|
|
|
|
654
|
|
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
60
|
|
|
|
|
669
|
$ic->_init_implementor($scheme); |
194
|
60
|
|
|
|
|
187
|
$implements{$scheme} = $ic; |
195
|
60
|
|
|
|
|
349
|
$ic; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub _init_implementor |
200
|
|
|
|
|
|
|
{ |
201
|
60
|
|
|
60
|
|
270
|
my($class, $scheme) = @_; |
202
|
|
|
|
|
|
|
# Remember that one implementor class may actually |
203
|
|
|
|
|
|
|
# serve to implement several URI schemes. |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
sub clone |
208
|
|
|
|
|
|
|
{ |
209
|
420
|
|
|
420
|
1
|
821
|
my $self = shift; |
210
|
420
|
|
|
|
|
699
|
my $other = $$self; |
211
|
420
|
|
|
|
|
990
|
bless \$other, ref $self; |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
|
214
|
0
|
|
|
0
|
0
|
0
|
sub TO_JSON { ${$_[0]} } |
|
0
|
|
|
|
|
0
|
|
215
|
|
|
|
|
|
|
|
216
|
0
|
|
|
0
|
|
0
|
sub _no_scheme_ok { 0 } |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub _scheme |
219
|
|
|
|
|
|
|
{ |
220
|
1552
|
|
|
1552
|
|
1923
|
my $self = shift; |
221
|
|
|
|
|
|
|
|
222
|
1552
|
100
|
|
|
|
2871
|
unless (@_) { |
223
|
1219
|
100
|
|
|
|
6432
|
return undef unless $$self =~ /^($scheme_re):/o; |
224
|
903
|
|
|
|
|
2865
|
return $1; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
333
|
|
|
|
|
415
|
my $old; |
228
|
333
|
|
|
|
|
483
|
my $new = shift; |
229
|
333
|
100
|
100
|
|
|
1217
|
if (defined($new) && length($new)) { |
230
|
269
|
50
|
|
|
|
1306
|
Carp::croak("Bad scheme '$new'") unless $new =~ /^$scheme_re$/o; |
231
|
269
|
100
|
|
|
|
1141
|
$old = $1 if $$self =~ s/^($scheme_re)://o; |
232
|
269
|
|
|
|
|
902
|
my $newself = URI->new("$new:$$self"); |
233
|
269
|
|
|
|
|
698
|
$$self = $$newself; |
234
|
269
|
|
|
|
|
599
|
bless $self, ref($newself); |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
else { |
237
|
64
|
50
|
|
|
|
185
|
if ($self->_no_scheme_ok) { |
238
|
64
|
50
|
|
|
|
541
|
$old = $1 if $$self =~ s/^($scheme_re)://o; |
239
|
64
|
50
|
33
|
|
|
233
|
Carp::carp("Oops, opaque part now look like scheme") |
240
|
|
|
|
|
|
|
if $^W && $$self =~ m/^$scheme_re:/o |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
else { |
243
|
0
|
0
|
|
|
|
0
|
$old = $1 if $$self =~ m/^($scheme_re):/o; |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
333
|
|
|
|
|
587
|
return $old; |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub scheme |
251
|
|
|
|
|
|
|
{ |
252
|
1084
|
|
|
1084
|
1
|
2100
|
my $scheme = shift->_scheme(@_); |
253
|
1084
|
100
|
|
|
|
2558
|
return undef unless defined $scheme; |
254
|
584
|
|
|
|
|
1533
|
lc($scheme); |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
sub has_recognized_scheme { |
258
|
5
|
|
|
5
|
1
|
37
|
my $self = shift; |
259
|
5
|
|
|
|
|
35
|
return ref($self) !~ /^URI::_(?:foreign|generic)\z/; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub opaque |
263
|
|
|
|
|
|
|
{ |
264
|
84
|
|
|
84
|
1
|
128
|
my $self = shift; |
265
|
|
|
|
|
|
|
|
266
|
84
|
100
|
|
|
|
179
|
unless (@_) { |
267
|
57
|
50
|
|
|
|
706
|
$$self =~ /^(?:$scheme_re:)?([^\#]*)/o or die; |
268
|
57
|
|
|
|
|
336
|
return $1; |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
27
|
50
|
|
|
|
400
|
$$self =~ /^($scheme_re:)? # optional scheme |
272
|
|
|
|
|
|
|
([^\#]*) # opaque |
273
|
|
|
|
|
|
|
(\#.*)? # optional fragment |
274
|
|
|
|
|
|
|
$/sx or die; |
275
|
|
|
|
|
|
|
|
276
|
27
|
|
|
|
|
66
|
my $old_scheme = $1; |
277
|
27
|
|
|
|
|
59
|
my $old_opaque = $2; |
278
|
27
|
|
|
|
|
49
|
my $old_frag = $3; |
279
|
|
|
|
|
|
|
|
280
|
27
|
|
|
|
|
39
|
my $new_opaque = shift; |
281
|
27
|
100
|
|
|
|
52
|
$new_opaque = "" unless defined $new_opaque; |
282
|
27
|
|
|
|
|
221
|
$new_opaque =~ s/([^$uric])/ URI::Escape::escape_char($1)/ego; |
|
14
|
|
|
|
|
38
|
|
283
|
27
|
|
|
|
|
71
|
utf8::downgrade($new_opaque); |
284
|
|
|
|
|
|
|
|
285
|
27
|
100
|
|
|
|
62
|
$$self = defined($old_scheme) ? $old_scheme : ""; |
286
|
27
|
|
|
|
|
70
|
$$self .= $new_opaque; |
287
|
27
|
100
|
|
|
|
58
|
$$self .= $old_frag if defined $old_frag; |
288
|
|
|
|
|
|
|
|
289
|
27
|
|
|
|
|
73
|
$old_opaque; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
1
|
|
|
1
|
1
|
17
|
sub path { goto &opaque } # alias |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub fragment |
296
|
|
|
|
|
|
|
{ |
297
|
71
|
|
|
71
|
1
|
126
|
my $self = shift; |
298
|
71
|
100
|
|
|
|
150
|
unless (@_) { |
299
|
51
|
100
|
|
|
|
248
|
return undef unless $$self =~ /\#(.*)/s; |
300
|
24
|
|
|
|
|
140
|
return $1; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
|
303
|
20
|
|
|
|
|
28
|
my $old; |
304
|
20
|
100
|
|
|
|
92
|
$old = $1 if $$self =~ s/\#(.*)//s; |
305
|
|
|
|
|
|
|
|
306
|
20
|
|
|
|
|
34
|
my $new_frag = shift; |
307
|
20
|
100
|
|
|
|
44
|
if (defined $new_frag) { |
308
|
18
|
|
|
|
|
159
|
$new_frag =~ s/([^$uric])/ URI::Escape::escape_char($1) /ego; |
|
2
|
|
|
|
|
6
|
|
309
|
18
|
|
|
|
|
48
|
utf8::downgrade($new_frag); |
310
|
18
|
|
|
|
|
48
|
$$self .= "#$new_frag"; |
311
|
|
|
|
|
|
|
} |
312
|
20
|
|
|
|
|
40
|
$old; |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub as_string |
317
|
|
|
|
|
|
|
{ |
318
|
726
|
|
|
726
|
1
|
2391
|
my $self = shift; |
319
|
726
|
|
|
|
|
3062
|
$$self; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub as_iri |
324
|
|
|
|
|
|
|
{ |
325
|
15
|
|
|
15
|
1
|
22
|
my $self = shift; |
326
|
15
|
|
|
|
|
25
|
my $str = $$self; |
327
|
15
|
100
|
|
|
|
74
|
if ($str =~ s/%([89a-fA-F][0-9a-fA-F])/chr(hex($1))/eg) { |
|
274
|
|
|
|
|
636
|
|
328
|
|
|
|
|
|
|
# All this crap because the more obvious: |
329
|
|
|
|
|
|
|
# |
330
|
|
|
|
|
|
|
# Encode::decode("UTF-8", $str, sub { sprintf "%%%02X", shift }) |
331
|
|
|
|
|
|
|
# |
332
|
|
|
|
|
|
|
# doesn't work before Encode 2.39. Wait for a standard release |
333
|
|
|
|
|
|
|
# to bundle that version. |
334
|
|
|
|
|
|
|
|
335
|
10
|
|
|
|
|
54
|
require Encode; |
336
|
10
|
|
|
|
|
30
|
my $enc = Encode::find_encoding("UTF-8"); |
337
|
10
|
|
|
|
|
307
|
my $u = ""; |
338
|
10
|
|
|
|
|
26
|
while (length $str) { |
339
|
13
|
|
|
|
|
67
|
$u .= $enc->decode($str, Encode::FB_QUIET()); |
340
|
13
|
100
|
|
|
|
101
|
if (length $str) { |
341
|
|
|
|
|
|
|
# escape next char |
342
|
3
|
|
|
|
|
17
|
$u .= URI::Escape::escape_char(substr($str, 0, 1, "")); |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
} |
345
|
10
|
|
|
|
|
20
|
$str = $u; |
346
|
|
|
|
|
|
|
} |
347
|
15
|
|
|
|
|
40
|
return $str; |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub canonical |
352
|
|
|
|
|
|
|
{ |
353
|
|
|
|
|
|
|
# Make sure scheme is lowercased, that we don't escape unreserved chars, |
354
|
|
|
|
|
|
|
# and that we use upcase escape sequences. |
355
|
|
|
|
|
|
|
|
356
|
457
|
|
|
457
|
1
|
612
|
my $self = shift; |
357
|
457
|
|
100
|
|
|
951
|
my $scheme = $self->_scheme || ""; |
358
|
457
|
|
|
|
|
957
|
my $uc_scheme = $scheme =~ /[A-Z]/; |
359
|
457
|
|
|
|
|
824
|
my $esc = $$self =~ /%[a-fA-F0-9]{2}/; |
360
|
457
|
100
|
100
|
|
|
1967
|
return $self unless $uc_scheme || $esc; |
361
|
|
|
|
|
|
|
|
362
|
52
|
|
|
|
|
147
|
my $other = $self->clone; |
363
|
52
|
100
|
|
|
|
124
|
if ($uc_scheme) { |
364
|
10
|
|
|
|
|
30
|
$other->_scheme(lc $scheme); |
365
|
|
|
|
|
|
|
} |
366
|
52
|
100
|
|
|
|
115
|
if ($esc) { |
367
|
42
|
|
|
|
|
188
|
$$other =~ s{%([0-9a-fA-F]{2})} |
|
189
|
|
|
|
|
407
|
|
368
|
189
|
100
|
|
|
|
806
|
{ my $a = chr(hex($1)); |
369
|
|
|
|
|
|
|
$a =~ /^[$unreserved]\z/o ? $a : "%\U$1" |
370
|
|
|
|
|
|
|
}ge; |
371
|
52
|
|
|
|
|
153
|
} |
372
|
|
|
|
|
|
|
return $other; |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
# Compare two URIs, subclasses will provide a more correct implementation |
376
|
15
|
|
|
15
|
1
|
40
|
sub eq { |
377
|
15
|
50
|
|
|
|
38
|
my($self, $other) = @_; |
378
|
15
|
100
|
|
|
|
45
|
$self = URI->new($self, $other) unless ref $self; |
379
|
15
|
50
|
|
|
|
65
|
$other = URI->new($other, $self) unless ref $other; |
380
|
|
|
|
|
|
|
ref($self) eq ref($other) && # same class |
381
|
|
|
|
|
|
|
$self->canonical->as_string eq $other->canonical->as_string; |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
1
|
|
|
1
|
1
|
8
|
# generic-URI transformation methods |
385
|
1
|
|
|
1
|
1
|
5
|
sub abs { $_[0]; } |
386
|
|
|
|
|
|
|
sub rel { $_[0]; } |
387
|
3
|
|
|
3
|
1
|
18
|
|
388
|
|
|
|
|
|
|
sub secure { 0 } |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# help out Storable |
391
|
0
|
|
|
0
|
0
|
|
sub STORABLE_freeze { |
392
|
0
|
|
|
|
|
|
my($self, $cloning) = @_; |
393
|
|
|
|
|
|
|
return $$self; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
0
|
|
|
0
|
0
|
|
sub STORABLE_thaw { |
397
|
0
|
|
|
|
|
|
my($self, $cloning, $str) = @_; |
398
|
|
|
|
|
|
|
$$self = $str; |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
1; |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
__END__ |