From 75471ecd99d1b3583a2c87dd71b56a72358de4f2 Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Sun, 30 Jun 2019 20:41:08 +0000 Subject: [PATCH] Reuse FTP connection if possible --- lib/fetch.php | 36 +++++------------- lib/FtpConnection.php | 55 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/lib/FtpConnection.php b/lib/FtpConnection.php new file mode 100644 index 0000000..94f9ebd --- /dev/null +++ b/lib/FtpConnection.php @@ -0,0 +1,55 @@ +<?php +class FtpConnection { + private static $instances = []; + private $connection; + + static function create(string $host, int $port=21, string $user='anonymous', string $pass='anonymous') : FtpConnection { + $key = $host."\0".$port."\0".$user."\0".$pass; + if(!isset(self::$instances[$key])) { + self::$instances[$key] = new FtpConnection($host, $port, $user, $pass); + } + return self::$instances[$key]; + } + + private function __construct(string $host, int $port=21, string $user, string $pass) { + $this->connection = ftp_connect($host, $port, 10); + if($this->connection === FALSE) { + throw new Exception('FTP connection failed'); + } + if(!ftp_login($this->connection, $user, $pass)) { + throw new Exception('FTP login failed'); + } + if(!ftp_pasv($this->connection, TRUE)) { + throw new Exception('Passive FTP request failed'); + } + } + + public function __destruct() { + ftp_close($this->connection); + } + + public function size(string $file) : int { + $remoteSize = ftp_size($this->connection, $file); + if($remoteSize < 0) { + throw new Exception('FTP file size fetch failed'); + } + return $remoteSize; + } + + + public function mdtm(string $file) : int { + $remoteTime = ftp_mdtm($this->connection, $file); + if($remoteTime < 0) { + throw new Exception('FTP modification time fetch failed'); + } + return $remoteTime; + } + + public function get(string $local_file, string $remote_file, int $mode = FTP_BINARY, int $resumepos = 0) : bool { + $result = ftp_get($this->connection, $local_file, $remote_file, $mode, $resumepos); + if($result === FALSE) { + throw new Exception('FTP file get failed'); + } + return $result; + } +} diff --git a/lib/fetch.php b/lib/fetch.php index bb36a1a..57ffaaa 100644 --- a/lib/fetch.php +++ b/lib/fetch.php @@ -1,4 +1,6 @@ <?php +require_once(__DIR__.'/FtpConnection.php'); + function ftp_fetch_if_newer($url, $file = NULL) { $url = parse_url($url); if(!isset($url['scheme']) || $url['scheme'] != 'ftp') { @@ -30,24 +32,9 @@ $localSize = filesize($file); } - $ftp = ftp_connect($url['host'], $url['port'], 10); - if($ftp === FALSE) { - throw new Exception('FTP connection failed'); - } - if(!ftp_login($ftp, $url['user'], $url['pass'])) { - throw new Exception('FTP login failed'); - } - if(!ftp_pasv($ftp, TRUE)) { - throw new Exception('Passive FTP request failed'); - } - $remoteSize = ftp_size($ftp, $url['path']); - if($remoteSize < 0) { - throw new Exception('FTP file size fetch failed'); - } - $remoteTime = ftp_mdtm($ftp, $url['path']); - if($remoteTime < 0) { - throw new Exception('FTP modification time fetch failed'); - } + $ftp = FtpConnection::create($url['host'], $url['port'], $url['user'], $url['pass']); + $remoteSize = $ftp->size($url['path']); + $remoteTime = $ftp->mdtm($url['path']); $updated = FALSE; @@ -55,16 +42,13 @@ if(file_exists($file.'.tmp')) { unlink($file.'.tmp'); } - if(ftp_get($ftp, $file.'.tmp', $url['path'], FTP_BINARY)) { - touch($file.'.tmp', $remoteTime); - if(!rename($file.'.tmp', $file)) { - throw new Exception('Temporary file rename failed'); - } - $updated = TRUE; + $ftp->get($file.'.tmp', $url['path'], FTP_BINARY); + touch($file.'.tmp', $remoteTime); + if(!rename($file.'.tmp', $file)) { + throw new Exception('Temporary file rename failed'); } + $updated = TRUE; } - - ftp_close($ftp); return $updated; } -- Gitblit v1.9.1