我目前有一个上传表单,通过其API将文件发送到Dropbox。执行cURL后接收文件的.php如下:
$localFile = $_FILES["file_key"]['tmp_name'];
$fp = fopen($localFile, 'r');
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_URL, 'https://content.dropboxapi.com/2/files/upload');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"authorization: Bearer MY-TOKEN",
"content-type: application/octet-stream",
"dropbox-api-arg: {\"path\": \"/tmp/a.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}"
));
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 86400); // 1 Day Timeout
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_exec ($ch);
这很完美,但我对第二行的fopen
感到困扰。这是一个不好的做法吗?即使是“只读”模式,我是否可以收到恶意文件并破坏我的系统?
这是非常安全的。 PHP将其作为纯数据读取,它不会尝试执行它。 curl
将简单地传递给DropBox API。那时它是DropBox的问题(如果他们执行用户上传的代码,那将是非常令人惊讶的,除非他们有严重的安全漏洞)。
是的,如果您使用只读模式,这是安全的,因为文件没有被执行,内容只是被读取。
这是正确的方法,如果你在Linux或MacOS *或* BSD,并不关心Windows兼容性,但我仍然想要你的代码:
如果你曾编写任何可能在Windows上运行的代码,养成使用fopen模式rb
而不是r
的习惯,因为Windows上的fopen r
模式可能会损坏二进制数据(并通过你的octet-stream
标题,它的二进制数据)和linux / macos / * BSD都以同样的方式对待r
和rb
模式,所以制作它
$fp = fopen($localFile, 'rb');
这条线
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"authorization: Bearer MY-TOKEN",
"content-type: application/octet-stream",
"dropbox-api-arg: {\"path\": \"/tmp/a.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}"
));
应该真的读
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"authorization: Bearer MY-TOKEN",
"content-type: application/octet-stream",
"dropbox-api-arg: " . json_encode(array(
'path' => '/tmp/a.txt',
'mode' => 'add',
'autorename' => true,
'mute' => false,
'strict_conflict' => false,
))
));
它更具可读性,更易维护,更容易修改。虽然我必须说把这些数据作为HTTP HEADER放在Dropbox的部分是一个糟糕的设计决定,但是在大多数文件系统标准的文件名中完全合法的HTTP头中的字符是非法的,这意味着我怀疑有可能制作一个有效的json包含一个有效的文件名,不能进行http-header编码..他们应该使用multipart / form-data,只需将文件和json作为2个sepatare表单变量imo。