Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ xt_mode = 1

[Test::Pod::Coverage::Configurable]
skip = URI::IRI
skip = URI::_emailauth
skip = URI::_foreign
skip = URI::_idna
skip = URI::_login
Expand Down Expand Up @@ -120,7 +121,6 @@ trustme = URI::gopher => qr/^(?:gopher_type|gtype|search|selector|string)$/
trustme = URI::ldapi => qr/^(?:un_path)$/
trustme = URI::mailto => qr/^(?:headers|to)$/
Copy link
Preview

Copilot AI Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of the POP trustme line appears to be incorrect. The user and auth methods are now in URI::_emailauth but may still need to be trusted for POP documentation coverage since they're public methods of the POP class.

Suggested change
trustme = URI::mailto => qr/^(?:headers|to)$/
trustme = URI::mailto => qr/^(?:headers|to)$/
trustme = URI::pop => qr/^(?:user|auth)$/

Copilot uses AI. Check for mistakes.

trustme = URI::news => qr/^(?:group|message)$/
trustme = URI::pop => qr/^(?:auth|user)$/
trustme = URI::sip => qr/^(?:params|params_form)$/
trustme = URI::urn => qr/^(?:nid|nss)$/

Expand All @@ -129,6 +129,7 @@ wordlist = Pod::Wordlist
spell_cmd = aspell list
stopword = Berners
stopword = CRS
stopword = earhart
stopword = etype
stopword = evalue
stopword = IDNA
Expand Down
17 changes: 13 additions & 4 deletions lib/URI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ our $schemes_without_host_part_re = 'data|ldapi|urn|sqlite|sqlite3';

# These schemes can have an IPv6+ authority part:
# file, ftp, gopher, http, https, ldap, ldaps, mms, news, nntp, nntps, pop, rlogin, rtsp, rtspu, rsync, sip, sips, snews,
# telnet, tn3270, ssh, sftp
# smtp, telnet, tn3270, ssh, sftp
# (all DB URIs, i.e. cassandra, couch, couchdb, etc.), except 'sqlite:', 'sqlite3:'. Others?
#MAINT: URI has no test coverage for DB schemes
#MAINT: decoupling - perhaps let each class decide itself by defining a member function 'scheme_has_authority_part()'?
Expand Down Expand Up @@ -976,7 +976,7 @@ which has its own defaults for I<ftps> and I<ftpes> URI schemes.
=item B<gopher>:

The I<gopher> URI scheme is specified in
<draft-murali-url-gopher-1996-12-04> and will hopefully be available
C<draft-murali-url-gopher-1996-12-04> and will hopefully be available
Copy link
Preview

Copilot AI Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This change from angle brackets to C<> markup is inconsistent with the SMTP documentation format which uses L<> for external links. Consider using L instead for consistency.

Suggested change
C<draft-murali-url-gopher-1996-12-04> and will hopefully be available
L<draft-murali-url-gopher-1996-12-04> and will hopefully be available

Copilot uses AI. Check for mistakes.

as a RFC 2396 based specification.

C<URI> objects belonging to the gopher scheme support the common,
Expand Down Expand Up @@ -1112,8 +1112,8 @@ 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
and server methods, as well as two email authorization methods:
C<user> and C<auth>.

=item B<rlogin>:

Expand Down Expand Up @@ -1160,6 +1160,15 @@ generic and server methods. In addition, they provide methods to
access the userinfo sub-components ($uri->user and $uri->password)
as well as $uri->authdomain and $uri->sharename methods.

=item B<smtp>:

The I<smtp> URI scheme is specified in L<draft-earhart-url-smtp-00|https://datatracker.ietf.org/doc/html/draft-earhart-url-smtp-00>.
The scheme is used to reference a SMTP server.

C<URI> objects belonging to the smtp scheme support the common, generic
and server methods, as well as two email authorization methods:
C<user> and C<auth>.

=item B<snews>:

See I<news> scheme. Its syntax is the same as news, but the default
Expand Down
70 changes: 70 additions & 0 deletions lib/URI/_emailauth.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package URI::_emailauth;

use strict;
use warnings;

our $VERSION = '5.33';

use parent 'URI::_server';

use URI::Escape qw(uri_unescape);

# Common user/auth code used in email URL schemes, such as POP, SMTP, IMAP.
# <scheme>://<user>;auth=<auth>@<host>:<port>

