-package URI; # $Date: 2003/08/02 23:39:31 $\r
-\r
-use strict;\r
-use vars qw($VERSION);\r
-$VERSION = "1.09";\r
-\r
-use vars qw($ABS_REMOTE_LEADING_DOTS $ABS_ALLOW_RELATIVE_SCHEME);\r
-\r
-my %implements; # mapping from scheme to implementor class\r
-\r
-# Some "official" character classes\r
-\r
-use vars qw($reserved $mark $unreserved $uric $scheme_re);\r
-$reserved = q(;/?:@&=+$,);\r
-$mark = q(-_.!~*'()); #'; emacs\r
-$unreserved = "A-Za-z0-9\Q$mark\E";\r
-$uric = quotemeta($reserved) . $unreserved . "%";\r
-\r
-$scheme_re = '[a-zA-Z][a-zA-Z0-9.+\-]*';\r
-\r
-use Carp ();\r
-use URI::Escape ();\r
-\r
-use overload ('""' => sub { ${$_[0]} },\r
- '==' => sub { overload::StrVal($_[0]) eq\r
- overload::StrVal($_[1])\r
- },\r
- fallback => 1,\r
- );\r
-\r
-sub new\r
-{\r
- my($class, $uri, $scheme) = @_;\r
-\r
- $uri = defined ($uri) ? "$uri" : ""; # stringify\r
- # Get rid of potential wrapping\r
- $uri =~ s/^<(?:URL:)?(.*)>$/$1/; # \r
- $uri =~ s/^"(.*)"$/$1/;\r
- $uri =~ s/^\s+//;\r
- $uri =~ s/\s+$//;\r
-\r
- my $impclass;\r
- if ($uri =~ m/^($scheme_re):/so) {\r
- $scheme = $1;\r
- } else {\r
- if (($impclass = ref($scheme))) {\r
- $scheme = $scheme->scheme;\r
- } elsif ($scheme && $scheme =~ m/^($scheme_re)(?::|$)/o) {\r
- $scheme = $1;\r
- }\r
- }\r
- $impclass ||= implementor($scheme) ||\r
- do {\r
- require URI::_foreign;\r
- $impclass = 'URI::_foreign';\r
- };\r
-\r
- return $impclass->_init($uri, $scheme);\r
-}\r
-\r
-\r
-sub new_abs\r
-{\r
- my($class, $uri, $base) = @_;\r
- $uri = $class->new($uri, $base);\r
- $uri->abs($base);\r
-}\r
-\r
-\r
-sub _init\r
-{\r
- my $class = shift;\r
- my($str, $scheme) = @_;\r
- $str =~ s/([^$uric\#])/$URI::Escape::escapes{$1}/go;\r
- $str = "$scheme:$str" unless $str =~ /^$scheme_re:/o ||\r
- $class->_no_scheme_ok;\r
- my $self = bless \$str, $class;\r
- $self;\r
-}\r
-\r
-\r
-sub implementor\r
-{\r
- my($scheme, $impclass) = @_;\r
- unless ($scheme) {\r
- require URI::_generic;\r
- return "URI::_generic";\r
- }\r
-\r
- $scheme = lc($scheme);\r
-\r
- if ($impclass) {\r
- # Set the implementor class for a given scheme\r
- my $old = $implements{$scheme};\r
- $impclass->_init_implementor($scheme);\r
- $implements{$scheme} = $impclass;\r
- return $old;\r
- }\r
-\r
- my $ic = $implements{$scheme};\r
- return $ic if $ic;\r
-\r
- # scheme not yet known, look for internal or\r
- # preloaded (with 'use') implementation\r
- $ic = "URI::$scheme"; # default location\r
-\r
- # turn scheme into a valid perl identifier by a simple tranformation...\r
- $ic =~ s/\+/_P/g;\r
- $ic =~ s/\./_O/g;\r
- $ic =~ s/\-/_/g;\r
-\r
- no strict 'refs';\r
- # check we actually have one for the scheme:\r
- unless (@{"${ic}::ISA"}) {\r
- # Try to load it\r
- eval "require $ic";\r
- die $@ if $@ && $@ !~ /Can\'t locate.*in \@INC/;\r
- return unless @{"${ic}::ISA"};\r
- }\r
-\r
- $ic->_init_implementor($scheme);\r
- $implements{$scheme} = $ic;\r
- $ic;\r
-}\r
-\r
-\r
-sub _init_implementor\r
-{\r
- my($class, $scheme) = @_;\r
- # Remember that one implementor class may actually\r
- # serve to implement several URI schemes.\r
-}\r
-\r
-\r
-sub clone\r
-{\r
- my $self = shift;\r
- my $other = $$self;\r
- bless \$other, ref $self;\r
-}\r
-\r
-\r
-sub _no_scheme_ok { 0 }\r
-\r
-sub _scheme\r
-{\r
- my $self = shift;\r
-\r
- unless (@_) {\r
- return unless $$self =~ /^($scheme_re):/o;\r
- return $1;\r
- }\r
-\r
- my $old;\r
- my $new = shift;\r
- if (defined($new) && length($new)) {\r
- Carp::croak("Bad scheme '$new'") unless $new =~ /^$scheme_re$/o;\r
- $old = $1 if $$self =~ s/^($scheme_re)://o;\r
- my $newself = URI->new("$new:$$self");\r
- $$self = $$newself; \r
- bless $self, ref($newself);\r
- } else {\r
- if ($self->_no_scheme_ok) {\r
- $old = $1 if $$self =~ s/^($scheme_re)://o;\r
- Carp::carp("Oops, opaque part now look like scheme")\r
- if $^W && $$self =~ m/^$scheme_re:/o\r
- } else {\r
- $old = $1 if $$self =~ m/^($scheme_re):/o;\r
- }\r
- }\r
-\r
- return $old;\r
-}\r
-\r
-sub scheme\r
-{\r
- my $scheme = shift->_scheme(@_);\r
- return unless defined $scheme;\r
- lc($scheme);\r
-}\r
-\r
-\r
-sub opaque\r
-{\r
- my $self = shift;\r
-\r
- unless (@_) {\r
- $$self =~ /^(?:$scheme_re:)?([^\#]*)/o or die;\r
- return $1;\r
- }\r
-\r
- $$self =~ /^($scheme_re:)? # optional scheme\r
- ([^\#]*) # opaque\r
- (\#.*)? # optional fragment\r
- $/sx or die;\r
-\r
- my $old_scheme = $1;\r
- my $old_opaque = $2;\r
- my $old_frag = $3;\r
-\r
- my $new_opaque = shift;\r
- $new_opaque = "" unless defined $new_opaque;\r
- $new_opaque =~ s/([^$uric])/$URI::Escape::escapes{$1}/go;\r
-\r
- $$self = defined($old_scheme) ? $old_scheme : "";\r
- $$self .= $new_opaque;\r
- $$self .= $old_frag if defined $old_frag;\r
-\r
- $old_opaque;\r
-}\r
-\r
-*path = \&opaque; # alias\r
-\r
-\r
-sub fragment\r
-{\r
- my $self = shift;\r
- unless (@_) {\r
- return unless $$self =~ /\#(.*)/s;\r
- return $1;\r
- }\r
-\r
- my $old;\r
- $old = $1 if $$self =~ s/\#(.*)//s;\r
-\r
- my $new_frag = shift;\r
- if (defined $new_frag) {\r
- $new_frag =~ s/([^$uric])/$URI::Escape::escapes{$1}/go;\r
- $$self .= "#$new_frag";\r
- }\r
- $old;\r
-}\r
-\r
-\r
-sub as_string\r
-{\r
- my $self = shift;\r
- $$self;\r
-}\r
-\r
-\r
-sub canonical\r
-{\r
- my $self = shift;\r
-\r
- # Make sure scheme is lowercased\r
- my $scheme = $self->_scheme || "";\r
- my $uc_scheme = $scheme =~ /[A-Z]/;\r
- my $lc_esc = $$self =~ /%(?:[a-f][a-fA-F0-9]|[A-F0-9][a-f])/;\r
- if ($uc_scheme || $lc_esc) {\r
- my $other = $self->clone;\r
- $other->_scheme(lc $scheme) if $uc_scheme;\r
- $$other =~ s/(%(?:[a-f][a-fA-F0-9]|[A-F0-9][a-f]))/uc($1)/ge\r
- if $lc_esc;\r
- return $other;\r
- }\r
- $self;\r
-}\r
-\r
-# Compare two URIs, subclasses will provide a more correct implementation\r
-sub eq {\r
- my($self, $other) = @_;\r
- $self = URI->new($self, $other) unless ref $self;\r
- $other = URI->new($other, $self) unless ref $other;\r
- ref($self) eq ref($other) && # same class\r
- $self->canonical->as_string eq $other->canonical->as_string;\r
-}\r
-\r
-# generic-URI transformation methods\r
-sub abs { $_[0]; }\r
-sub rel { $_[0]; }\r
-\r
-1;\r
-\r
-__END__\r
-\r
-=head1 NAME\r
-\r
-URI - Uniform Resource Identifiers (absolute and relative)\r
-\r
-=head1 SYNOPSIS\r
-\r
- $u1 = URI->new("http://www.perl.com");\r
- $u2 = URI->new("foo", "http");\r
- $u3 = $u2->abs($u1);\r
- $u4 = $u3->clone;\r
- $u5 = URI->new("HTTP://WWW.perl.com:80")->canonical;\r
-\r
- $str = $u->as_string;\r
- $str = "$u";\r
-\r
- $scheme = $u->scheme;\r
- $opaque = $u->opaque;\r
- $path = $u->path;\r
- $frag = $u->fragment;\r
-\r
- $u->scheme("ftp");\r
- $u->host("ftp.perl.com");\r
- $u->path("cpan/");\r
-\r
-=head1 DESCRIPTION\r
-\r
-This module implements the C<URI> class. Objects of this class\r
-represent "Uniform Resource Identifier references" as specified in RFC\r
-2396.\r
-\r
-A Uniform Resource Identifier is a compact string of characters for\r
-identifying an abstract or physical resource. A Uniform Resource\r
-Identifier can be further classified either a Uniform Resource Locator\r
-(URL) or a Uniform Resource Name (URN). The distinction between URL\r
-and URN does not matter to the C<URI> class interface. A\r
-"URI-reference" is a URI that may have additional information attached\r
-in the form of a fragment identifier.\r
-\r
-An absolute URI reference consists of three parts. A I<scheme>, a\r
-I<scheme specific part> and a I<fragment> identifier. A subset of URI\r
-references share a common syntax for hierarchical namespaces. For\r
-these the scheme specific part is further broken down into\r
-I<authority>, I<path> and I<query> components. These URI can also\r
-take the form of relative URI references, where the scheme (and\r
-usually also the authority) component is missing, but implied by the\r
-context of the URI reference. The three forms of URI reference\r
-syntax are summarized as follows:\r
-\r
- <scheme>:<scheme-specific-part>#<fragment>\r
- <scheme>://<authority><path>?<query>#<fragment>\r
- <path>?<query>#<fragment>\r
-\r
-The components that a URI reference can be divided into depend on the\r
-I<scheme>. The C<URI> class provides methods to get and set the\r
-individual components. The methods available for a specific\r
-C<URI> object depend on the scheme.\r
-\r
-=head1 CONSTRUCTORS\r
-\r
-The following methods construct new C<URI> objects:\r
-\r
-=over 4\r
-\r
-=item $uri = URI->new( $str, [$scheme] )\r
-\r
-This class method constructs a new URI object. The string\r
-representation of a URI is given as argument together with an optional\r
-scheme specification. Common URI wrappers like "" and <>, as well as\r
-leading and trailing white space, are automatically removed from\r
-the $str argument before it is processed further.\r
-\r
-The constructor determines the scheme, maps this to an appropriate\r
-URI subclass, constructs a new object of that class and returns it.\r
-\r
-The $scheme argument is only used when $str is a\r
-relative URI. It can either be a simple string that\r
-denotes the scheme, a string containing an absolute URI reference or\r
-an absolute C<URI> object. If no $scheme is specified for a relative\r
-URI $str, then $str is simply treated as a generic URI (no scheme\r
-specific methods available).\r
-\r
-The set of characters available for building URI references is\r
-restricted (see L<URI::Escape>). Characters outside this set are\r
-automatically escaped by the URI constructor.\r
-\r
-=item $uri = URI->new_abs( $str, $base_uri )\r
-\r
-This constructs a new absolute URI object. The $str argument can\r
-denote a relative or absolute URI. If relative, then it will be\r
-absolutized using $base_uri as base. The $base_uri must be an absolute\r
-URI.\r
-\r
-=item $uri = URI::file->new( $filename, [$os] )\r
-\r
-This constructs a new I<file> URI from a file name. See L<URI::file>.\r
-\r
-=item $uri = URI::file->new_abs( $filename, [$os] )\r
-\r
-This constructs a new absolute I<file> URI from a file name. See\r
-L<URI::file>.\r
-\r
-=item $uri = URI::file->cwd\r
-\r
-This returns the current working directory as a I<file> URI. See\r
-L<URI::file>.\r
-\r
-=item $uri->clone\r
-\r
-This method returns a copy of the $uri.\r
-\r
-=back\r
-\r
-=head1 COMMON METHODS\r
-\r
-The methods described in this section are available for all C<URI>\r
-objects.\r
-\r
-Methods that give access to components of a URI will always return the\r
-old value of the component. The value returned will be C<undef> if the\r
-component was not present. There is generally a difference between a\r
-component that is empty (represented as C<"">) and a component that is\r
-missing (represented as C<undef>). If an accessor method is given an\r
-argument it will update the corresponding component in addition to\r
-returning the old value of the component. Passing an undefined\r
-argument will remove the component (if possible). The description of\r
-the various accessor methods will tell if the component is passed as\r
-an escaped or an unescaped string. Components that can be futher\r
-divided into sub-parts are usually passed escaped, as unescaping might\r
-change its semantics.\r
-\r
-The common methods available for all URI are:\r
-\r
-=over 4\r
-\r
-=item $uri->scheme( [$new_scheme] )\r
-\r
-This method sets and returns the scheme part of the $uri. If the $uri is\r
-relative, then $uri->scheme returns C<undef>. If called with an\r
-argument, it will update the scheme of $uri, possibly changing the\r
-class of $uri, and return the old scheme value. The method croaks\r
-if the new scheme name is illegal; scheme names must begin with a\r
-letter and must consist of only US-ASCII letters, numbers, and a few\r
-special marks: ".", "+", "-". This restriction effectively means\r
-that scheme have to be passed unescaped. Passing an undefined\r
-argument to the scheme method will make the URI relative (if possible).\r
-\r
-Letter case does not matter for scheme names. The string\r
-returned by $uri->scheme is always lowercase. If you want the scheme\r
-just as it was written in the URI in its original case,\r
-you can use the $uri->_scheme method instead.\r
-\r
-=item $uri->opaque( [$new_opaque] )\r
-\r
-This method sets and returns the scheme specific part of the $uri \r
-(everything between the scheme and the fragment)\r
-as an escaped string.\r
-\r
-=item $uri->path( [$new_path] )\r
-\r
-This method sets and returns the same value as $uri->opaque unless the URI\r
-supports the generic syntax for hierarchical namespaces.\r
-In that case the generic method is overridden to set and return\r
-the part of the URI between the I<host name> and the I<fragment>.\r
-\r
-=item $uri->fragment( [$new_frag] )\r
-\r
-This method returns the fragment identifier of a URI reference\r
-as an escaped string.\r
-\r
-=item $uri->as_string\r
-\r
-This method returns a URI object to a plain string. URI objects are\r
-also converted to plain strings automatically by overloading. This\r
-means that $uri objects can be used as plain strings in most Perl\r
-constructs.\r
-\r
-=item $uri->canonical\r
-\r
-This method will return a normalized version of the URI. The rules\r
-for normalization are scheme dependent. It usually involves\r
-lowercasing of the scheme and the Internet host name components,\r
-removing the explicit port specification if it matches the default port,\r
-uppercasing all escape sequences, and unescaping octets that can be\r
-better represented as plain characters.\r
-\r
-For efficiency reasons, if the $uri already was in normalized form,\r
-then a reference to it is returned instead of a copy.\r
-\r
-=item $uri->eq( $other_uri )\r
-\r
-=item URI::eq( $first_uri, $other_uri )\r
-\r
-This method tests whether two URI references are equal. URI references\r
-that normalize to the same string are considered equal. The method\r
-can also be used as a plain function which can also test two string\r
-arguments.\r
-\r
-If you need to test whether two C<URI> object references denote the\r
-same object, use the '==' operator.\r
-\r
-=item $uri->abs( $base_uri )\r
-\r
-This method returns an absolute URI reference. If $uri already is\r
-absolute, then a reference to it is simply returned. If the $uri\r
-is relative, then a new absolute URI is constructed by combining the\r
-$uri and the $base_uri, and returned.\r
-\r
-=item $uri->rel( $base_uri )\r
-\r
-This method returns a relative URI reference if it is possible to\r
-make one that denotes the same resource relative to $base_uri.\r
-If not, then $uri is simply returned.\r
-\r
-=back\r
-\r
-=head1 GENERIC METHODS\r
-\r
-The following methods are available to schemes that use the\r
-common/generic syntax for hierarchical namespaces. The description of\r
-schemes below will tell which one these are. Unknown schemes are\r
-assumed to support the generic syntax, and therefore the following\r
-methods:\r
-\r
-=over 4\r
-\r
-=item $uri->authority( [$new_authority] )\r
-\r
-This method sets and returns the escaped authority component\r
-of the $uri.\r
-\r
-=item $uri->path( [$new_path] )\r
-\r
-This method sets and returns the escaped path component of\r
-the $uri (the part between the host name and the query or fragment).\r
-The path will never be undefined, but it can be the empty string.\r
-\r
-=item $uri->path_query( [$new_path_query] )\r
-\r
-This method sets and returns the escaped path and query\r
-components as a single entity. The path and the query are\r
-separated by a "?" character, but the query can itself contain "?".\r
-\r
-=item $uri->path_segments( [$segment,...] )\r
-\r
-This method sets and returns the path. In scalar context it returns\r
-the same value as $uri->path. In list context it will return the\r
-unescaped path segments that make up the path. Path segments that\r
-have parameters are returned as an anonymous array. The first element\r
-is the unescaped path segment proper. Subsequent elements are escaped\r
-parameter strings. Such an anonymous array uses overloading so it can\r
-be treated as a string too, but this string does not include the\r
-parameters.\r
-\r
-=item $uri->query( [$new_query] )\r
-\r
-This method sets and returns the escaped query component of\r
-the $uri.\r
-\r
-=item $uri->query_form( [$key => $value,...] )\r
-\r
-This method sets and returns query components that use the\r
-I<application/x-www-form-urlencoded> format. Key/value pairs are\r
-separated by "&" and the key is separated from the value with a "="\r
-character.\r
-\r
-=item $uri->query_keywords( [$keywords,...] )\r
-\r
-This method sets and returns query components that use the\r
-keywords separated by "+" format.\r
-\r
-=back\r
-\r
-=head1 SERVER METHODS\r
-\r
-Schemes where the I<authority> component denotes a Internet host will\r
-have the following methods available in addition to the generic\r
-methods.\r
-\r
-=over 4\r
-\r
-=item $uri->userinfo( [$new_userinfo] )\r
-\r
-This method sets and returns the escaped userinfo part of the\r
-authority componenent.\r
-\r
-For some schemes this will be a user name and a password separated by\r
-a colon. This practice is not recommended. Embedding passwords in\r
-clear text (such as URI) has proven to be a security risk in almost\r
-every case where it has been used.\r
-\r
-=item $uri->host( [$new_host] )\r
-\r
-This method sets and returns the unescaped hostname.\r
-\r
-If the $new_host string ends with a colon and a number, then this\r
-number will also set the port.\r
-\r
-=item $uri->port( [ $new_port] )\r
-\r
-This method sets and returns the port. The port is simple integer\r
-that should be greater than 0.\r
-\r
-If no explicit port is specified in the URI, then the default port of\r
-the URI scheme is returned. If you don't want the default port\r
-substituted, then you can use the $uri->_port method instead.\r
-\r
-=item $uri->host_port( [ $new_host_port ] )\r
-\r
-This method sets and returns the host and port as a single\r
-unit. The returned value will include a port, even if it matches the\r
-default port. The host part and the port part is separated with a\r
-colon; ":".\r
-\r
-=item $uri->default_port\r
-\r
-This method returns the default port of the URI scheme that $uri\r
-belongs to. For I<http> this will be the number 80, for I<ftp> this\r
-will be the number 21, etc. The default port for a scheme can not be\r
-changed.\r
-\r
-=back\r
-\r
-=head1 SCHEME SPECIFIC SUPPORT\r
-\r
-The following URI schemes are specifically supported. For C<URI>\r
-objects not belonging to one of these you can only use the common and\r
-generic methods.\r
-\r
-=over 4\r
-\r
-=item B<data>:\r
-\r
-The I<data> URI scheme is specified in RFC 2397. It allows inclusion\r
-of small data items as "immediate" data, as if it had been included\r
-externally.\r
-\r
-C<URI> objects belonging to the data scheme support the common methods\r
-and two new methods to access their scheme specific components;\r
-$uri->media_type and $uri->data. See L<URI::data> for details.\r
-\r
-=item B<file>:\r
-\r
-An old specification of the I<file> URI scheme is found in RFC 1738.\r
-A new RFC 2396 based specification in not available yet, but file URI\r
-references are in common use.\r
-\r
-C<URI> objects belonging to the file scheme support the common and\r
-generic methods. In addition they provide two methods to map file URI\r
-back to local file names; $uri->file and $uri->dir. See L<URI::file>\r
-for details.\r
-\r
-=item B<ftp>:\r
-\r
-An old specification of the I<ftp> URI scheme is found in RFC 1738. A\r
-new RFC 2396 based specification in not available yet, but ftp URI\r
-references are in common use.\r
-\r
-C<URI> objects belonging to the ftp scheme support the common,\r
-generic and server methods. In addition they provide two methods to\r
-access the userinfo sub-components: $uri->user and $uri->password.\r
-\r
-=item B<gopher>:\r
-\r
-The I<gopher> URI scheme is specified in\r
-<draft-murali-url-gopher-1996-12-04> and will hopefully be available\r
-as a RFC 2396 based specification.\r
-\r
-C<URI> objects belonging to the gopher scheme support the common,\r
-generic and server methods. In addition they support some methods to\r
-access gopher specific path components: $uri->gopher_type,\r
-$uri->selector, $uri->search, $uri->string.\r
-\r
-=item B<http>:\r
-\r
-The I<http> URI scheme is specified in\r
-<draft-ietf-http-v11-spec-rev-06> (which will become an RFC soon).\r
-The scheme is used to reference resources hosted by HTTP servers.\r
-\r
-C<URI> objects belonging to the http scheme support the common,\r
-generic and server methods.\r
-\r
-=item B<https>:\r
-\r
-The I<https> URI scheme is a Netscape invention which is commonly\r
-implemented. The scheme is used to reference HTTP servers through SSL\r
-connections. It's syntax is the same as http, but the default\r
-port is different.\r
-\r
-=item B<ldap>:\r
-\r
-The I<ldap> URI scheme is specified in RFC 2255. LDAP is the\r
-Lightweight Directory Access Protocol. A ldap URI describes an LDAP\r
-search operation to perform to retrieve information from an LDAP\r
-directory.\r
-\r
-C<URI> objects belonging to the ldap scheme support the common,\r
-generic and server methods as well as specific ldap methods; $uri->dn,\r
-$uri->attributes, $uri->scope, $uri->filter, $uri->extensions. See\r
-L<URI::ldap> for details.\r
-\r
-=item B<mailto>:\r
-\r
-The I<mailto> URI scheme is specified in RFC 2368. The scheme was\r
-originally used to designate the Internet mailing address of an\r
-individual or service. It has (in RFC 2368) been extended to allow\r
-setting of other mail header fields and the message body.\r
-\r
-C<URI> objects belonging to the mailto scheme support the common\r
-methods and the generic query methods. In addition they support the\r
-following mailto specific methods: $uri->to, $uri->headers.\r
-\r
-=item B<news>:\r
-\r
-The I<news>, I<nntp> and I<snews> URI schemes are specified in\r
-<draft-gilman-news-url-01> and will hopefully be available as a RFC\r
-2396 based specification soon.\r
-\r
-C<URI> objects belonging to the news scheme support the common,\r
-generic and server methods. In addition they provide some methods to\r
-access the path: $uri->group and $uri->message.\r
-\r
-=item B<nntp>:\r
-\r
-See I<news> scheme.\r
-\r
-=item B<pop>:\r
-\r
-The I<pop> URI scheme is specified in RFC 2384. The scheme is used to\r
-reference a POP3 mailbox.\r
-\r
-C<URI> objects belonging to the pop scheme support the common, generic\r
-and server methods. In addition they provide two methods to access the\r
-userinfo components: $uri->user and $uri->auth\r
-\r
-=item B<rlogin>:\r
-\r
-An old speficication of the I<rlogin> URI scheme is found in RFC\r
-1738. C<URI> objects belonging to the rlogin scheme support the\r
-common, generic and server methods.\r
-\r
-=item B<rsync>:\r
-\r
-Information about rsync is available from http://rsync.samba.org.\r
-C<URI> objects belonging to the rsync scheme support the common,\r
-generic and server methods. In addition they provide methods to\r
-access the userinfo sub-components: $uri->user and $uri->password.\r
-\r
-=item B<snews>:\r
-\r
-See I<news> scheme. It's syntax is the same as news, but the default\r
-port is different.\r
-\r
-=item B<telnet>:\r
-\r
-An old speficication of the I<telnet> URI scheme is found in RFC\r
-1738. C<URI> objects belonging to the telnet scheme support the\r
-common, generic and server methods.\r
-\r
-=back\r
-\r
-\r
-=head1 CONFIGURATION VARIABLES\r
-\r
-The following configuration variables influence how the class and it's\r
-methods behave:\r
-\r
-=over 4\r
-\r
-=item $URI::ABS_ALLOW_RELATIVE_SCHEME\r
-\r
-Some older parsers used to allow the scheme name to be present in the\r
-relative URL if it was the same as the base URL scheme. RFC 2396 says\r
-that this should be avoided, but you can enable this old behaviour by\r
-setting the $URI::ABS_ALLOW_RELATIVE_SCHEME variable to a TRUE value.\r
-The difference is demonstrated by the following examples:\r
-\r
- URI->new("http:foo")->abs("http://host/a/b")\r
- ==> "http:foo"\r
-\r
- local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1;\r
- URI->new("http:foo")->abs("http://host/a/b")\r
- ==> "http:/host/a/foo"\r
-\r
-\r
-=item $URI::ABS_REMOTE_LEADING_DOTS\r
-\r
-You can also have the abs() method ignore excess ".."\r
-segments in the relative URI by setting $URI::ABS_REMOTE_LEADING_DOTS\r
-to a TRUE value. The difference is demonstrated by the following\r
-examples:\r
-\r
- URI->new("../../../foo")->abs("http://host/a/b")\r
- ==> "http://host/../../foo"\r
-\r
- local $URI::URL::ABS_REMOTE_LEADING_DOTS = 1;\r
- URI->new("../../../foo")->abs("http://host/a/b")\r
- ==> "http://host/foo"\r
-\r
-=back\r
-\r
-\r
-\r
-=head1 SEE ALSO\r
-\r
-L<URI::file>, L<URI::WithBase>, L<URI::Escape>, L<URI::Heuristic>\r
-\r
-RFC 2396: "Uniform Resource Identifiers (URI): Generic Syntax",\r
-Berners-Lee, Fielding, Masinter, August 1998.\r
-\r
-=head1 COPYRIGHT\r
-\r
-Copyright 1995-2000 Gisle Aas.\r
-\r
-Copyright 1995 Martijn Koster.\r
-\r
-This program is free software; you can redistribute it and/or modify\r
-it under the same terms as Perl itself.\r
-\r
-=head1 AUTHORS / ACKNOWLEDGMENTS\r
-\r
-This module is based on the C<URI::URL> module, which in turn was\r
-(distantly) based on the C<wwwurl.pl> code in the libwww-perl for\r
-perl4 developed by Roy Fielding, as part of the Arcadia project at the\r
-University of California, Irvine, with contributions from Brooks\r
-Cutter.\r
-\r
-C<URI::URL> was developed by Gisle Aas, Tim Bunce, Roy Fielding and\r
-Martijn Koster with input from other people on the libwww-perl mailing\r
-list.\r
-\r
-C<URI> and related subclasses was developed by Gisle Aas.\r
-\r
-=cut\r
+package URI; # $Date: 2003/08/02 23:39:31 $
+
+use strict;
+use vars qw($VERSION);
+$VERSION = "1.09";
+
+use vars qw($ABS_REMOTE_LEADING_DOTS $ABS_ALLOW_RELATIVE_SCHEME);
+
+my %implements; # mapping from scheme to implementor class
+
+# Some "official" character classes
+
+use vars qw($reserved $mark $unreserved $uric $scheme_re);
+$reserved = q(;/?:@&=+$,);
+$mark = q(-_.!~*'()); #'; emacs
+$unreserved = "A-Za-z0-9\Q$mark\E";
+$uric = quotemeta($reserved) . $unreserved . "%";
+
+$scheme_re = '[a-zA-Z][a-zA-Z0-9.+\-]*';
+
+use Carp ();
+use URI::Escape ();
+
+use overload ('""' => sub { ${$_[0]} },
+ '==' => sub { overload::StrVal($_[0]) eq
+ overload::StrVal($_[1])
+ },
+ fallback => 1,
+ );
+
+sub new
+{
+ my($class, $uri, $scheme) = @_;
+
+ $uri = defined ($uri) ? "$uri" : ""; # stringify
+ # Get rid of potential wrapping
+ $uri =~ s/^<(?:URL:)?(.*)>$/$1/; #
+ $uri =~ s/^"(.*)"$/$1/;
+ $uri =~ s/^\s+//;
+ $uri =~ s/\s+$//;
+
+ my $impclass;
+ if ($uri =~ m/^($scheme_re):/so) {
+ $scheme = $1;
+ } else {
+ if (($impclass = ref($scheme))) {
+ $scheme = $scheme->scheme;
+ } elsif ($scheme && $scheme =~ m/^($scheme_re)(?::|$)/o) {
+ $scheme = $1;
+ }
+ }
+ $impclass ||= implementor($scheme) ||
+ do {
+ require URI::_foreign;
+ $impclass = 'URI::_foreign';
+ };
+
+ return $impclass->_init($uri, $scheme);
+}
+
+
+sub new_abs
+{
+ my($class, $uri, $base) = @_;
+ $uri = $class->new($uri, $base);
+ $uri->abs($base);
+}
+
+
+sub _init
+{
+ my $class = shift;
+ my($str, $scheme) = @_;
+ $str =~ s/([^$uric\#])/$URI::Escape::escapes{$1}/go;
+ $str = "$scheme:$str" unless $str =~ /^$scheme_re:/o ||
+ $class->_no_scheme_ok;
+ my $self = bless \$str, $class;
+ $self;
+}
+
+
+sub implementor
+{
+ my($scheme, $impclass) = @_;
+ unless ($scheme) {
+ require URI::_generic;
+ return "URI::_generic";
+ }
+
+ $scheme = lc($scheme);
+
+ if ($impclass) {
+ # Set the implementor class for a given scheme
+ my $old = $implements{$scheme};
+ $impclass->_init_implementor($scheme);
+ $implements{$scheme} = $impclass;
+ return $old;
+ }
+
+ my $ic = $implements{$scheme};
+ return $ic if $ic;
+
+ # scheme not yet known, look for internal or
+ # preloaded (with 'use') implementation
+ $ic = "URI::$scheme"; # default location
+
+ # turn scheme into a valid perl identifier by a simple tranformation...
+ $ic =~ s/\+/_P/g;
+ $ic =~ s/\./_O/g;
+ $ic =~ s/\-/_/g;
+
+ no strict 'refs';
+ # check we actually have one for the scheme:
+ unless (@{"${ic}::ISA"}) {
+ # Try to load it
+ eval "require $ic";
+ die $@ if $@ && $@ !~ /Can\'t locate.*in \@INC/;
+ return unless @{"${ic}::ISA"};
+ }
+
+ $ic->_init_implementor($scheme);
+ $implements{$scheme} = $ic;
+ $ic;
+}
+
+
+sub _init_implementor
+{
+ my($class, $scheme) = @_;
+ # Remember that one implementor class may actually
+ # serve to implement several URI schemes.
+}
+
+
+sub clone
+{
+ my $self = shift;
+ my $other = $$self;
+ bless \$other, ref $self;
+}
+
+
+sub _no_scheme_ok { 0 }
+
+sub _scheme
+{
+ my $self = shift;
+
+ unless (@_) {
+ return unless $$self =~ /^($scheme_re):/o;
+ return $1;
+ }
+
+ my $old;
+ my $new = shift;
+ if (defined($new) && length($new)) {
+ Carp::croak("Bad scheme '$new'") unless $new =~ /^$scheme_re$/o;
+ $old = $1 if $$self =~ s/^($scheme_re)://o;
+ my $newself = URI->new("$new:$$self");
+ $$self = $$newself;
+ bless $self, ref($newself);
+ } else {
+ if ($self->_no_scheme_ok) {
+ $old = $1 if $$self =~ s/^($scheme_re)://o;
+ Carp::carp("Oops, opaque part now look like scheme")
+ if $^W && $$self =~ m/^$scheme_re:/o
+ } else {
+ $old = $1 if $$self =~ m/^($scheme_re):/o;
+ }
+ }
+
+ return $old;
+}
+
+sub scheme
+{
+ my $scheme = shift->_scheme(@_);
+ return unless defined $scheme;
+ lc($scheme);
+}
+
+
+sub opaque
+{
+ my $self = shift;
+
+ unless (@_) {
+ $$self =~ /^(?:$scheme_re:)?([^\#]*)/o or die;
+ return $1;
+ }
+
+ $$self =~ /^($scheme_re:)? # optional scheme
+ ([^\#]*) # opaque
+ (\#.*)? # optional fragment
+ $/sx or die;
+
+ my $old_scheme = $1;
+ my $old_opaque = $2;
+ my $old_frag = $3;
+
+ my $new_opaque = shift;
+ $new_opaque = "" unless defined $new_opaque;
+ $new_opaque =~ s/([^$uric])/$URI::Escape::escapes{$1}/go;
+
+ $$self = defined($old_scheme) ? $old_scheme : "";
+ $$self .= $new_opaque;
+ $$self .= $old_frag if defined $old_frag;
+
+ $old_opaque;
+}
+
+*path = \&opaque; # alias
+
+
+sub fragment
+{
+ my $self = shift;
+ unless (@_) {
+ return unless $$self =~ /\#(.*)/s;
+ return $1;
+ }
+
+ my $old;
+ $old = $1 if $$self =~ s/\#(.*)//s;
+
+ my $new_frag = shift;
+ if (defined $new_frag) {
+ $new_frag =~ s/([^$uric])/$URI::Escape::escapes{$1}/go;
+ $$self .= "#$new_frag";
+ }
+ $old;
+}
+
+
+sub as_string
+{
+ my $self = shift;
+ $$self;
+}
+
+
+sub canonical
+{
+ my $self = shift;
+
+ # Make sure scheme is lowercased
+ my $scheme = $self->_scheme || "";
+ my $uc_scheme = $scheme =~ /[A-Z]/;
+ my $lc_esc = $$self =~ /%(?:[a-f][a-fA-F0-9]|[A-F0-9][a-f])/;
+ if ($uc_scheme || $lc_esc) {
+ my $other = $self->clone;
+ $other->_scheme(lc $scheme) if $uc_scheme;
+ $$other =~ s/(%(?:[a-f][a-fA-F0-9]|[A-F0-9][a-f]))/uc($1)/ge
+ if $lc_esc;
+ return $other;
+ }
+ $self;
+}
+
+# Compare two URIs, subclasses will provide a more correct implementation
+sub eq {
+ my($self, $other) = @_;
+ $self = URI->new($self, $other) unless ref $self;
+ $other = URI->new($other, $self) unless ref $other;
+ ref($self) eq ref($other) && # same class
+ $self->canonical->as_string eq $other->canonical->as_string;
+}
+
+# generic-URI transformation methods
+sub abs { $_[0]; }
+sub rel { $_[0]; }
+
+1;
+
+__END__
+
+=head1 NAME
+
+URI - Uniform Resource Identifiers (absolute and relative)
+
+=head1 SYNOPSIS
+
+ $u1 = URI->new("http://www.perl.com");
+ $u2 = URI->new("foo", "http");
+ $u3 = $u2->abs($u1);
+ $u4 = $u3->clone;
+ $u5 = URI->new("HTTP://WWW.perl.com:80")->canonical;
+
+ $str = $u->as_string;
+ $str = "$u";
+
+ $scheme = $u->scheme;
+ $opaque = $u->opaque;
+ $path = $u->path;
+ $frag = $u->fragment;
+
+ $u->scheme("ftp");
+ $u->host("ftp.perl.com");
+ $u->path("cpan/");
+
+=head1 DESCRIPTION
+
+This module implements the C<URI> class. Objects of this class
+represent "Uniform Resource Identifier references" as specified in RFC
+2396.
+
+A Uniform Resource Identifier is a compact string of characters for
+identifying an abstract or physical resource. A Uniform Resource
+Identifier can be further classified either a Uniform Resource Locator
+(URL) or a Uniform Resource Name (URN). The distinction between URL
+and URN does not matter to the C<URI> class interface. A
+"URI-reference" is a URI that may have additional information attached
+in the form of a fragment identifier.
+
+An absolute URI reference consists of three parts. A I<scheme>, a
+I<scheme specific part> and a I<fragment> identifier. A subset of URI
+references share a common syntax for hierarchical namespaces. For
+these the scheme specific part is further broken down into
+I<authority>, I<path> and I<query> components. These URI can also
+take the form of relative URI references, where the scheme (and
+usually also the authority) component is missing, but implied by the
+context of the URI reference. The three forms of URI reference
+syntax are summarized as follows:
+
+ <scheme>:<scheme-specific-part>#<fragment>
+ <scheme>://<authority><path>?<query>#<fragment>
+ <path>?<query>#<fragment>
+
+The components that a URI reference can be divided into depend on the
+I<scheme>. The C<URI> class provides methods to get and set the
+individual components. The methods available for a specific
+C<URI> object depend on the scheme.
+
+=head1 CONSTRUCTORS
+
+The following methods construct new C<URI> objects:
+
+=over 4
+
+=item $uri = URI->new( $str, [$scheme] )
+
+This class method constructs a new URI object. The string
+representation of a URI is given as argument together with an optional
+scheme specification. Common URI wrappers like "" and <>, as well as
+leading and trailing white space, are automatically removed from
+the $str argument before it is processed further.
+
+The constructor determines the scheme, maps this to an appropriate
+URI subclass, constructs a new object of that class and returns it.
+
+The $scheme argument is only used when $str is a
+relative URI. It can either be a simple string that
+denotes the scheme, a string containing an absolute URI reference or
+an absolute C<URI> object. If no $scheme is specified for a relative
+URI $str, then $str is simply treated as a generic URI (no scheme
+specific methods available).
+
+The set of characters available for building URI references is
+restricted (see L<URI::Escape>). Characters outside this set are
+automatically escaped by the URI constructor.
+
+=item $uri = URI->new_abs( $str, $base_uri )
+
+This constructs a new absolute URI object. The $str argument can
+denote a relative or absolute URI. If relative, then it will be
+absolutized using $base_uri as base. The $base_uri must be an absolute
+URI.
+
+=item $uri = URI::file->new( $filename, [$os] )
+
+This constructs a new I<file> URI from a file name. See L<URI::file>.
+
+=item $uri = URI::file->new_abs( $filename, [$os] )
+
+This constructs a new absolute I<file> URI from a file name. See
+L<URI::file>.
+
+=item $uri = URI::file->cwd
+
+This returns the current working directory as a I<file> URI. See
+L<URI::file>.
+
+=item $uri->clone
+
+This method returns a copy of the $uri.
+
+=back
+
+=head1 COMMON METHODS
+
+The methods described in this section are available for all C<URI>
+objects.
+
+Methods that give access to components of a URI will always return the
+old value of the component. The value returned will be C<undef> if the
+component was not present. There is generally a difference between a
+component that is empty (represented as C<"">) and a component that is
+missing (represented as C<undef>). If an accessor method is given an
+argument it will update the corresponding component in addition to
+returning the old value of the component. Passing an undefined
+argument will remove the component (if possible). The description of
+the various accessor methods will tell if the component is passed as
+an escaped or an unescaped string. Components that can be futher
+divided into sub-parts are usually passed escaped, as unescaping might
+change its semantics.
+
+The common methods available for all URI are:
+
+=over 4
+
+=item $uri->scheme( [$new_scheme] )
+
+This method sets and returns the scheme part of the $uri. If the $uri is
+relative, then $uri->scheme returns C<undef>. If called with an
+argument, it will update the scheme of $uri, possibly changing the
+class of $uri, and return the old scheme value. The method croaks
+if the new scheme name is illegal; scheme names must begin with a
+letter and must consist of only US-ASCII letters, numbers, and a few
+special marks: ".", "+", "-". This restriction effectively means
+that scheme have to be passed unescaped. Passing an undefined
+argument to the scheme method will make the URI relative (if possible).
+
+Letter case does not matter for scheme names. The string
+returned by $uri->scheme is always lowercase. If you want the scheme
+just as it was written in the URI in its original case,
+you can use the $uri->_scheme method instead.
+
+=item $uri->opaque( [$new_opaque] )
+
+This method sets and returns the scheme specific part of the $uri
+(everything between the scheme and the fragment)
+as an escaped string.
+
+=item $uri->path( [$new_path] )
+
+This method sets and returns the same value as $uri->opaque unless the URI
+supports the generic syntax for hierarchical namespaces.
+In that case the generic method is overridden to set and return
+the part of the URI between the I<host name> and the I<fragment>.
+
+=item $uri->fragment( [$new_frag] )
+
+This method returns the fragment identifier of a URI reference
+as an escaped string.
+
+=item $uri->as_string
+
+This method returns a URI object to a plain string. URI objects are
+also converted to plain strings automatically by overloading. This
+means that $uri objects can be used as plain strings in most Perl
+constructs.
+
+=item $uri->canonical
+
+This method will return a normalized version of the URI. The rules
+for normalization are scheme dependent. It usually involves
+lowercasing of the scheme and the Internet host name components,
+removing the explicit port specification if it matches the default port,
+uppercasing all escape sequences, and unescaping octets that can be
+better represented as plain characters.
+
+For efficiency reasons, if the $uri already was in normalized form,
+then a reference to it is returned instead of a copy.
+
+=item $uri->eq( $other_uri )
+
+=item URI::eq( $first_uri, $other_uri )
+
+This method tests whether two URI references are equal. URI references
+that normalize to the same string are considered equal. The method
+can also be used as a plain function which can also test two string
+arguments.
+
+If you need to test whether two C<URI> object references denote the
+same object, use the '==' operator.
+
+=item $uri->abs( $base_uri )
+
+This method returns an absolute URI reference. If $uri already is
+absolute, then a reference to it is simply returned. If the $uri
+is relative, then a new absolute URI is constructed by combining the
+$uri and the $base_uri, and returned.
+
+=item $uri->rel( $base_uri )
+
+This method returns a relative URI reference if it is possible to
+make one that denotes the same resource relative to $base_uri.
+If not, then $uri is simply returned.
+
+=back
+
+=head1 GENERIC METHODS
+
+The following methods are available to schemes that use the
+common/generic syntax for hierarchical namespaces. The description of
+schemes below will tell which one these are. Unknown schemes are
+assumed to support the generic syntax, and therefore the following
+methods:
+
+=over 4
+
+=item $uri->authority( [$new_authority] )
+
+This method sets and returns the escaped authority component
+of the $uri.
+
+=item $uri->path( [$new_path] )
+
+This method sets and returns the escaped path component of
+the $uri (the part between the host name and the query or fragment).
+The path will never be undefined, but it can be the empty string.
+
+=item $uri->path_query( [$new_path_query] )
+
+This method sets and returns the escaped path and query
+components as a single entity. The path and the query are
+separated by a "?" character, but the query can itself contain "?".
+
+=item $uri->path_segments( [$segment,...] )
+
+This method sets and returns the path. In scalar context it returns
+the same value as $uri->path. In list context it will return the
+unescaped path segments that make up the path. Path segments that
+have parameters are returned as an anonymous array. The first element
+is the unescaped path segment proper. Subsequent elements are escaped
+parameter strings. Such an anonymous array uses overloading so it can
+be treated as a string too, but this string does not include the
+parameters.
+
+=item $uri->query( [$new_query] )
+
+This method sets and returns the escaped query component of
+the $uri.
+
+=item $uri->query_form( [$key => $value,...] )
+
+This method sets and returns query components that use the
+I<application/x-www-form-urlencoded> format. Key/value pairs are
+separated by "&" and the key is separated from the value with a "="
+character.
+
+=item $uri->query_keywords( [$keywords,...] )
+
+This method sets and returns query components that use the
+keywords separated by "+" format.
+
+=back
+
+=head1 SERVER METHODS
+
+Schemes where the I<authority> component denotes a Internet host will
+have the following methods available in addition to the generic
+methods.
+
+=over 4
+
+=item $uri->userinfo( [$new_userinfo] )
+
+This method sets and returns the escaped userinfo part of the
+authority componenent.
+
+For some schemes this will be a user name and a password separated by
+a colon. This practice is not recommended. Embedding passwords in
+clear text (such as URI) has proven to be a security risk in almost
+every case where it has been used.
+
+=item $uri->host( [$new_host] )
+
+This method sets and returns the unescaped hostname.
+
+If the $new_host string ends with a colon and a number, then this
+number will also set the port.
+
+=item $uri->port( [ $new_port] )
+
+This method sets and returns the port. The port is simple integer
+that should be greater than 0.
+
+If no explicit port is specified in the URI, then the default port of
+the URI scheme is returned. If you don't want the default port
+substituted, then you can use the $uri->_port method instead.
+
+=item $uri->host_port( [ $new_host_port ] )
+
+This method sets and returns the host and port as a single
+unit. The returned value will include a port, even if it matches the
+default port. The host part and the port part is separated with a
+colon; ":".
+
+=item $uri->default_port
+
+This method returns the default port of the URI scheme that $uri
+belongs to. For I<http> this will be the number 80, for I<ftp> this
+will be the number 21, etc. The default port for a scheme can not be
+changed.
+
+=back
+
+=head1 SCHEME SPECIFIC SUPPORT
+
+The following URI schemes are specifically supported. For C<URI>
+objects not belonging to one of these you can only use the common and
+generic methods.
+
+=over 4
+
+=item B<data>:
+
+The I<data> URI scheme is specified in RFC 2397. It allows inclusion
+of small data items as "immediate" data, as if it had been included
+externally.
+
+C<URI> objects belonging to the data scheme support the common methods
+and two new methods to access their scheme specific components;
+$uri->media_type and $uri->data. See L<URI::data> for details.
+
+=item B<file>:
+
+An old specification of the I<file> URI scheme is found in RFC 1738.
+A new RFC 2396 based specification in not available yet, but file URI
+references are in common use.
+
+C<URI> objects belonging to the file scheme support the common and
+generic methods. In addition they provide two methods to map file URI
+back to local file names; $uri->file and $uri->dir. See L<URI::file>
+for details.
+
+=item B<ftp>:
+
+An old specification of the I<ftp> URI scheme is found in RFC 1738. A
+new RFC 2396 based specification in not available yet, but ftp URI
+references are in common use.
+
+C<URI> objects belonging to the ftp scheme support the common,
+generic and server methods. In addition they provide two methods to
+access the userinfo sub-components: $uri->user and $uri->password.
+
+=item B<gopher>:
+
+The I<gopher> URI scheme is specified in
+<draft-murali-url-gopher-1996-12-04> and will hopefully be available
+as a RFC 2396 based specification.
+
+C<URI> objects belonging to the gopher scheme support the common,
+generic and server methods. In addition they support some methods to
+access gopher specific path components: $uri->gopher_type,
+$uri->selector, $uri->search, $uri->string.
+
+=item B<http>:
+
+The I<http> URI scheme is specified in
+<draft-ietf-http-v11-spec-rev-06> (which will become an RFC soon).
+The scheme is used to reference resources hosted by HTTP servers.
+
+C<URI> objects belonging to the http scheme support the common,
+generic and server methods.
+
+=item B<https>:
+
+The I<https> URI scheme is a Netscape invention which is commonly
+implemented. The scheme is used to reference HTTP servers through SSL
+connections. It's syntax is the same as http, but the default
+port is different.
+
+=item B<ldap>:
+
+The I<ldap> URI scheme is specified in RFC 2255. LDAP is the
+Lightweight Directory Access Protocol. A ldap URI describes an LDAP
+search operation to perform to retrieve information from an LDAP
+directory.
+
+C<URI> objects belonging to the ldap scheme support the common,
+generic and server methods as well as specific ldap methods; $uri->dn,
+$uri->attributes, $uri->scope, $uri->filter, $uri->extensions. See
+L<URI::ldap> for details.
+
+=item B<mailto>:
+
+The I<mailto> URI scheme is specified in RFC 2368. The scheme was
+originally used to designate the Internet mailing address of an
+individual or service. It has (in RFC 2368) been extended to allow
+setting of other mail header fields and the message body.
+
+C<URI> objects belonging to the mailto scheme support the common
+methods and the generic query methods. In addition they support the
+following mailto specific methods: $uri->to, $uri->headers.
+
+=item B<news>:
+
+The I<news>, I<nntp> and I<snews> URI schemes are specified in
+<draft-gilman-news-url-01> and will hopefully be available as a RFC
+2396 based specification soon.
+
+C<URI> objects belonging to the news scheme support the common,
+generic and server methods. In addition they provide some methods to
+access the path: $uri->group and $uri->message.
+
+=item B<nntp>:
+
+See I<news> scheme.
+
+=item B<pop>:
+
+The I<pop> URI scheme is specified in RFC 2384. The scheme is used to
+reference a POP3 mailbox.
+
+C<URI> objects belonging to the pop scheme support the common, generic
+and server methods. In addition they provide two methods to access the
+userinfo components: $uri->user and $uri->auth
+
+=item B<rlogin>:
+
+An old speficication of the I<rlogin> URI scheme is found in RFC
+1738. C<URI> objects belonging to the rlogin scheme support the
+common, generic and server methods.
+
+=item B<rsync>:
+
+Information about rsync is available from http://rsync.samba.org.
+C<URI> objects belonging to the rsync scheme support the common,
+generic and server methods. In addition they provide methods to
+access the userinfo sub-components: $uri->user and $uri->password.
+
+=item B<snews>:
+
+See I<news> scheme. It's syntax is the same as news, but the default
+port is different.
+
+=item B<telnet>:
+
+An old speficication of the I<telnet> URI scheme is found in RFC
+1738. C<URI> objects belonging to the telnet scheme support the
+common, generic and server methods.
+
+=back
+
+
+=head1 CONFIGURATION VARIABLES
+
+The following configuration variables influence how the class and it's
+methods behave:
+
+=over 4
+
+=item $URI::ABS_ALLOW_RELATIVE_SCHEME
+
+Some older parsers used to allow the scheme name to be present in the
+relative URL if it was the same as the base URL scheme. RFC 2396 says
+that this should be avoided, but you can enable this old behaviour by
+setting the $URI::ABS_ALLOW_RELATIVE_SCHEME variable to a TRUE value.
+The difference is demonstrated by the following examples:
+
+ URI->new("http:foo")->abs("http://host/a/b")
+ ==> "http:foo"
+
+ local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1;
+ URI->new("http:foo")->abs("http://host/a/b")
+ ==> "http:/host/a/foo"
+
+
+=item $URI::ABS_REMOTE_LEADING_DOTS
+
+You can also have the abs() method ignore excess ".."
+segments in the relative URI by setting $URI::ABS_REMOTE_LEADING_DOTS
+to a TRUE value. The difference is demonstrated by the following
+examples:
+
+ URI->new("../../../foo")->abs("http://host/a/b")
+ ==> "http://host/../../foo"
+
+ local $URI::URL::ABS_REMOTE_LEADING_DOTS = 1;
+ URI->new("../../../foo")->abs("http://host/a/b")
+ ==> "http://host/foo"
+
+=back
+
+
+
+=head1 SEE ALSO
+
+L<URI::file>, L<URI::WithBase>, L<URI::Escape>, L<URI::Heuristic>
+
+RFC 2396: "Uniform Resource Identifiers (URI): Generic Syntax",
+Berners-Lee, Fielding, Masinter, August 1998.
+
+=head1 COPYRIGHT
+
+Copyright 1995-2000 Gisle Aas.
+
+Copyright 1995 Martijn Koster.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=head1 AUTHORS / ACKNOWLEDGMENTS
+
+This module is based on the C<URI::URL> module, which in turn was
+(distantly) based on the C<wwwurl.pl> code in the libwww-perl for
+perl4 developed by Roy Fielding, as part of the Arcadia project at the
+University of California, Irvine, with contributions from Brooks
+Cutter.
+
+C<URI::URL> was developed by Gisle Aas, Tim Bunce, Roy Fielding and
+Martijn Koster with input from other people on the libwww-perl mailing
+list.
+
+C<URI> and related subclasses was developed by Gisle Aas.
+
+=cut