/[suikacvs]/messaging/manakai/lib/Message/URI/URIReference.pm
Suika

Contents of /messaging/manakai/lib/Message/URI/URIReference.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations) (download)
Mon Nov 10 05:30:59 2008 UTC (16 years ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +4 -4 lines
++ manakai/lib/Message/CGI/ChangeLog	10 Nov 2008 05:30:33 -0000
2008-11-10  Wakaba  <wakaba@suika.fam.cx>

	* HTTP.pm (request_uri): Percent-escape non-ASCII octets in
	REQUEST_URI to avoid they become unclear whether they are bytes or
	characters in later processing.

++ manakai/lib/Message/URI/ChangeLog	10 Nov 2008 05:30:51 -0000
2008-11-10  Wakaba  <wakaba@suika.fam.cx>

	* URIReference.pm (is_relative_iri_reference_3987): Escapes in
	$ucschar was not expanded.

1 package Message::URI::URIReference;
2 use strict;
3 our $VERSION=do{my @r=(q$Revision: 1.6 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
4
5 package Message::IF::URIImplementation;
6 package Message::DOM::DOMImplementation;
7 push our @ISA, 'Message::IF::URIImplementation';
8
9 sub create_uri_reference ($$) {
10 if (UNIVERSAL::isa ($_[1], 'Message::IF::URIReference')) {
11 local $Error::Depth = $Error::Depth + 1;
12 my $uri = $_[1]->uri_reference;
13 return bless \$uri, 'Message::URI::URIReference';
14 } elsif (ref $_[1] eq 'SCALAR') {
15 my $uri = ''.${$_[1]};
16 return bless \$uri, 'Message::URI::URIReference';
17 } else {
18 my $uri = ''.$_[1];
19 return bless \$uri, 'Message::URI::URIReference';
20 }
21 } # create_uri_reference
22
23 package Message::IF::URIReference;
24 package Message::URI::URIReference;
25 push our @ISA, 'Message::IF::URIReference';
26
27 sub uri_reference ($;$) {
28 if (@_ == 1) {my ($self) = @_;
29 my $r = '';
30
31 {
32
33
34 $r = $$self;
35
36
37 }
38 $r;
39 } else {my ($self, $given) = @_;
40
41 {
42
43
44 $$self = $given;
45
46
47 {
48
49 local $Error::Depth = $Error::Depth + 1;
50
51 {
52
53
54
55 $self->
56 _on_scheme_changed
57 ;
58
59
60
61 }
62
63
64 ;}
65
66 ;
67
68
69 }
70 }
71 }
72 sub stringify ($) {
73 my ($self) = @_;
74 my $r = '';
75
76 {
77
78
79 $r = $$self;
80
81
82 }
83 $r}
84 sub _on_scheme_changed ($) {
85 my ($self) = @_;
86
87
88 }
89 sub _on_authority_changed ($) {
90 my ($self) = @_;
91
92
93 }
94 sub _on_path_changed ($) {
95 my ($self) = @_;
96
97
98 }
99 sub _on_query_changed ($) {
100 my ($self) = @_;
101
102
103 }
104 sub _on_fragment_changed ($) {
105 my ($self) = @_;
106
107
108 }
109 sub uri_scheme ($;$) {
110 if (@_ == 1) {my ($self) = @_;
111 my $r = '';
112
113 {
114
115 if
116 ($$self =~ m!^([^/?#:]+):!) {
117 $r = $1;
118 } else {
119 $r =
120 undef
121 ;
122 }
123
124
125 }
126 $r;
127 } else {my ($self, $given) = @_;
128
129 {
130
131 if
132 (defined $given) {
133 if (length $given and $given !~ m![/?#:]!) {
134 unless ($$self =~ s!^[^/?#:]+:!$given:!) {
135 $$self = $given . ':' . $$self;
136
137
138 {
139
140 local $Error::Depth = $Error::Depth + 1;
141
142 {
143
144
145
146 $self->
147 _on_scheme_changed
148 ;
149
150
151
152 }
153
154
155 ;}
156
157 ;
158 }
159 }
160 } else {
161 $$self =~ s!^[^/?#:]+:!!;
162
163
164 {
165
166 local $Error::Depth = $Error::Depth + 1;
167
168 {
169
170
171
172 $self->
173 _on_scheme_changed
174 ;
175
176
177
178 }
179
180
181 ;}
182
183 ;
184 }
185
186
187 }
188 }
189 }
190 sub uri_authority ($;$) {
191 if (@_ == 1) {my ($self) = @_;
192 my $r = '';
193
194 {
195
196 if
197 ($$self =~ m!^(?:[^:/?#]+:)?(?://([^/?#]*))?!) {
198 $r = $1;
199 } else {
200 $r =
201 undef
202 ;
203 }
204
205
206 }
207 $r;
208 } else {my ($self, $given) = @_;
209
210 {
211
212 if
213 (defined $given) {
214 unless ($given =~ m![/?#]!) {
215 unless ($$self =~ s!^((?:[^:/?#]+:)?)(?://[^/?#]*)?!$1//$given!) {
216 $$self = '//' . $given;
217
218
219 {
220
221 local $Error::Depth = $Error::Depth + 1;
222
223 {
224
225
226
227 $self->
228 _on_authority_changed
229 ;
230
231
232
233 }
234
235
236 ;}
237
238 ;
239 }
240 }
241 } else {
242 if ($$self =~ s!^((?:[^:/?#]+:)?)(?://[^/?#]*)?!$1!) {
243
244
245 {
246
247 local $Error::Depth = $Error::Depth + 1;
248
249 {
250
251
252
253 $self->
254 _on_authority_changed
255 ;
256
257
258
259 }
260
261
262 ;}
263
264 ;
265 }
266 }
267
268
269 }
270 }
271 }
272 sub uri_userinfo ($;$) {
273 if (@_ == 1) {my ($self) = @_;
274 my $r = '';
275
276 {
277
278
279 {
280
281 local $Error::Depth = $Error::Depth + 1;
282
283 {
284
285
286 my
287 $v = $self->
288 uri_authority
289 ;
290 if (defined $v and $v =~ /^([^@\[\]]*)\@/) {
291 $r = $1;
292 } else {
293 $r =
294 undef
295 ;
296 }
297
298
299
300 }
301
302
303 ;}
304
305 ;
306
307
308 }
309 $r;
310 } else {my ($self, $given) = @_;
311
312 {
313
314
315 {
316
317 local $Error::Depth = $Error::Depth + 1;
318
319 {
320
321
322 my
323 $auth = $self->
324 uri_authority
325 ;
326 if (defined $auth) {
327 if (defined $given) {
328 unless ($auth =~ s/^[^\@\[\]]*\@/$given\@/) {
329 $auth = $given . '@' . $auth;
330 }
331 } else {
332 $auth =~ s/^[^\@\[\]]*\@//;
333 }
334 $self->
335 uri_authority
336 ($auth);
337 } else {
338 if (defined $given and $given !~ /[\/#?\@\[\]]/) {
339 $self->
340 uri_authority
341 ($given.'@');
342 }
343 }
344
345
346
347 }
348
349
350 ;}
351
352 ;
353
354
355 }
356 }
357 }
358 sub uri_host ($;$) {
359 if (@_ == 1) {my ($self) = @_;
360 my $r = '';
361
362 {
363
364
365 {
366
367 local $Error::Depth = $Error::Depth + 1;
368
369 {
370
371
372 my
373 $v = $self->
374 uri_authority
375 ;
376 if (defined $v) {
377 $v =~ s/^[^@\[\]]*\@//;
378 $v =~ s/:[0-9]*\z//;
379 $r = $v;
380 } else {
381 $r =
382 undef
383 ;
384 }
385
386
387
388 }
389
390
391 ;}
392
393 ;
394
395
396 }
397 $r;
398 } else {my ($self, $given) = @_;
399
400 {
401
402
403 {
404
405 local $Error::Depth = $Error::Depth + 1;
406
407 {
408
409
410 my
411 $auth = $self->
412 uri_authority
413 ;
414 if (defined $auth) {
415 my $v = '';
416 if ($auth =~ /^([^\@\[\]]*\@)/) {
417 $v .= $1;
418 }
419 $v .= $given;
420 if ($auth =~ /(:[0-9]*)\z/) {
421 $v .= $1;
422 }
423 $self->
424 uri_authority
425 ($v);
426 } elsif ($given !~ /[\/\@:#?]/) {
427 $self->
428 uri_authority
429 ($given);
430 }
431
432
433
434 }
435
436
437 ;}
438
439 ;
440
441
442 }
443 }
444 }
445 sub uri_port ($;$) {
446 if (@_ == 1) {my ($self) = @_;
447 my $r = '';
448
449 {
450
451
452 {
453
454 local $Error::Depth = $Error::Depth + 1;
455
456 {
457
458
459 my
460 $v = $self->
461 uri_authority
462 ;
463 if (defined $v and $v =~ /:([0-9]*)\z/) {
464 $r = $1;
465 } else {
466 $r =
467 undef
468 ;
469 }
470
471
472
473 }
474
475
476 ;}
477
478 ;
479
480
481 }
482 $r;
483 } else {my ($self, $given) = @_;
484
485 {
486
487
488 {
489
490 local $Error::Depth = $Error::Depth + 1;
491
492 {
493
494
495 my
496 $auth = $self->
497 uri_authority
498 ;
499 if (defined $auth) {
500 if (defined $given) {
501 unless ($auth =~ s/:[0-9]*\z/:$given/) {
502 $auth = $auth . ':' . $given;
503 }
504 } else {
505 $auth =~ s/:[0-9]*\z//;
506 }
507 $self->
508 uri_authority
509 ($auth);
510 } else {
511 if (defined $given and $given =~ /\A[0-9]*\z/) {
512 $self->
513 uri_authority
514 (':'.$given);
515 }
516 }
517
518
519
520 }
521
522
523 ;}
524
525 ;
526
527
528 }
529 }
530 }
531 sub uri_path ($;$) {
532 if (@_ == 1) {my ($self) = @_;
533 my $r = '';
534
535 {
536
537 if
538 ($$self =~ m!\A(?:[^:/?#]+:)?(?://[^/?#]*)?([^?#]*)!) {
539 $r = $1;
540 }
541
542
543 }
544 $r;
545 } else {my ($self, $given) = @_;
546
547 {
548
549 if
550 ($given !~ /[?#]/ and
551 $$self =~ m!^((?:[^:/?#]+:)?(?://[^/?#]*)?)[^?#]*((?:\?[^#]*)?(?:#.*)?)!s) {
552 $$self = $1.$given.$2;
553
554
555 {
556
557 local $Error::Depth = $Error::Depth + 1;
558
559 {
560
561
562
563 $self->
564 _on_path_changed
565 ;
566
567
568
569 }
570
571
572 ;}
573
574 ;
575 }
576
577
578 }
579 }
580 }
581 sub uri_query ($;$) {
582 if (@_ == 1) {my ($self) = @_;
583 my $r = '';
584
585 {
586
587 if
588 ($$self =~ m!^(?:[^:/?#]+:)?(?://[^/?#]*)?[^?#]*(?:\?([^#]*))?!s) {
589 $r = $1;
590 } else {
591 $r =
592 undef
593 ;
594 }
595
596
597 }
598 $r;
599 } else {my ($self, $given) = @_;
600
601 {
602
603 if
604 ((not defined $given or $given !~ /#/) and
605 $$self =~ m!^((?:[^:/?#]+:)?(?://[^/?#]*)?[^?#]*)(?:\?[^#]*)?((?:#.*)?)!s) {
606 $$self = defined $given ? $1.'?'.$given.$2 : $1.$2;
607
608
609 {
610
611 local $Error::Depth = $Error::Depth + 1;
612
613 {
614
615
616
617 $self->
618 _on_query_changed
619 ;
620
621
622
623 }
624
625
626 ;}
627
628 ;
629 }
630
631
632 }
633 }
634 }
635 sub uri_fragment ($;$) {
636 if (@_ == 1) {my ($self) = @_;
637 my $r = '';
638
639 {
640
641 if
642 ($$self =~ m!^(?:[^:/?#]+:)?(?://[^/?#]*)?[^?#]*(?:\?[^#]*)?(?:#(.*))?!s) {
643 $r = $1;
644 } else {
645 $r =
646 undef
647 ;
648 }
649
650
651 }
652 $r;
653 } else {my ($self, $given) = @_;
654
655 {
656
657 if
658 ($$self =~ m!^((?:[^:/?#]+:)?(?://[^/?#]*)?[^?#]*(?:\?[^#]*)?)(?:#.*)?!s) {
659 $$self = defined $given ? $1 . '#' . $given : $1;
660
661
662 {
663
664 local $Error::Depth = $Error::Depth + 1;
665
666 {
667
668
669
670 $self->
671 _on_fragment_changed
672 ;
673
674
675
676 }
677
678
679 ;}
680
681 ;
682 }
683
684
685 }
686 }
687 }
688 sub get_uri_path_segment ($$) {
689 my ($self, $index) = @_;
690 my $r = '';
691
692 {
693
694
695 {
696
697 local $Error::Depth = $Error::Depth + 1;
698
699 {
700
701
702
703 $r = [split m!/!, $self->
704 uri_path
705 , -1]->[$index];
706 $r = '' if not defined $r and
707 ($index == 0 or $index == -1); # If path is empty
708
709
710
711 }
712
713
714 ;}
715
716 ;
717
718
719 }
720 $r}
721 sub set_uri_path_segment ($$;$) {
722 my ($self, $index, $newValue) = @_;
723
724 {
725
726
727 {
728
729 local $Error::Depth = $Error::Depth + 1;
730
731 {
732
733
734 my
735 @p = split m!/!, $self->
736 uri_path
737 , -1;
738 if (defined $newValue) {
739 $p[$index] = $newValue;
740 } else {
741 splice @p, $index, 1;
742 }
743 no warnings 'uninitialized';
744 $self->
745 uri_path
746 (join '/', @p);
747
748
749
750 }
751
752
753 ;}
754
755 ;
756
757
758 }
759 }
760
761 ## TODO: An attribute that returns the number of path segments is necessary.
762
763 *is_uri = \&is_uri_3986;
764
765 sub is_uri_3986 ($) {
766 my $self = $_[0];
767 my $r = 0;
768
769 {
770
771 my
772 $v = $$self;
773 V: {
774 ## -- Scheme
775 unless ($v =~ s/^[A-Za-z][A-Za-z0-9+.-]*://s) {
776 last V;
777 }
778
779 ## -- Fragment
780 if ($v =~ s/#(.*)\z//s) {
781 my $w = $1;
782 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}) {
783 last V;
784 }
785 }
786
787 ## -- Query
788 if ($v =~ s/\?(.*)\z//s) {
789 my $w = $1;
790 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}) {
791 last V;
792 }
793 }
794
795 ## -- Authority
796 if ($v =~ s!^//([^/]*)!!s) {
797 my $w = $1;
798 $w =~ s/^(?>[A-Za-z0-9._~!\$&'()*+,;=:-]|%[0-9A-Fa-f][0-9A-Fa-f])*\@//os;
799 $w =~ s/:[0-9]*\z//;
800 if ($w =~ /^\[(.*)\]\z/s) {
801 my $x = $1;
802 unless ($x =~ /\A[vV][0-9A-Fa-f]+\.[A-Za-z0-9._~!\$&'()*+,;=:-]+\z/) {
803 ## IPv6address
804 my $isv6;
805
806
807 {
808
809 my
810 $ipv4 = qr/(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)(?>\.(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)){3}/;
811 my $h16 = qr/[0-9A-Fa-f]{1,4}/;
812 if ($x =~ s/(?:$ipv4|$h16)\z//o) {
813 if ($x =~ /\A(?>$h16:){6}\z/o or
814 $x =~ /\A::(?>$h16:){0,5}\z/o or
815 $x =~ /\A${h16}::(?>$h16:){4}\z/o or
816 $x =~ /\A$h16(?::$h16)?::(?>$h16:){3}\z/o or
817 $x =~ /\A$h16(?::$h16){0,2}::(?>$h16:){2}\z/o or
818 $x =~ /\A$h16(?::$h16){0,3}::$h16:\z/o or
819 $x =~ /\A$h16(?::$h16){0,4}::\z/o) {
820 $isv6 =
821 1
822 ;
823 }
824 } elsif ($x =~ s/$h16\z//o) {
825 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,5}\z/o) {
826 $isv6 =
827 1
828 ;
829 }
830 } elsif ($x =~ s/::\z//o) {
831 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,6}\z/o) {
832 $isv6 =
833 1
834 ;
835 }
836 }
837
838
839 }
840
841 ;
842 last V unless $isv6;
843 }
844 } else {
845 unless ($w =~ /\A(?>[A-Za-z0-9._~!\$&'()*+,;=-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z/) {
846 last V;
847 }
848 }
849 }
850
851 ## -- Path
852 unless ($v =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}s) {
853 last V;
854 }
855
856 $r =
857 1
858 ;
859 } # V
860
861
862 }
863 $r;
864 } # is_uri_3986
865
866 *is_relative_reference = \&is_relative_reference_3986;
867
868 sub is_relative_reference_3986 ($) {
869 my $self = $_[0];
870 my $r = 0;
871
872 {
873
874 my
875 $v = $$self;
876 V: {
877 ## -- No scheme
878 if ($v =~ s!^[^/?#]*:!!s) {
879 last V;
880 }
881
882 ## -- Fragment
883 if ($v =~ s/#(.*)\z//s) {
884 my $w = $1;
885 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}) {
886 last V;
887 }
888 }
889
890 ## -- Query
891 if ($v =~ s/\?(.*)\z//s) {
892 my $w = $1;
893 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}) {
894 last V;
895 }
896 }
897
898 ## -- Authority
899 if ($v =~ s!^//([^/]*)!!s) {
900 my $w = $1;
901 $w =~ s/^(?>[A-Za-z0-9._~!\$&'()*+,;=:-]|%[0-9A-Fa-f][0-9A-Fa-f])*\@//os;
902 $w =~ s/:[0-9]*\z//;
903 if ($w =~ /^\[(.*)\]\z/s) {
904 my $x = $1;
905 unless ($x =~ /\A[vV][0-9A-Fa-f]+\.[A-Za-z0-9._~!\$&'()*+,;=:-]+\z/) {
906 ## IPv6address
907 my $isv6;
908
909
910 {
911
912 my
913 $ipv4 = qr/(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)(?>\.(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)){3}/;
914 my $h16 = qr/[0-9A-Fa-f]{1,4}/;
915 if ($x =~ s/(?:$ipv4|$h16)\z//o) {
916 if ($x =~ /\A(?>$h16:){6}\z/o or
917 $x =~ /\A::(?>$h16:){0,5}\z/o or
918 $x =~ /\A${h16}::(?>$h16:){4}\z/o or
919 $x =~ /\A$h16(?::$h16)?::(?>$h16:){3}\z/o or
920 $x =~ /\A$h16(?::$h16){0,2}::(?>$h16:){2}\z/o or
921 $x =~ /\A$h16(?::$h16){0,3}::$h16:\z/o or
922 $x =~ /\A$h16(?::$h16){0,4}::\z/o) {
923 $isv6 =
924 1
925 ;
926 }
927 } elsif ($x =~ s/$h16\z//o) {
928 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,5}\z/o) {
929 $isv6 =
930 1
931 ;
932 }
933 } elsif ($x =~ s/::\z//o) {
934 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,6}\z/o) {
935 $isv6 =
936 1
937 ;
938 }
939 }
940
941
942 }
943
944 ;
945 last V unless $isv6;
946 }
947 } else {
948 unless ($w =~ /\A(?>[A-Za-z0-9._~!\$&'()*+,;=-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z/) {
949 last V;
950 }
951 }
952 }
953
954 ## -- Path
955 unless ($v =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}s) {
956 last V;
957 }
958
959 $r =
960 1
961 ;
962 } # V
963
964
965 }
966 $r;
967 } # is_relative_reference_3986
968
969 *is_uri_reference = \&is_uri_reference_3986;
970
971 sub is_uri_reference_3986 ($) {
972 my $self = $_[0];
973 my $r = 0;
974
975 {
976
977
978 {
979
980 local $Error::Depth = $Error::Depth + 1;
981
982 {
983
984
985
986 $r = $self->
987 is_uri_3986
988 ||
989 $self->
990 is_relative_reference_3986
991 ;
992
993
994
995 }
996
997
998 ;}
999
1000 ;
1001
1002
1003 }
1004 $r;
1005 } # is_uri_reference_3986
1006
1007 *is_absolute_uri = \&is_absolute_uri_3986;
1008
1009 sub is_absolute_uri_3986 ($) {
1010 my $self = $_[0];
1011 my $r = 0;
1012
1013 {
1014
1015
1016 {
1017
1018 local $Error::Depth = $Error::Depth + 1;
1019
1020 {
1021
1022
1023
1024 $r = $$self !~ /#/ && $self->
1025 is_uri_3986
1026 ;
1027
1028
1029
1030 }
1031
1032
1033 ;}
1034
1035 ;
1036
1037
1038 }
1039 $r;
1040 } # is_uri_reference_3986
1041
1042 sub is_empty_reference ($) {
1043 return ${$_[0]} eq '';
1044 } # is_empty_reference
1045
1046 *is_iri = \&is_iri_3987;
1047
1048 sub is_iri_3987 ($) {
1049 my $self = $_[0];
1050 my $r = 0;
1051
1052 {
1053
1054 my
1055 $v = $$self;
1056 V: {
1057 ## LRM, RLM, LRE, RLE, LRO, RLO, PDF
1058 ## U+200E, U+200F, U+202A - U+202E
1059 my $ucschar = qq{\x{00A0}-\x{200D}\x{2010}-\x{2029}\x{202F}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}};
1060
1061 ## -- Scheme
1062 unless ($v =~ s/^[A-Za-z][A-Za-z0-9+.-]*://s) {
1063 last V;
1064 }
1065
1066 ## -- Fragment
1067 if ($v =~ s/#(.*)\z//s) {
1068 my $w = $1;
1069 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}o) {
1070 last V;
1071 }
1072 }
1073
1074 ## -- Query
1075 if ($v =~ s/\?(.*)\z//s) {
1076 my $w = $1;
1077 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?$ucschar\x{E000}-\x{F8FF}\x{F0000}-\x{FFFFD}\x{100000}-\x{10FFFD}-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}o) {
1078 last V;
1079 }
1080 }
1081
1082 ## -- Authority
1083 if ($v =~ s!^//([^/]*)!!s) {
1084 my $w = $1;
1085 $w =~ s/^(?>[A-Za-z0-9._~!\$&'()*+,;=:$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\@//os;
1086 $w =~ s/:[0-9]*\z//;
1087 if ($w =~ /^\[(.*)\]\z/s) {
1088 my $x = $1;
1089 unless ($x =~ /\A[vV][0-9A-Fa-f]+\.[A-Za-z0-9._~!\$&'()*+,;=:-]+\z/) {
1090 ## IPv6address
1091 my $isv6;
1092
1093
1094 {
1095
1096 my
1097 $ipv4 = qr/(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)(?>\.(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)){3}/;
1098 my $h16 = qr/[0-9A-Fa-f]{1,4}/;
1099 if ($x =~ s/(?:$ipv4|$h16)\z//o) {
1100 if ($x =~ /\A(?>$h16:){6}\z/o or
1101 $x =~ /\A::(?>$h16:){0,5}\z/o or
1102 $x =~ /\A${h16}::(?>$h16:){4}\z/o or
1103 $x =~ /\A$h16(?::$h16)?::(?>$h16:){3}\z/o or
1104 $x =~ /\A$h16(?::$h16){0,2}::(?>$h16:){2}\z/o or
1105 $x =~ /\A$h16(?::$h16){0,3}::$h16:\z/o or
1106 $x =~ /\A$h16(?::$h16){0,4}::\z/o) {
1107 $isv6 =
1108 1
1109 ;
1110 }
1111 } elsif ($x =~ s/$h16\z//o) {
1112 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,5}\z/o) {
1113 $isv6 =
1114 1
1115 ;
1116 }
1117 } elsif ($x =~ s/::\z//o) {
1118 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,6}\z/o) {
1119 $isv6 =
1120 1
1121 ;
1122 }
1123 }
1124
1125
1126 }
1127
1128 ;
1129 last V unless $isv6;
1130 }
1131 } else {
1132 unless ($w =~ /\A(?>[A-Za-z0-9._~!\$&'()*+,;=$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z/o) {
1133 last V;
1134 }
1135 }
1136 }
1137
1138 ## -- Path
1139 unless ($v =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}os) {
1140 last V;
1141 }
1142
1143 $r =
1144 1
1145 ;
1146 } # V
1147
1148
1149 }
1150 $r;
1151 } # is_iri_3987
1152
1153 *is_relative_iri_reference = \&is_relative_iri_reference_3987;
1154
1155 sub is_relative_iri_reference_3987 ($) {
1156 my $self = $_[0];
1157 my $r = 0;
1158
1159 {
1160
1161 my
1162 $v = $$self;
1163 V: {
1164 ## LRM, RLM, LRE, RLE, LRO, RLO, PDF
1165 ## U+200E, U+200F, U+202A - U+202E
1166 my $ucschar = qq{\x{00A0}-\x{200D}\x{2010}-\x{2029}\x{202F}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}};
1167
1168 ## -- No scheme
1169 if ($v =~ s!^[^/?#]*:!!s) {
1170 last V;
1171 }
1172
1173 ## -- Fragment
1174 if ($v =~ s/#(.*)\z//s) {
1175 my $w = $1;
1176 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}o) {
1177 last V;
1178 }
1179 }
1180
1181 ## -- Query
1182 if ($v =~ s/\?(.*)\z//s) {
1183 my $w = $1;
1184 unless ($w =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/?$ucschar\x{E000}-\x{F8FF}\x{F0000}-\x{FFFFD}\x{100000}-\x{10FFFD}-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}o) {
1185 last V;
1186 }
1187 }
1188
1189 ## -- Authority
1190 if ($v =~ s!^//([^/]*)!!s) {
1191 my $w = $1;
1192 $w =~ s/^(?>[A-Za-z0-9._~!\$&'()*+,;=:$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\@//os;
1193 $w =~ s/:[0-9]*\z//;
1194 if ($w =~ /^\[(.*)\]\z/s) {
1195 my $x = $1;
1196 unless ($x =~ /\A[vV][0-9A-Fa-f]+\.[A-Za-z0-9._~!\$&'()*+,;=:-]+\z/) {
1197 ## IPv6address
1198 my $isv6;
1199
1200
1201 {
1202
1203 my
1204 $ipv4 = qr/(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)(?>\.(?>0|1[0-9]{0,2}|2(?>[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)){3}/;
1205 my $h16 = qr/[0-9A-Fa-f]{1,4}/;
1206 if ($x =~ s/(?:$ipv4|$h16)\z//o) {
1207 if ($x =~ /\A(?>$h16:){6}\z/o or
1208 $x =~ /\A::(?>$h16:){0,5}\z/o or
1209 $x =~ /\A${h16}::(?>$h16:){4}\z/o or
1210 $x =~ /\A$h16(?::$h16)?::(?>$h16:){3}\z/o or
1211 $x =~ /\A$h16(?::$h16){0,2}::(?>$h16:){2}\z/o or
1212 $x =~ /\A$h16(?::$h16){0,3}::$h16:\z/o or
1213 $x =~ /\A$h16(?::$h16){0,4}::\z/o) {
1214 $isv6 =
1215 1
1216 ;
1217 }
1218 } elsif ($x =~ s/$h16\z//o) {
1219 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,5}\z/o) {
1220 $isv6 =
1221 1
1222 ;
1223 }
1224 } elsif ($x =~ s/::\z//o) {
1225 if ($x eq '' or $x =~ /\A$h16(?>:$h16){0,6}\z/o) {
1226 $isv6 =
1227 1
1228 ;
1229 }
1230 }
1231
1232
1233 }
1234
1235 ;
1236 last V unless $isv6;
1237 }
1238 } else {
1239 unless ($w =~ /\A(?>[A-Za-z0-9._~!\$&'()*+,;=$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z/o) {
1240 last V;
1241 }
1242 }
1243 }
1244
1245 ## -- Path
1246 unless ($v =~ m{\A(?>[A-Za-z0-9._~!\$&'()*+,;=:\@/$ucschar-]|%[0-9A-Fa-f][0-9A-Fa-f])*\z}os) {
1247 last V;
1248 }
1249
1250 $r =
1251 1
1252 ;
1253 } # V
1254
1255
1256 }
1257 $r;
1258 } # is_relative_iri_reference_3987
1259
1260 *is_iri_reference = \&is_iri_reference_3987;
1261
1262 sub is_iri_reference_3987 ($) {
1263 my $self = $_[0];
1264 my $r = 0;
1265
1266 {
1267
1268
1269 {
1270
1271 local $Error::Depth = $Error::Depth + 1;
1272
1273 {
1274
1275
1276
1277 $r = $self->
1278 is_iri_3987
1279 ||
1280 $self->
1281 is_relative_iri_reference_3987
1282 ;
1283
1284
1285
1286 }
1287
1288
1289 ;}
1290
1291 ;
1292
1293
1294 }
1295 $r;
1296 } # is_iri_reference_3987
1297
1298 *is_absolute_iri = \&is_absolute_iri_3987;
1299
1300 sub is_absolute_iri_3987 ($) {
1301 my $self = $_[0];
1302 my $r = 0;
1303
1304 {
1305
1306
1307 {
1308
1309 local $Error::Depth = $Error::Depth + 1;
1310
1311 {
1312
1313
1314
1315 $r = $$self !~ /#/ && $self->
1316 is_iri_3987
1317 ;
1318
1319
1320
1321 }
1322
1323
1324 ;}
1325
1326 ;
1327
1328
1329 }
1330 $r;
1331 } # is_absolute_iri_3987
1332
1333 sub get_uri_reference ($) {
1334 my ($self) = @_;
1335 my $r;
1336
1337 {
1338
1339
1340 {
1341
1342 local $Error::Depth = $Error::Depth + 1;
1343
1344 {
1345
1346
1347
1348 $r = $self->
1349 get_uri_reference_3986
1350 ;
1351
1352
1353
1354 }
1355
1356
1357 ;}
1358
1359 ;
1360
1361
1362 }
1363 $r}
1364 sub get_uri_reference_3986 ($) {
1365 my ($self) = @_;
1366 my $r;
1367
1368 {
1369
1370
1371 {
1372
1373 local $Error::Depth = $Error::Depth + 1;
1374
1375 {
1376
1377
1378 require
1379 Encode;
1380 my $v = Encode::encode ('utf8', $$self);
1381 $v =~ s/([<>"{}|\\\^`\x00-\x20\x7E-\xFF])/sprintf '%%%02X', ord $1/ge;
1382 $r = bless \$v, 'Message::URI::URIReference';
1383 }
1384
1385
1386 ;}
1387
1388 ;
1389
1390
1391 }
1392 $r}
1393 sub get_iri_reference ($) {
1394 my ($self) = @_;
1395 my $r;
1396
1397 {
1398
1399
1400 {
1401
1402 local $Error::Depth = $Error::Depth + 1;
1403
1404 {
1405
1406
1407
1408 $r = $self->
1409 get_iri_reference_3987
1410 ;
1411
1412
1413
1414 }
1415
1416
1417 ;}
1418
1419 ;
1420
1421
1422 }
1423 $r}
1424 sub get_iri_reference_3987 ($) {
1425 my ($self) = @_;
1426 my $r;
1427
1428 {
1429
1430
1431 {
1432
1433 local $Error::Depth = $Error::Depth + 1;
1434
1435 {
1436
1437
1438 require
1439 Encode;
1440 my $v = Encode::encode ('utf8', $$self);
1441 $v =~ s{%([2-9A-Fa-f][0-9A-Fa-f])}
1442 {
1443 my $ch = hex $1;
1444 if ([
1445 # 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
1446 # 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF
1447
1448 1
1449 ,
1450 1
1451 ,
1452 1
1453 ,
1454 1
1455 ,
1456 1
1457 ,
1458 1
1459 ,
1460 1
1461 ,
1462 1
1463 , # 0x00
1464
1465 1
1466 ,
1467 1
1468 ,
1469 1
1470 ,
1471 1
1472 ,
1473 1
1474 ,
1475 1
1476 ,
1477 1
1478 ,
1479 1
1480 , # 0x08
1481
1482 1
1483 ,
1484 1
1485 ,
1486 1
1487 ,
1488 1
1489 ,
1490 1
1491 ,
1492 1
1493 ,
1494 1
1495 ,
1496 1
1497 , # 0x10
1498
1499 1
1500 ,
1501 1
1502 ,
1503 1
1504 ,
1505 1
1506 ,
1507 1
1508 ,
1509 1
1510 ,
1511 1
1512 ,
1513 1
1514 , # 0x18
1515
1516 1
1517 ,
1518 1
1519 ,
1520 1
1521 ,
1522 1
1523 ,
1524 1
1525 ,
1526 1
1527 ,
1528 1
1529 ,
1530 1
1531 , # 0x20
1532
1533 1
1534 ,
1535 1
1536 ,
1537 1
1538 ,
1539 1
1540 ,
1541 1
1542 ,
1543 0
1544 ,
1545 0
1546 ,
1547 1
1548 , # 0x28
1549
1550 0
1551 ,
1552 0
1553 ,
1554 0
1555 ,
1556 0
1557 ,
1558 0
1559 ,
1560 0
1561 ,
1562 0
1563 ,
1564 0
1565 , # 0x30
1566
1567 0
1568 ,
1569 0
1570 ,
1571 1
1572 ,
1573 1
1574 ,
1575 1
1576 ,
1577 1
1578 ,
1579 1
1580 ,
1581 1
1582 , # 0x38
1583
1584 1
1585 ,
1586 0
1587 ,
1588 0
1589 ,
1590 0
1591 ,
1592 0
1593 ,
1594 0
1595 ,
1596 0
1597 ,
1598 0
1599 , # 0x40
1600
1601 0
1602 ,
1603 0
1604 ,
1605 0
1606 ,
1607 0
1608 ,
1609 0
1610 ,
1611 0
1612 ,
1613 0
1614 ,
1615 0
1616 , # 0x48
1617
1618 0
1619 ,
1620 0
1621 ,
1622 0
1623 ,
1624 0
1625 ,
1626 0
1627 ,
1628 0
1629 ,
1630 0
1631 ,
1632 0
1633 , # 0x50
1634
1635 0
1636 ,
1637 0
1638 ,
1639 0
1640 ,
1641 1
1642 ,
1643 1
1644 ,
1645 1
1646 ,
1647 1
1648 ,
1649 0
1650 , # 0x58
1651
1652 1
1653 ,
1654 0
1655 ,
1656 0
1657 ,
1658 0
1659 ,
1660 0
1661 ,
1662 0
1663 ,
1664 0
1665 ,
1666 0
1667 , # 0x60
1668
1669 0
1670 ,
1671 0
1672 ,
1673 0
1674 ,
1675 0
1676 ,
1677 0
1678 ,
1679 0
1680 ,
1681 0
1682 ,
1683 0
1684 , # 0x68
1685
1686 0
1687 ,
1688 0
1689 ,
1690 0
1691 ,
1692 0
1693 ,
1694 0
1695 ,
1696 0
1697 ,
1698 0
1699 ,
1700 0
1701 , # 0x70
1702
1703 0
1704 ,
1705 0
1706 ,
1707 0
1708 ,
1709 1
1710 ,
1711 1
1712 ,
1713 1
1714 ,
1715 0
1716 ,
1717 1
1718 , # 0x78
1719 # 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
1720 # 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF
1721 ]->[$ch]) {
1722 # PERCENT SIGN, reserved, not-allowed in ASCII
1723 '%'.$1;
1724 } else {
1725 pack 'C', $ch;
1726 }
1727 }ge;
1728 $v =~ s{(
1729 [\xC2-\xDF][\x80-\xBF] | # UTF8-2
1730 [\xE0][\xA0-\xBF][\x80-\xBF] |
1731 [\xE1-\xEC][\x80-\xBF][\x80-\xBF] |
1732 [\xED][\x80-\x9F][\x80-\xBF] |
1733 [\xEE\xEF][\x80-\xBF][\x80-\xBF] | # UTF8-3
1734 [\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF] |
1735 [\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] |
1736 [\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF] | # UTF8-4
1737 [\x80-\xFF]
1738 )}{
1739 my $c = $1;
1740 if (length ($c) == 1) {
1741 $c =~ s/(.)/sprintf '%%%02X', ord $1/ge;
1742 $c;
1743 } else {
1744 my $ch = Encode::decode ('utf8', $c);
1745 if ($ch =~ /^[\x{00A0}-\x{200D}\x{2010}-\x{2029}\x{202F}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}]/) {
1746 $c;
1747 } else {
1748 $c =~ s/([\x80-\xFF])/sprintf '%%%02X', ord $1/ge;
1749 $c;
1750 }
1751 }
1752 }gex;
1753 $v =~ s/([<>"{}|\\\^`\x00-\x20\x7F])/sprintf '%%%02X', ord $1/ge;
1754 $v = Encode::decode ('utf8', $v);
1755 $r = bless \$v, 'Message::URI::URIReference';
1756 }
1757
1758
1759 ;}
1760
1761 ;
1762
1763
1764 }
1765 $r}
1766 sub get_absolute_reference ($$;%) {
1767 my ($self, $base, %opt) = @_;
1768 my $r;
1769
1770 {
1771
1772
1773 {
1774
1775 local $Error::Depth = $Error::Depth + 1;
1776
1777 {
1778
1779
1780
1781 $r = $self->
1782 get_absolute_reference_3986
1783
1784 ($base, non_strict => $opt{non_strict});
1785
1786
1787
1788 }
1789
1790
1791 ;}
1792
1793 ;
1794
1795
1796 }
1797 $r}
1798 sub get_absolute_reference_3986 ($$%) {
1799 my ($self, $base, %opt) = @_;
1800 my $r;
1801
1802 {
1803
1804
1805 {
1806
1807 local $Error::Depth = $Error::Depth + 1;
1808
1809 {
1810
1811
1812
1813 ## -- Decomposition
1814 my ($b_scheme, $b_auth, $b_path, $b_query, $b_frag);
1815 my ($r_scheme, $r_auth, $r_path, $r_query, $r_frag);
1816
1817 if ($$self =~ m!\A(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?\z!s) {
1818 ($r_scheme, $r_auth, $r_path, $r_query, $r_frag)
1819 = ($1, $2, $3, $4, $5);
1820 } else { # unlikely happen
1821 ($r_scheme, $r_auth, $r_path, $r_query, $r_frag)
1822 = (
1823 undef
1824 ,
1825 undef
1826 , '',
1827 undef
1828 ,
1829 undef
1830 );
1831 }
1832 my $ba = ref $base eq 'SCALAR'
1833 ? $base
1834 : ref $base eq 'Message::URI::URIReference'
1835 ? $base
1836 : ref $base
1837 ? \"$base"
1838 : \$base;
1839 if ($$ba =~ m!\A(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?\z!s) {
1840 ($b_scheme, $b_auth, $b_path, $b_query, $b_frag)
1841 = (defined $1 ? $1 : '', $2, $3, $4, $5);
1842 } else { # unlikely happen
1843 ($b_scheme, $b_auth, $b_path, $b_query, $b_frag)
1844 = ('',
1845 undef
1846 , '',
1847 undef
1848 ,
1849 undef
1850 );
1851 }
1852
1853 ## -- Merge
1854 my $path_merge = sub ($$) {
1855 my ($bpath, $rpath) = @_;
1856 if ($bpath eq '') {
1857 return '/'.$rpath;
1858 }
1859 $bpath =~ s/[^\/]*\z//;
1860 return $bpath . $rpath;
1861 }; # merge
1862
1863 ## -- Removing Dot Segments
1864 my $remove_dot_segments = sub ($) {
1865 local $_ = shift;
1866 my $buf = '';
1867 L: while (length $_) {
1868 next L if s/^\.\.?\///;
1869 next L if s/^\/\.(?:\/|\z)/\//;
1870 if (s/^\/\.\.(\/|\z)/\//) {
1871 $buf =~ s/\/?[^\/]*$//;
1872 next L;
1873 }
1874 last Z if s/^\.\.?\z//;
1875 s/^(\/?[^\/]*)//;
1876 $buf .= $1;
1877 }
1878 return $buf;
1879 }; # remove_dot_segments
1880
1881 ## -- Transformation
1882 my ($t_scheme, $t_auth, $t_path, $t_query, $t_frag);
1883
1884 if ($opt{non_strict} and $r_scheme eq $b_scheme) {
1885 undef $r_scheme;
1886 }
1887
1888 if (defined $r_scheme) {
1889 $t_scheme = $r_scheme;
1890 $t_auth = $r_auth;
1891 $t_path = $remove_dot_segments->($r_path);
1892 $t_query = $r_query;
1893 } else {
1894 if (defined $r_auth) {
1895 $t_auth = $r_auth;
1896 $t_path = $remove_dot_segments->($r_path);
1897 $t_query = $r_query;
1898 } else {
1899 if ($r_path =~ /\A\z/) {
1900 $t_path = $b_path;
1901 if (defined $r_query) {
1902 $t_query = $r_query;
1903 } else {
1904 $t_query = $b_query;
1905 }
1906 } elsif ($r_path =~ /^\//) {
1907 $t_path = $remove_dot_segments->($r_path);
1908 $t_query = $r_query;
1909 } else {
1910 $t_path = $path_merge->($b_path, $r_path);
1911 $t_path = $remove_dot_segments->($t_path);
1912 $t_query = $r_query;
1913 }
1914 $t_auth = $b_auth;
1915 }
1916 $t_scheme = $b_scheme;
1917 }
1918 $t_frag = $r_frag;
1919
1920 ## -- Recomposition
1921 my $result = '' ;
1922 $result .= $t_scheme . ':' if defined $t_scheme;
1923 $result .= '//' . $t_auth if defined $t_auth ;
1924 $result .= $t_path ;
1925 $result .= '?' . $t_query if defined $t_query ;
1926 $result .= '#' . $t_frag if defined $t_frag ;
1927
1928 $r = bless \$result, 'Message::URI::URIReference';
1929
1930 }
1931
1932
1933 ;}
1934
1935 ;
1936
1937
1938 }
1939 $r}
1940 sub get_absolute_reference_3987 ($$;%) {
1941 my ($self, $base, %opt) = @_;
1942 my $r;
1943
1944 {
1945
1946
1947 {
1948
1949 local $Error::Depth = $Error::Depth + 1;
1950
1951 {
1952
1953
1954
1955 $r = $self->
1956 get_absolute_reference_3986
1957
1958 ($base, non_strict => $opt{non_strict});
1959
1960
1961
1962 }
1963
1964
1965 ;}
1966
1967 ;
1968
1969
1970 }
1971 $r}
1972 sub is_same_document_reference ($$) {
1973 my ($self, $base) = @_;
1974 my $r = 0;
1975
1976 {
1977
1978
1979 {
1980
1981 local $Error::Depth = $Error::Depth + 1;
1982
1983 {
1984
1985
1986
1987 $r = $self->
1988 is_same_document_reference_3986
1989 ($base);
1990
1991
1992
1993 }
1994
1995
1996 ;}
1997
1998 ;
1999
2000
2001 }
2002 $r}
2003 sub is_same_document_reference_3986 ($$;%) {
2004 my ($self, $base, %opt) = @_;
2005 my $r = 0;
2006
2007 {
2008
2009
2010 {
2011
2012 local $Error::Depth = $Error::Depth + 1;
2013
2014 {
2015
2016
2017 if
2018 (substr ($$self, 0, 1) eq '#') {
2019 $r =
2020 1
2021 ;
2022 } else {
2023 my $target = $self->
2024 get_absolute_reference_3986
2025
2026 ($base, non_strict => $opt{non_strict})
2027 ->
2028 uri_reference
2029 ;
2030 $target =~ s/#.*\z//;
2031 my $ba = ref $base eq 'SCALAR'
2032 ? $$base
2033 : ref $base eq 'Message::URI::URIReference'
2034 ? $$base
2035 : ref $base
2036 ? "$base"
2037 : $base;
2038 $ba =~ s/#.*\z//;
2039 $r = ($target eq $ba);
2040 }
2041
2042
2043
2044 }
2045
2046
2047 ;}
2048
2049 ;
2050
2051
2052 }
2053 $r}
2054 sub get_relative_reference ($$) {
2055 my ($self, $base) = @_;
2056 my $r;
2057
2058 {
2059
2060
2061 {
2062
2063 local $Error::Depth = $Error::Depth + 1;
2064
2065 {
2066
2067
2068 my
2069 @base;
2070 my $ba = ref $base eq 'SCALAR'
2071 ? $base
2072 : ref $base eq 'Message::URI::URIReference'
2073 ? $base
2074 : ref $base
2075 ? \"$base"
2076 : \$base;
2077 if ($$ba =~ m!\A(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?\z!) {
2078 (@base) = (defined $1 ? $1 : '', $2, $3, $4, $5);
2079 } else { # unlikeley happen
2080 (@base) = ('',
2081 undef
2082 , '',
2083 undef
2084 ,
2085 undef
2086 );
2087 }
2088 my @t;
2089 my $t = $self->
2090 get_absolute_reference
2091 ($base);
2092 if ("$t" =~ m!\A(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?\z!) {
2093 (@t) = (defined $1 ? $1 : '', $2, $3, $4, $5);
2094 } else { # unlikeley happen
2095 (@t) = ('',
2096 undef
2097 , '',
2098 undef
2099 ,
2100 undef
2101 );
2102 }
2103
2104 my @ref;
2105 R: {
2106 ## Scheme
2107 if ($base[0] ne $t[0]) {
2108 (@ref) = @t;
2109 last R;
2110 }
2111
2112 ## Authority
2113 if (not defined $base[1] and not defined $t[1]) {
2114 (@ref) = @t;
2115 last R;
2116 } elsif (not defined $t[1]) {
2117 (@ref) = @t;
2118 last R;
2119 } elsif (not defined $base[1]) {
2120 (@ref) = @t;
2121 last R;
2122 } elsif ($base[1] ne $t[1]) {
2123 (@ref) = @t;
2124 last R;
2125 }
2126 ## NOTE: Avoid uncommon references.
2127
2128 if (defined $t[4] and # fragment
2129 $t[2] eq $base[2] and # path
2130 ((not defined $t[3] and not defined $base[3]) or # query
2131 (defined $t[3] and defined $base[3] and $t[3] eq $base[3]))) {
2132 (@ref) = (
2133 undef
2134 ,
2135 undef
2136 , '',
2137 undef
2138 , $t[4]);
2139 last R;
2140 }
2141
2142 ## Path
2143 my @tpath = split m!/!, $t[2], -1;
2144 my @bpath = split m!/!, $base[2], -1;
2145 if (@tpath < 1 or @bpath < 1) { ## No |/|
2146 (@ref) = @t;
2147 last R;
2148 }
2149 my $bpl;
2150
2151 ## Removes common segments
2152 while (@tpath and @bpath and $tpath[0] eq $bpath[0]) {
2153 shift @tpath;
2154 $bpl = shift @bpath;
2155 }
2156
2157 if (@tpath == 0) {
2158 if (@bpath == 0) { ## Avoid empty path for backward compatibility
2159 unshift @tpath, $bpl;
2160 } else {
2161 unshift @tpath, '..', $bpl;
2162 }
2163 } elsif (@bpath == 0) {
2164 unshift @tpath, $bpl;
2165 }
2166
2167 unshift @tpath, ('..') x (@bpath - 1) if @bpath > 1;
2168
2169 unshift @tpath, '.' if $tpath[0] eq '' or
2170 $tpath[0] =~ /:/;
2171
2172 (@ref) = (
2173 undef
2174 ,
2175 undef
2176 , (join '/', @tpath), $t[3], $t[4]);
2177 } # R
2178
2179 ## -- Recomposition
2180 my $result = '' ;
2181 $result .= $ref[0] . ':' if defined $ref[0]; # scheme;
2182 $result .= '//' . $ref[1] if defined $ref[1]; # authority
2183 $result .= $ref[2] ; # path
2184 $result .= '?' . $ref[3] if defined $ref[3]; # query
2185 $result .= '#' . $ref[4] if defined $ref[4]; # fragment
2186
2187 $r = bless \$result, 'Message::URI::URIReference';
2188
2189
2190
2191 }
2192
2193
2194 ;}
2195
2196 ;
2197
2198
2199 }
2200 $r}
2201
2202 sub ___report_error ($$) {
2203 $_[1]->throw;
2204 } # ___report_error
2205
2206 sub clone ($) {
2207 my $self = shift;
2208 my $v = $$self;
2209 return bless \$v, ref $self;
2210 } # clone
2211
2212 *clone_uri_reference = \&clone;
2213
2214 use overload
2215 bool => sub () {1},
2216 '""' => 'stringify',
2217 'eq' => sub ($$) {
2218 my ($self, $v) = @_;
2219 my $r = 0;
2220
2221 {
2222
2223 if
2224 (defined $v) {
2225
2226
2227 {
2228
2229 local $Error::Depth = $Error::Depth + 1;
2230
2231 {
2232
2233
2234
2235 $r = $v eq $$self;
2236
2237
2238
2239 }
2240
2241
2242 ;}
2243
2244 ;
2245 }
2246
2247
2248 }
2249 $r}
2250 ,
2251 fallback => 1;
2252
2253 # Portions of the Perl implementation contained in the module
2254 # are derived from the example parser (April 7, 2004) available at
2255 # <URI::http://www.gbiv.com/protocols/uri/rev-2002/uri_test.pl>
2256 # that is placed in the Public Domain by Roy T. Fielding
2257 # and Day Software, Inc.
2258
2259 1;
2260 ## License: <http://suika.fam.cx/~wakaba/archive/2004/8/18/license#Perl+MPL>
2261 ## $Date: 2007/08/11 13:06:39 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24