<?php
/* =================================================================================
 * License: GPL-2.0 license
 * Author: 众产®  https://ciy.cn/code
 * Version: 0.1.2
====================================================================================*/

namespace web\admin;

class upload {
    public static function json_upload() {
        $rsuser = verifyfast();
        error_reporting(E_ALL ^ E_NOTICE);
        $uploadcfg['exts'] = array(
            'jpe', 'jpg', 'jpeg', 'gif', 'png', 'ai', 'bmp', 'psb', 'psd', 'tif', 'svg', 'webp',
            'zip', '7z', 'rar', 'tar', 'arj', 'iso', 'cab', 'gz', 'glb',
            'txt', 'csv', 'doc', 'docx', 'pps', 'ppt', 'pptx', 'pdf', 'wps', 'wpt', 'xls', 'xlsx', 'xml', 'et', 'ett',
            'avi', 'mp4', 'mp3', 'swf', 'flv', 'f4v', 'm4v', 'wma', 'rm', 'rmvb', '3gp', 'ts', 'mts', 'vob', 'mpg', 'mpeg', 'mov', 'wmv', 'wav',
            'bak', 'cad', 'chm', 'log', 'ai', 'ico'
        );
        $uploadcfg['noexts'] = array('goc', 'php', 'php3', 'php4', 'phtm', 'phtml', 'php5', 'js', 'html', 'htm', 'sh', 'so'); //建议nginx部署使用。
        $uploadcfg['checkext'] = 'exts'; //扩展名白名单exts、黑名单noexts
        $path = get('pathfile');
        $rep = get('rep');
        if(empty($path))
            return errjson('缺少参数pathfile');
        if (count($_FILES) == 0)
            return errjson('没有文件上传');
        $file = reset($_FILES);
        if ($file['error'] > 0)
            return errjson(\ciy\upload::UploadError($file['error']));
        list($name, $extfile) = \ciy\upload::Fileext($path);
        if ($uploadcfg['checkext'] == 'exts') {
            if (!in_array($extfile, $uploadcfg['exts']))
                return errjson("不允许上传{$extfile}类型文件");
        } else {
            if (in_array($extfile, $uploadcfg['noexts']))
                return errjson("禁止上传{$extfile}类型文件");
        }
        $ret = \ciy\upload::SaveUploadFile($path, $file, $rep == 'true');
        if (is_array($ret))
            return succjson($ret);
        return errjson($ret);
    }
    public static function json_yunsync() {
        if (count($_FILES) == 0)
            return errjson('没有文件上传');
        $file = reset($_FILES);
        if ($file['error'] > 0)
            return errjson('上传参数出错:' . $file['error']);
        //上传临时文件,通过http put 上传到s3
        $post = new \ciy\post();
        $headers = json_decode($post->get('headers'), true);
        $url = $post->get('url');
        $http = new \ciy\http();
        foreach($headers as $key => $value){
            $http->set_header($key,$value);
        }
        $http->set_method('PUT');
        $http->upfile($url, $file['tmp_name']);
        $statcode = $http->get_statcode();
        if($statcode == 200)
            return succjson();
        $data = $http->get_data();
        $ind = strpos($data,'error:');
        if($ind !== false)
            return errjson(substr($data, $ind + 6));
        return errjson('code[' . $statcode . ']');
    }
    public static function json_s3() {
        //根据token的ABC决定，用哪个key，包含access/key/region/bucket/endpoint
        //存到目录和文件，由js决定，ud/xxx/xxx.jpg
        $path = get('pathfile'); //    s0/2/2024/0913/demo/65631_7101.jpg
        $storselect = get('storselect'); //   A
        $cfg = webini('s3' . $storselect);
        if(is_string($cfg))
            return errjson($cfg);
        $objectKey = 'ud/' . $path;
        $sha256 = 'UNSIGNED-PAYLOAD';

        $zdate = gmdate('Ymd\THis\Z');
        $shortDate = substr($zdate, 0, 8);

        $dateKey = hash_hmac('sha256', $shortDate, 'AWS4' . $cfg['secret'], true);

        $regionKey = hash_hmac('sha256', $cfg['region'], $dateKey, true);
        $serviceKey = hash_hmac('sha256', 's3', $regionKey, true);
        $signingKey = hash_hmac('sha256', 'aws4_request', $serviceKey, true);

        $canonicalUri = '/' . $cfg['bucket'] . '/' . $objectKey;
        $canonicalQueryString = '';
        $canonicalHeaders = 'host:' . $cfg['endpoint'] . "\n" .
            'x-amz-acl:' . $cfg['acl'] . "\n" .
            'x-amz-content-sha256:' . $sha256 . "\n" .
            'x-amz-date:' . $zdate . "\n";
        $signedHeaders = 'host;x-amz-acl;x-amz-content-sha256;x-amz-date';
        $canonicalRequest = 'PUT' . "\n" .
            $canonicalUri . "\n" .
            $canonicalQueryString . "\n" .
            $canonicalHeaders . "\n" .
            $signedHeaders . "\n" .
            $sha256;

        $stringToSign = 'AWS4-HMAC-SHA256' . "\n" .
            $zdate . "\n" .
            $shortDate . '/' . $cfg['region'] . '/s3/aws4_request' . "\n" .
            hash('sha256', $canonicalRequest);

        $signature = hash_hmac('sha256', $stringToSign, $signingKey);

        $authorizationHeader = 'AWS4-HMAC-SHA256 Credential=' . $cfg['access'] . '/' . $shortDate . '/' . $cfg['region'] . '/s3/aws4_request, ' .
            'SignedHeaders=' . $signedHeaders . ', ' .
            'Signature=' . $signature;

        $ret['method'] = 'PUT';
        $ret['url'] = 'https://' . $cfg['endpoint'] . '/' . $cfg['bucket'] . '/' . $objectKey;
        $ret['syncurl'] = 'https://up.ciy.cn/up/?json=true&func=yunsync';
        $ret['headers'] = array();
        $ret['headers']['Authorization'] = $authorizationHeader;
        $ret['headers']['x-amz-acl'] = $cfg['acl'];
        $ret['headers']['x-amz-content-sha256'] = $sha256;
        $ret['headers']['x-amz-date'] = $zdate;
        //直传后返回url
        return succjson($ret);
    }
}
