Problem with ftp_get and ftp_put over SSL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I need to transfer files between a server at my company and one of our
vendors.  The vendor's running a SecureFTP (FTPS) server.  In order to
automate this from our side, I've created a class that wraps the ftp
functions in an object.

When I test my class on a standard FTP server, everything works fine: I
can login, chdir, chmod, get/nb_get, put/nb_put, etc.  However, when I
connect to the vendor's server using ftp_ssl_connect (instead of
ftp_connect), everything works fine with the exception of put/nb_put and
get/nb_get.  (I'm testing using PHPUnit2, and all my tests pass except
for the get/put tests.)

At first, I thought it may be a firewall issue, but I've checked the
logs on our firewall and nothing is being logged as being blocked at
that level.  Also, the firewall rule is written in such a way that it's
allowing all traffic to/from the vendor's server; so it doesn't appear
like it's an issue with the data port not being open.  I have verified
that the same commands I'm using in my PHP code work using an FTP
client, and they do.  I've used lftp to connect to the vendor's FTPS
server, chmod, chdir, get/put files...everything works fine.

For the put/get commands, when I run my PHPUnit2 tests, I am getting the
following output on the put/nb_put and get/nb_put commands:

Warning: ftp_nb_put(): PORT command successful.
in /home/tboring/scripts/ftp.class.php on line 490

Warning: ftp_put(): PORT command successful.
in /home/tboring/scripts/ftp.class.php on line 587

Warning: ftp_get(): PORT command successful.
in /home/tboring/scripts/ftp.class.php on line 399

Warning: ftp_nb_get(): PORT command successful.
in /home/tboring/scripts/ftp.class.php on line 453

Here's the actual code from my test object for all 4 commands:

function testNbput()
{
   $this->FTP->nb_put("output.test", "output.test", FTP_ASCII);

   echo "\nTest Name: testNbput()\n";
   $this->assertEquals(0, $this->FTP->getVar(error_code));
}

function testPut()
{
  $this->FTP->put('output.test', 'output.test', FTP_ASCII);
  
  echo "\nTest Name: testPut()\n";
  $this->assertEquals(0, $this->FTP->getVar(error_code));
}

function testGet()
{
  $this->FTP->get("/tmp/test.txt", "test.txt", FTP_ASCII);

  echo "\nTest Name: testGet()\n";
  $this->assertEquals(0, $this->FTP->getVar(error_code));
}

function testNbget()
{
  $this->FTP->nb_get("/tmp/test.txt", "test.txt", FTP_ASCII);

  echo "\nTest Name: testNbget()\n";
  $this->assertEquals(0, $this->FTP->getVar(error_code));
}

Here's the corresponding code from my class:

function get($local_file, $remote_file, $mode)
{
   if (isset($this->conn_id)) {
     if (ftp_get($this->conn_id, $local_file, $remote_file, $mode)) {
       $this->xfer_status = "FTP_FINISHED";
       $this->last_file_downloaded = $remote_file;
       $this->error_code = 0;
     } else {
        $this->error_code = 11;
        $this->error_message = "Unable to get file $file using $mode.";
     }
   } else {
       $this->error_code = 7;
       $this->error_message = "There is no current connection to an
FTP/FTPS server.";
  }
}

function nb_get($local_file, $remote_file, $mode)
{
   if (isset($this->conn_id)) {
     $status = ftp_nb_get($this->conn_id, $local_file, $remote_file,
$mode);

     while ($status == FTP_MOREDATA) {
       $status = ftp_nb_continue($this->conn_id);
     }

     if ($status != FTP_FINISHED) {
       $this->xfer_status = "FTP_FAILED";
       $this->error_code = 11;
       $this->error_message = "Unable to download file $file using
$mode.";
     } else {
       $this->xfer_status = "FTP_FINISHED";
       $this->last_file_downloaded = $remote_file;
       $this->error_code = 0;
     }
   } else {
       $this->error_code = 7;
       $this->error_message = "There is no current connection to an
FTP/FTPS server.";
   }
}

function nb_put($remote_file, $local_file, $mode)
{
   if (isset($this->conn_id)) {
     $status = ftp_nb_put($this->conn_id, $remote_file, $local_file,
$mode);

     while ($status == FTP_MOREDATA) {
       $status = ftp_nb_continue($this->conn_id);
     }

     if ($status != FTP_FINISHED) {
       $this->xfer_status = "FTP_FAILED";
       $this->error_code = 11;
       $this->error_message = "Unable to upload file $file using
$mode.";
     } else {
       $this->xfer_status = "FTP_FINISHED";
       $this->last_file_uploaded = $local_file;
       $this->error_code = 0;
     }
   } else {
       $this->error_code = 7;
       $this->error_message = "There is no current connection to an
FTP/FTPS server.";
  }
}

function put($remote_file, $local_file, $mode)
{
   if ($this->conn_id) {
     if (ftp_put($this->conn_id, $remote_file, $local_file, $mode)) {
       $this->xfer_status = FTP_FINISHED;
       $this->last_file_uploaded = $local_file;
       $this->error_code = 0;
     } else {
       $this->xfer_status = FTP_FAILED;
       $this->error_code = 11;
       $this->error_message = "Unable to upload file $file using
$mode.";
    }
  } else {
     $this->error_code = 7;
     $this->error_message = "There is no current connection to an
FTP/FTPS server.";
  }
}

I've gone through and checked what I think are all the obvious things.
I've made sure that the get commands are getting files that actually
exist; if the files didn't exist, however, I'd be getting "file does not
exist" errors (I know because I had some typos in my filenames).  On th
e put commands, I've verified that the files I'm trying to upload
actually exist on my local machine and that my program is in the correct
directory when attempting the transfer...and it is.

I'm currently in the process of getting in contact with the FTP server
admin to see if they can spot any error messages in the FTP server logs,
but given that the vendor is a fairly large company that may take
several days to actually track this person down.

At this point I'm trying to narrow down the problem to find out if it's
an issue with my code, the FTPS server, or with PHP's ftp functionality.
Does anyone have any ideas or suggestions? 

Thanks,
Tim





-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux