Skip Menu |

This queue is for tickets about the libnet CPAN distribution.

Report information
The Basics
Id: 37700
Status: resolved
Priority: 0/
Queue: libnet

People
Owner: Nobody in particular
Requestors: dom [...] cpan.org
roam [...] ringlet.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: 1.22_02



Subject: Net::FTP assumes a data connection after a failed command
First of all, thanks a lot for maintaing libnet! In the Net::FTP::_data_cmd() routine the dataconn() sub is invoked unconditionally and without any error checking immediately after sending a command to the server. It turns out that there are FTP servers out there on the Big Bad Internet that close the data connection port immediately after a failed transfer command. In this case, Net::FTP misbehaves in two ways: 1. Net::FTP::dataconn->close() and _close() methods try to use the 'net_ftp_cmd' member without checking if it has even been set - and on a failed connection, it is not, thus Perl 5.10.0 breaks out with an error. 2. Net::FTP::_data_cmd() invokes dataconn() unconditionally even when it does not *need* it - even when the command has failed. The end result is that the attached test script fails on Perl 5.10.0 on Debian testing (lenny) - the Perl interpreter throws an error in Net::FTP::dataconn::_close() (and after fixing it, another one in close()), which LWP::Request interprets as an "Internal server error". I've attached two patches - net-ftp-dataconn-close.patch adds a Net::FTP::dataconn check whether the 'net_ftp_cmd' member is defined at all before using it, and net-ftp-dataconn-eval.patch modifies Net::FTP::_data_cmd() to invoke dataconn() in an eval, so that a failure there will *still* return properly if the result code is bad. Of course, there are other ways to work around these problems, but these were the ones that I thought of first :)
Subject: net-ftp-dataconn-test.pl
#!/usr/bin/perl -Tw use strict; use LWP::UserAgent; my ($ua, $req, $resp); $ua = LWP::UserAgent->new('env_proxy' => 1) or die("Could not instantiate the LWP user agent\n"); $req = HTTP::Request->new('GET' => 'ftp://ftp.inet.no/pub/socks/'); $ENV{'FTP_PASSIVE'} = 1; LWP::Debug::level('+'); $resp = $ua->request($req); print ($resp->is_success()? "yep\n": "nope\n");
Subject: net-ftp-dataconn-eval.patch
--- Net/FTP.pm.old 2008-07-15 18:30:29.000000000 +0300 +++ Net/FTP.pm 2008-07-15 18:30:41.000000000 +0300 @@ -1011,7 +1011,9 @@ if ($ok) { $ftp->command($cmd, @_); - $data = $ftp->_dataconn(); + eval { + $data = $ftp->_dataconn(); + }; $ok = CMD_INFO == $ftp->response(); if ($ok) { $data->reading
Subject: net-ftp-dataconn-close.patch
--- Net/FTP/dataconn.pm.old 2008-07-15 18:47:54.000000000 +0300 +++ Net/FTP/dataconn.pm 2008-07-15 18:48:09.000000000 +0300 @@ -52,7 +52,7 @@ $data->SUPER::close(); delete ${*$ftp}{'net_ftp_dataconn'} - if exists ${*$ftp}{'net_ftp_dataconn'} + if defined($ftp) && exists ${*$ftp}{'net_ftp_dataconn'} && $data == ${*$ftp}{'net_ftp_dataconn'}; } @@ -69,6 +69,7 @@ $data->_close; + return 0 unless defined($ftp); $ftp->response() == CMD_OK && $ftp->message =~ /unique file name:\s*(\S*)\s*\)/ && (${*$ftp}{'net_ftp_unique'} = $1);
Show quoted text
> I've attached two patches - net-ftp-dataconn-close.patch adds a > Net::FTP::dataconn check whether the 'net_ftp_cmd' member is defined at > all before using it,
This looks like the correct fix to me. With the patch I get the correct error message on a connection timeout. Please apply.
On Mon Dec 07 17:08:14 2009, NWELLNHOF wrote: Show quoted text
> > I've attached two patches - net-ftp-dataconn-close.patch adds a > > Net::FTP::dataconn check whether the 'net_ftp_cmd' member is defined at > > all before using it,
> > This looks like the correct fix to me. With the patch I get the correct > error message on a connection timeout. > > Please apply.
Hello, Is there anything we can do to help get this applied, now that it's been confirmed as fixing the problem? Incidentally this is also <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=491062> Thanks, Dominic.
This should now be fixed in 1.22_02.