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