使用PHP Curl的FTPS获得部分下载(FTPS with PHP Curl getting partial download)
我有一个问题,使用php curl在ftps上使用隐式ssl检索文件(如下所述: ftp_ssl_connect,隐式ftp超过tls )。 问题是有时候 - 大概有5%的时间,我最终会部分下载。
我的班级或多或少地改编自改编自Nico Westerdale的答案,以下是相关方法:
class ftps { private $server; private $username; private $password; private $curlhandle; public $dir = '/'; public function __construct($server, $username, $password) { $this->server = $server; $this->username = $username; $this->password = $password; $this->curlhandle = curl_init(); } private function common($remote) { curl_reset($this->curlhandle); curl_setopt($this->curlhandle, CURLOPT_URL, 'ftps://' . $this->server . '/' . $remote); curl_setopt($this->curlhandle, CURLOPT_USERPWD, $this->username . ':' . $this->password); curl_setopt($this->curlhandle, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($this->curlhandle, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($this->curlhandle, CURLOPT_FTP_SSL, CURLFTPSSL_TRY); curl_setopt($this->curlhandle, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS); return $this->curlhandle; } public function download($filepath, $local = false) { $filename = basename($filepath); $remote = dirname($filepath); if ($remote == '.') { $remote = $this->dir; } if ($local === false) { $local = $filename; } if ($fp = fopen($local, 'w')) { $this->curlhandle = self::common($remote . $filename); curl_setopt($this->curlhandle, CURLOPT_UPLOAD, 0); curl_setopt($this->curlhandle, CURLOPT_FILE, $fp); curl_exec($this->curlhandle); if (curl_error($this->curlhandle)) { return false; } else { return $local; } } return false; } }
我使用它是这样的:
$ftps = new ftps('example.com','john_doe','123456'); $ftps->download('remote_filename','local_filename');
正如我上面提到的, 除了大约5%的时间结果是部分下载的文件以外 ,这个工作几乎完美无缺。 然后我检查远程服务器,并且能够验证文件确实存在于其中 - 再次尝试脚本并且它总是在第二次尝试时获取整个文件。
什么会导致使用像这样的卷曲的间歇性问题? 我的下一步行动是实施某种校验和,并继续下载尝试,直到所有的哈希结果,但这种感觉更像是一种琐碎的解决方法,而不是真正的解决方案,并且很高兴知道问题的实际根源。
I'm having an issue retrieving a file using php curl over ftps with implicit ssl (as discussed here: ftp_ssl_connect with implicit ftp over tls). The problem is that sometimes - probably 5% of the time, I end up with a partial download.
My class is more or less adapted from adapted from Nico Westerdale's answer and here are the relevant methods:
class ftps { private $server; private $username; private $password; private $curlhandle; public $dir = '/'; public function __construct($server, $username, $password) { $this->server = $server; $this->username = $username; $this->password = $password; $this->curlhandle = curl_init(); } private function common($remote) { curl_reset($this->curlhandle); curl_setopt($this->curlhandle, CURLOPT_URL, 'ftps://' . $this->server . '/' . $remote); curl_setopt($this->curlhandle, CURLOPT_USERPWD, $this->username . ':' . $this->password); curl_setopt($this->curlhandle, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($this->curlhandle, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($this->curlhandle, CURLOPT_FTP_SSL, CURLFTPSSL_TRY); curl_setopt($this->curlhandle, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS); return $this->curlhandle; } public function download($filepath, $local = false) { $filename = basename($filepath); $remote = dirname($filepath); if ($remote == '.') { $remote = $this->dir; } if ($local === false) { $local = $filename; } if ($fp = fopen($local, 'w')) { $this->curlhandle = self::common($remote . $filename); curl_setopt($this->curlhandle, CURLOPT_UPLOAD, 0); curl_setopt($this->curlhandle, CURLOPT_FILE, $fp); curl_exec($this->curlhandle); if (curl_error($this->curlhandle)) { return false; } else { return $local; } } return false; } }
I'm using it like this:
$ftps = new ftps('example.com','john_doe','123456'); $ftps->download('remote_filename','local_filename');
As I mentioned above, this works almost flawlessly except about 5% of the time the result is a partially downloaded file. I then check the remote server and am able to verify that the file is indeed there in it's entirety - try the script again and it invariably gets the whole file on a second attempt.
What would cause an intermittent issue using curl like this? My next move would be to implement some kind of checksum and continue download attempts until everything hashes but this feels more like a sloppy workaround than a true solution and it would be nice to know the actual root of the problem.
原文:https://stackoverflow.com/questions/47001712
最满意答案
File dir = new File("/path/to/dir"); dir.canRead(); dir.canWrite(); ...
File dir = new File("/path/to/dir"); dir.canRead(); dir.canWrite(); ...
相关问答
更多-
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
我认为这可以使用jcifs完成,但您可能需要用户的密码。 是windows或者unix文件系统吗? 对于Windows,您可以调用cacls c:\path并解析usersname的输出。 但这有点难看。 I think this can be done with jcifs, but you may need the password of the user. Is a windows oder unix filesystem? For windows you may call cacls c:\path ...
-
我相信您需要在添加规则后使用路径和DirectorySecurity变量调用Directory.SetAccessControl 。 I believe you need to call Directory.SetAccessControl using the path and your DirectorySecurity variable after you add rules.
-
出于显而易见的原因,你不能使用os lib; 但你可以使用测试 。 我做了一个关于如何使用它的2分钟快速示例。 from fabric.api import env, task, run, sudo as _sudo, settings, hide env.user = 'vagrant' env.key_filename = '~/.vagrant/machines/default/virtualbox/private_key' env.host_string = '127.0.0.1' env.por ...
-
使用Linux Centos上的第二个用户权限创建文件夹/文件(Creates folder/file with second user permission on linux Centos)[2023-06-26]
使用 粘点 文件夹上的setguid ( s属性)属性。 它确保在其中创建的所有新文件或文件夹都将继承它 权利 组ID。 例如: mkdir test sudo chown jask:root test sudo chmod g+s test touch test/test_file ll test/ -rw-rw-r-- 1 jask root 0 15. pro 11.46 test_file 同样,你可以使用setuid chmod u+s来继承owner(uid)。 当不在文件夹中但 ... -
如何使用java向文件和文件夹授予权限700和770(How to give permission 700 and 770 to file & folder using java)[2019-09-12]
试试吧 txtFilePath.toFile().setExecutable(true); txtFilePath.toFile().setReadable(true); txtFilePath.toFile().setWritable(true); 否则你可以在下面查看 我如何以编程方式更改文件权限? This code Will be working, if you want to give 770 permission to a file - Setper ... -
ACL中未提及的任何人的默认权限是“无权访问”( 空的DACL不授予访问权限)。 因此,请阻止文件夹从其父级继承安全性,并仅为UserA分配权限。 (当然,这并不妨碍管理员获取所有权,然后为自己授予权限。没有什么可以防止这种情况) 例如,创建一个名为C:\FruitBat的目录,只能由用户DOMAIN\User1访问: System.Security.AccessControl.DirectorySecurity dacl = new System.Security.AccessControl.Direct ...
-
File dir = new File("/path/to/dir"); dir.canRead(); dir.canWrite(); ... File dir = new File("/path/to/dir"); dir.canRead(); dir.canWrite(); ...
-
主要技巧是创建一个指向\\ ImageServer \的虚拟目录。 我在这里找到了一篇文章。 虽然是关于IIS 6我认为在IIS 7上工作也不会有问题。 The main trick is to create a virtual dir which points at \\ImageServer\. I found an article here. Although is about IIS 6 I think it won't be a problem to work on IIS 7 also.
-
您需要了解的主要过程是为文件或目录添加/修改ACLS。 首先,要获取为目录设置的权限集,可以使用DirectoryInfo.GetAccessControl()方法(文件将具有类似的FileInfo.GetAccessControl() )或静态Directory.GetAccessControl() 。 这将为您提供一个对象,其中包含目录的ACL和其他安全信息。 var parentDir = new DirectoryInfo(@"c:\some\directory"); var parentAc = ...