sub user
{
my $self = shift;
my $old = $self->userinfo;

if (@_) {
my $new_info = $old;
$new_info = "" unless defined $new_info;
$new_info =~ s/^[^;]*//;

my $new = shift;
if (!defined($new) && !length($new_info)) {
$self->userinfo(undef);
} else {
$new = "" unless defined $new;
$new =~ s/%/%25/g;
$new =~ s/;/%3B/g;
$self->userinfo("$new$new_info");
}
}

return undef unless defined $old;
$old =~ s/;.*//;
return uri_unescape($old);
}

sub auth
{
my $self = shift;
my $old = $self->userinfo;

if (@_) {
my $new = $old;
$new = "" unless defined $new;
$new =~ s/(^[^;]*)//;
my $user = $1;
$new =~ s/;auth=[^;]*//i;


Copy link
Preview

Copilot AI Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the extra blank line. This appears to be unnecessary whitespace that should be cleaned up.

Suggested change

Copilot uses AI. Check for mistakes.

my $auth = shift;
if (defined $auth) {
$auth =~ s/%/%25/g;
$auth =~ s/;/%3B/g;
$new = ";AUTH=$auth$new";
}
$self->userinfo("$user$new");

}

return undef unless defined $old;
$old =~ s/^[^;]*//;
return uri_unescape($1) if $old =~ /;auth=(.*)/i;
return;
}

1;
57 changes: 1 addition & 56 deletions lib/URI/pop.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,12 @@ use warnings;

our $VERSION = '5.33';

use parent 'URI::_server';
use parent 'URI::_emailauth';

use URI::Escape qw(uri_unescape);

sub default_port { 110 }

#pop://<user>;auth=<auth>@<host>:<port>

sub user
{
my $self = shift;
my $old = $self->userinfo;

if (@_) {
my $new_info = $old;
$new_info = "" unless defined $new_info;
$new_info =~ s/^[^;]*//;

my $new = shift;
if (!defined($new) && !length($new_info)) {
$self->userinfo(undef);
} else {
$new = "" unless defined $new;
$new =~ s/%/%25/g;
$new =~ s/;/%3B/g;
$self->userinfo("$new$new_info");
}
}

return undef unless defined $old;
$old =~ s/;.*//;
return uri_unescape($old);
}

sub auth
{
my $self = shift;
my $old = $self->userinfo;

if (@_) {
my $new = $old;
$new = "" unless defined $new;
$new =~ s/(^[^;]*)//;
my $user = $1;
$new =~ s/;auth=[^;]*//i;


my $auth = shift;
if (defined $auth) {
$auth =~ s/%/%25/g;
$auth =~ s/;/%3B/g;
$new = ";AUTH=$auth$new";
}
$self->userinfo("$user$new");

}

return undef unless defined $old;
$old =~ s/^[^;]*//;
return uri_unescape($1) if $old =~ /;auth=(.*)/i;
return;
}

1;
16 changes: 16 additions & 0 deletions lib/URI/smtp.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package URI::smtp; # draft-earhart-url-smtp-00

use strict;
use warnings;

our $VERSION = '5.33';

use parent 'URI::_emailauth';

use URI::Escape qw(uri_unescape);

sub default_port { 25 }

#smtp://<user>;auth=<auth>@<host>:<port>

1;
42 changes: 42 additions & 0 deletions t/smtp.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use strict;
use warnings;

use Test::More tests => 8;

use URI ();

my $u = URI->new('smtp://[email protected]');

ok($u->user eq "foobar" &&
!defined($u->auth) &&
$u->host eq "smtp.example.com" &&
$u->port == 25 &&
$u eq 'smtp://[email protected]');

$u->auth("+XOAUTH2");
ok($u->auth eq "+XOAUTH2" &&
$u eq 'smtp://foobar;[email protected]');

$u->user("bizz");
ok($u->user eq "bizz" &&
$u eq 'smtp://bizz;[email protected]');

$u->port(4000);
is($u, 'smtp://bizz;[email protected]:4000');

$u = URI->new("smtp:");
$u->host("smtp.example.com");
$u->user("foobar");
$u->auth("*");
is($u, 'smtp://foobar;AUTH=*@smtp.example.com');

$u->auth(undef);
is($u, 'smtp://[email protected]');

$u->user(undef);
is($u, 'smtp://smtp.example.com');

# Try some funny characters too
$u->user('sn☃wm@n');
ok($u->user eq 'sn☃wm@n' &&
$u eq 'smtp://sn%E2%98%83wm%[email protected]');
Loading