Skip Menu |

This queue is for tickets about the Mail-Box CPAN distribution.

Report information
The Basics
Id: 82983
Status: resolved
Priority: 0/
Queue: Mail-Box

People
Owner: Nobody in particular
Requestors: rotkraut [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.107
Fixed in: 2.118



Subject: Failed to open IMAP4 folder using Mail::Box::Manager: Couldn't select IMAP4 folder
Problem describtion =================== I can successfully open an IMAP4 folder, using Mail::Box::IMAP4 directly in the following way: use Mail::Box::IMAP4; my $imaphost = 'mail.example.org'; my $imapuser = 'USER'; my $imappass = 'PASS'; my $mailbox = 'INBOX'; my $folder= new Mail::Box::IMAP4(server_name => $imaphost, username => $imapuser, password => $imappass, folder => $mailbox); print $folder->nrMessages, " messages\n"; But when I try to use Mail::Box::Manager instead, the following code fails: use Mail::Box::Manager; my $imaphost = 'mail.example.org'; my $imapuser = 'USER'; my $imappass = 'PASS'; my $mailbox = 'INBOX'; my $url = "imap4://$imapuser:$imappass\@$imaphost/$mailbox"; my $mgr = Mail::Box::Manager->new; my $folder = $mgr->open(folder => $url); print $folder->nrMessages, " messages\n"; I get the following error message: ERROR: Couldn't select IMAP4 folder imap4://USER@mail.example.org:143 ERROR: Couldn't select IMAP4 folder imap4://USER@mail.example.org:143 WARNING: Folder does not exist, failed opening imap4 folder imap4://USER@mail.example.org:143. Analysis ======== The problem seem to be caused by the differences in the semantic of the 'folder' argument between Mail::Box::Manager and Mail::Box::IMAP4. In Mail::Box::Manager assumes the "folder" argument to be the url, while Mail::Box::IMAP4 assumes the folder to be just the IMAP4 mailbox part, "/INBOX" in this example. Digging through the code, I see that Mail::Box::Manager correctly decodes the folder url in sub open in line 141: my %decoded = $self->decodeFolderURL($name); if(keys %decoded) { # accept decoded info @args{keys %decoded} = values %decoded; } which results in %args = ( authentication => 'AUTO', folder => '/INBOX' password => 'PASS', server_name => 'mail.example.org', server_port => undef, type => 'imap4', username => 'USER', ); This is just fine and could perfectly be passed to Mail::Box::IMAP4 this way. But then, Mail::Box::Manager overwrites the folder in line 174: elsif($type eq 'imap4') { my $un = $args{username} ||= $ENV{USER} || $ENV{LOGIN}; my $srv = $args{server_name} ||= 'localhost'; my $port = $args{server_port} ||= 143; $args{folder} = $name = "imap4://$un\@$srv:$port"; } This is just plain wrong. As a consequence, Mail::Box::IMAP4->new gets called with the following arguments: %args = ( access => 'r', authentication => 'AUTO', folder => 'imap4://USER@mail.example.org:143', folderdir => '.', manager => Mail::Box::Manager=HASH(0x1409580), password => 'PASS', server_name => 'mail.example.org', server_port => 143, type => 'imap4', username => 'USER', ); which obviously leads to the above-mentioned error. Fix === Do not overwrite the folder in Mail::Box::Manager, see attached patch. After applying the patch, opening an IMAP4 folder using Mail::Box::Manager with the example code above works fine for me. Note: the code code for POP3 in Mail::Box::Manager looks similar and might contain the same error. But I do not have access to any POP3 server, so I can't try this out.
Subject: Mail-Box-IMAP-folder.patch
--- lib/Mail/Box/Manager.pm.orig 2012-11-28 12:28:35.000000000 +0100 +++ lib/Mail/Box/Manager.pm 2013-01-27 15:26:51.312252501 +0100 @@ -171,7 +171,7 @@ { my $un = $args{username} ||= $ENV{USER} || $ENV{LOGIN}; my $srv = $args{server_name} ||= 'localhost'; my $port = $args{server_port} ||= 143; - $args{folder} = $name = "imap4://$un\@$srv:$port"; + $name = "imap4://$un\@$srv:$port"; } unless(defined $name && length $name)
Subject: Re: [rt.cpan.org #82983] Failed to open IMAP4 folder using Mail::Box::Manager: Couldn't select IMAP4 folder
Date: Mon, 28 Jan 2013 11:15:10 +0100
To: Rolf Krahl via RT <bug-Mail-Box [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* Rolf Krahl via RT (bug-Mail-Box@rt.cpan.org) [130127 14:42]: Show quoted text
> Sun Jan 27 09:42:15 2013: Request 82983 was acted upon. > Transaction: Ticket created by ROTKRAUT > Subject: Failed to open IMAP4 folder using Mail::Box::Manager: Couldn't > select IMAP4 folder
... Show quoted text
> This is just fine and could perfectly be passed to Mail::Box::IMAP4 > this way. But then, Mail::Box::Manager overwrites the folder in line > 174: > > elsif($type eq 'imap4') > { my $un = $args{username} ||= $ENV{USER} || $ENV{LOGIN}; > my $srv = $args{server_name} ||= 'localhost'; > my $port = $args{server_port} ||= 143; > $args{folder} = $name = "imap4://$un\@$srv:$port"; > } > > This is just plain wrong. As a consequence, Mail::Box::IMAP4->new > gets called with the following arguments:
Isn't the only problem that the password is not included in the new folder url? We cannot leave the original "folder" parameter in-tact, because that may not exist and may need some defaults added. The latter to be able to reduce the risk that the same folder gets opened twice with nearly the same name. The folder option is designed to be more flexible. Show quoted text
> --- lib/Mail/Box/Manager.pm.orig 2012-11-28 12:28:35.000000000 +0100 > +++ lib/Mail/Box/Manager.pm 2013-01-27 15:26:51.312252501 +0100 > - $args{folder} = $name = "imap4://$un\@$srv:$port"; > + $name = "imap4://$un\@$srv:$port"; > }
Not applied (yet) -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Subject: Re: [rt.cpan.org #82983] Failed to open IMAP4 folder using Mail::Box::Manager: Couldn't select IMAP4 folder
Date: Mon, 28 Jan 2013 15:28:47 +0100
To: bug-Mail-Box [...] rt.cpan.org
From: Rolf Krahl <rotkraut [...] cpan.org>
Am Montag, 28. Januar 2013, 05:15:32 schrieben Sie: Show quoted text
> * Rolf Krahl via RT (bug-Mail-Box@rt.cpan.org) [130127 14:42]: >
> > This is just fine and could perfectly be passed to Mail::Box::IMAP4 > > this way. But then, Mail::Box::Manager overwrites the folder in line > > 174: > > > > elsif($type eq 'imap4') > > { my $un = $args{username} ||= $ENV{USER} || $ENV{LOGIN}; > > my $srv = $args{server_name} ||= 'localhost'; > > my $port = $args{server_port} ||= 143; > > $args{folder} = $name = "imap4://$un\@$srv:$port"; > > } > > > > This is just plain wrong. As a consequence, Mail::Box::IMAP4->new > > gets called with the following arguments:
> > Isn't the only problem that the password is not included in the > new folder url?
No, the problem is that Mail::Box::Manager and Mail::Box::IMAP4 are incompatible with respect to the meaning of the folder argument in their respective methods open and new. Just to make terms and definitions clear, lets assume the following settings: my $imaphost = 'mail.example.org'; my $imapuser = 'USER'; my $imappass = 'PASS'; my $mailbox = 'INBOX'; my $url = "imap4://$imapuser:$imappass\@$imaphost/$mailbox"; Mail::Box::Manager->open may be called in different ways, but in general, a folder is the full folder url in terms of Mail::Box::Manager. Mail::Box::IMAP4->new is not able to deal with folder urls at all. It must be called with all the components in separate arguments, in this way: Mail::Box::IMAP4->new(server_name => $imaphost, username => $imapuser, password => $imappass, folder => $mailbox); In particular, in Mail::Box::IMAP4, the folder is always the mailbox name, $mailbox at the IMAP server. At this point of the code, the password is present in $args{password}. In fact, the example script logs in succesfully to the IMAP server. But then it tries to open a mailbox by the name "imap4://USER@mail.example.org:143", which obviously does not exist at the IMAP server and that's the point, the script fails. Show quoted text
> We cannot leave the original "folder" parameter in-tact, because that > may not exist and may need some defaults added.
At this point in the code, the "folder" parameter does not contain the original argument from the call to $mgr->open any more. It has already been processed, all defaults are already applied, and the "folder" parameter, as well as the other components in %args are the result of the call to decodeFolderURL in line 141. This decoding of the url already split up all components in their respective fields, just the way it need to be set up in order to call Mail::Box::IMAP4->new.
Resolved in 2015