|
...
|
...
|
@@ -66,60 +66,83 @@ class FileManageController extends BaseController |
|
|
|
{
|
|
|
|
// 检查参数
|
|
|
|
if (!isset($this->param['path']) || empty($this->param['path'])) {
|
|
|
|
$this->response('参数错误', Code::SYSTEM_ERROR);
|
|
|
|
$this->response('参数错误:path 参数缺失或为空', Code::SYSTEM_ERROR);
|
|
|
|
}
|
|
|
|
// 获取文件名
|
|
|
|
// 获取文件名和完整 URL
|
|
|
|
$username = basename($this->param['path']);
|
|
|
|
$parsed_url = parse_url($this->param['path']);
|
|
|
|
// 构造文件 URL
|
|
|
|
$fileUrl = isset($parsed_url['scheme'])
|
|
|
|
? $this->param['path']
|
|
|
|
: 'https://file.globalso.com' . $this->param['path'];
|
|
|
|
// 初始化 cURL
|
|
|
|
// 使用 cURL 获取文件头信息
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $fileUrl);
|
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
|
|
|
|
curl_setopt($ch, CURLOPT_HEADER, false);
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 不直接输出,而是返回结果
|
|
|
|
curl_setopt($ch, CURLOPT_HEADER, true); // 获取响应头
|
|
|
|
curl_setopt($ch, CURLOPT_NOBODY, true); // 只请求头部,不下载实际文件
|
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
|
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时时间
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用 SSL 验证
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
|
|
curl_setopt($ch, CURLOPT_BUFFERSIZE, 8192); // 设置缓冲区大小
|
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 设置超时时间
|
|
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时时间
|
|
|
|
$response = curl_exec($ch);
|
|
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
$fileSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
|
|
|
|
curl_close($ch);
|
|
|
|
// 检查文件大小和状态码
|
|
|
|
if ($httpCode != 200 || $fileSize <= 0) {
|
|
|
|
$this->response('无法获取文件信息或文件不存在', Code::SYSTEM_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置为分块输出
|
|
|
|
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
|
|
|
|
echo $data;
|
|
|
|
flush(); // 强制刷新缓冲区
|
|
|
|
return strlen($data);
|
|
|
|
});
|
|
|
|
// 检查文件头信息
|
|
|
|
$headers = get_headers($fileUrl, 1);
|
|
|
|
if ($headers === false || !isset($headers['Content-Length'])) {
|
|
|
|
$this->response('无法获取文件信息', Code::SYSTEM_ERROR);
|
|
|
|
// 获取文件类型
|
|
|
|
$contentType = 'application/octet-stream'; // 默认类型为二进制流
|
|
|
|
if (preg_match('/Content-Type: (.+)/i', $response, $matches)) {
|
|
|
|
$contentType = $matches[1];
|
|
|
|
}
|
|
|
|
// 设置响应头
|
|
|
|
header('Content-Description: File Transfer');
|
|
|
|
header('Content-Type: ' . ($headers['Content-Type'] ?? 'application/octet-stream'));
|
|
|
|
header('Content-Type: ' . $contentType);
|
|
|
|
header('Content-Disposition: attachment; filename="' . $username . '"');
|
|
|
|
header('Content-Length: ' . $headers['Content-Length']);
|
|
|
|
header('Content-Length: ' . $fileSize);
|
|
|
|
header('Cache-Control: must-revalidate');
|
|
|
|
header('Pragma: public');
|
|
|
|
header('Expires: 0');
|
|
|
|
// 清空输出缓冲区
|
|
|
|
while (ob_get_level() > 0) {
|
|
|
|
ob_end_clean();
|
|
|
|
}
|
|
|
|
// 初始化 cURL 下载文件
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $fileUrl);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // 直接输出内容
|
|
|
|
curl_setopt($ch, CURLOPT_HEADER, false);
|
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
|
|
|
|
curl_setopt($ch, CURLOPT_BUFFERSIZE, 8192); // 设置缓冲区大小
|
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 300); // 设置超时时间
|
|
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时时间
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用 SSL 验证
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
|
|
// 分块输出文件内容
|
|
|
|
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
|
|
|
|
echo $data;
|
|
|
|
flush(); // 强制输出缓冲
|
|
|
|
return strlen($data);
|
|
|
|
});
|
|
|
|
// 执行 cURL
|
|
|
|
ob_end_clean(); // 清空之前的输出缓冲区
|
|
|
|
curl_exec($ch);
|
|
|
|
|
|
|
|
// 检查 cURL 错误
|
|
|
|
if (curl_errno($ch)) {
|
|
|
|
// 检查 cURL 错误或 HTTP 状态码
|
|
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if (curl_errno($ch) || $httpCode != 200) {
|
|
|
|
$errorMsg = curl_errno($ch)
|
|
|
|
? 'cURL 错误: ' . curl_error($ch)
|
|
|
|
: 'HTTP 错误: ' . $httpCode;
|
|
|
|
curl_close($ch);
|
|
|
|
$this->response('文件下载失败: ' . curl_error($ch), Code::SYSTEM_ERROR);
|
|
|
|
$this->response('文件下载失败: ' . $errorMsg, Code::SYSTEM_ERROR);
|
|
|
|
}
|
|
|
|
// 关闭 cURL
|
|
|
|
curl_close($ch);
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function upload(Request $request, FileManage $fileManage){
|
|
|
|
$request->validate([
|
|
|
|
'file'=>['required'],
|
...
|
...
|
|