|
@@ -21,6 +21,12 @@ class TxcosStorage extends Storage
|
|
|
private $point;
|
|
|
|
|
|
/**
|
|
|
+ * 账号 AppID
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ private $appid;
|
|
|
+
|
|
|
+ /**
|
|
|
* 存储空间名称
|
|
|
* @var string
|
|
|
*/
|
|
@@ -48,6 +54,7 @@ class TxcosStorage extends Storage
|
|
|
protected function initialize()
|
|
|
{
|
|
|
// 读取配置文件
|
|
|
+ $this->appid = sysconf('storage.txcos_appid');
|
|
|
$this->point = sysconf('storage.txcos_point');
|
|
|
$this->bucket = sysconf('storage.txcos_bucket');
|
|
|
$this->secretId = sysconf('storage.txcos_secret_id');
|
|
@@ -92,11 +99,11 @@ class TxcosStorage extends Storage
|
|
|
$data['q-ak'] = $token['q-ak'];
|
|
|
$data['q-key-time'] = $token['q-key-time'];
|
|
|
$data['q-signature'] = $token['d-signature'];
|
|
|
- $data['success_action_status'] = '200';
|
|
|
if (is_string($attname) && strlen($attname) > 0) {
|
|
|
$filename = urlencode($attname);
|
|
|
$data['Content-Disposition'] = "inline;filename={$filename}";
|
|
|
}
|
|
|
+ $data['success_action_status'] = '200';
|
|
|
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
|
|
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
|
|
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
|
@@ -125,7 +132,7 @@ class TxcosStorage extends Storage
|
|
|
public function del(string $name, bool $safe = false)
|
|
|
{
|
|
|
[$file] = explode('?', $name);
|
|
|
- $result = HttpExtend::request('DELETE', "http://{$this->bucket}.{$this->point}/{$file}", [
|
|
|
+ $result = HttpExtend::request('DELETE', "http://{$this->bucket}-{$this->appid}.{$this->point}/{$file}", [
|
|
|
'returnHeader' => true, 'headers' => $this->headerSign('DELETE', $file),
|
|
|
]);
|
|
|
return is_numeric(stripos($result, '204 No Content'));
|
|
@@ -140,7 +147,7 @@ class TxcosStorage extends Storage
|
|
|
public function has(string $name, bool $safe = false)
|
|
|
{
|
|
|
$file = $this->delSuffix($name);
|
|
|
- $result = HttpExtend::request('HEAD', "http://{$this->bucket}.{$this->point}/{$file}", [
|
|
|
+ $result = HttpExtend::request('HEAD', "http://{$this->bucket}-{$this->appid}.{$this->point}/{$file}", [
|
|
|
'returnHeader' => true, 'headers' => $this->headerSign('HEAD', $name),
|
|
|
]);
|
|
|
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
|
@@ -190,8 +197,8 @@ class TxcosStorage extends Storage
|
|
|
*/
|
|
|
public function upload(): string
|
|
|
{
|
|
|
- $http = $this->app->request->isSsl() ? 'https' : 'http';
|
|
|
- return "{$http}://{$this->bucket}.{$this->point}";
|
|
|
+ $protocol = $this->app->request->isSsl() ? 'https' : 'http';
|
|
|
+ return "{$protocol}://{$this->bucket}-{$this->appid}.{$this->point}";
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -209,23 +216,16 @@ class TxcosStorage extends Storage
|
|
|
$siteurl = $this->url($name, false, $attname);
|
|
|
$policy = json_encode([
|
|
|
'expiration' => date('Y-m-d\TH:i:s.000\Z', $endTimestamp),
|
|
|
- 'conditions' => [
|
|
|
- ['q-sign-algorithm' => 'sha1'],
|
|
|
- ['q-ak' => $this->secretId],
|
|
|
- ['q-sign-time' => $keyTime]
|
|
|
- ],
|
|
|
+ 'conditions' => [['q-sign-algorithm' => 'sha1'], ['q-ak' => $this->secretId], ['q-sign-time' => $keyTime]],
|
|
|
]);
|
|
|
- $data = [
|
|
|
+ return [
|
|
|
'policy' => base64_encode($policy),
|
|
|
'q-sign-algorithm' => 'sha1',
|
|
|
'q-ak' => $this->secretId,
|
|
|
'q-key-time' => $keyTime,
|
|
|
- 'siteurl' => $siteurl
|
|
|
+ 'q-signature' => hash_hmac('sha1', sha1($policy), hash_hmac('sha1', $keyTime, $this->secretKey)),
|
|
|
+ 'siteurl' => $siteurl,
|
|
|
];
|
|
|
- $signKey = hash_hmac('sha1', $keyTime, $this->secretKey);
|
|
|
- $stringToSign = sha1($policy);
|
|
|
- $data['q-signature'] = hash_hmac('sha1', $stringToSign, $signKey);
|
|
|
- return $data;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -237,33 +237,33 @@ class TxcosStorage extends Storage
|
|
|
*/
|
|
|
private function headerSign(string $method, string $soruce, array $header = []): array
|
|
|
{
|
|
|
- // 1.生成KeyTime
|
|
|
+ // 1.生成 KeyTime
|
|
|
$startTimestamp = time();
|
|
|
$endTimestamp = $startTimestamp + 3600;
|
|
|
$keyTime = "{$startTimestamp};{$endTimestamp}";
|
|
|
// 2.生成 SignKey
|
|
|
$signKey = hash_hmac('sha1', $keyTime, $this->secretKey);
|
|
|
- // 3.生成UrlParamList,HttpParameters
|
|
|
- list($parse_url, $urlParamList, $httpParameters) = [parse_url($soruce), '', ''];
|
|
|
+ // 3.生成 UrlParamList, HttpParameters
|
|
|
+ [$parse_url, $urlParamList, $httpParameters] = [parse_url($soruce), '', ''];
|
|
|
if (!empty($parse_url['query'])) {
|
|
|
parse_str($parse_url['query'], $params);
|
|
|
uksort($params, 'strnatcasecmp');
|
|
|
$urlParamList = join(';', array_keys($params));
|
|
|
$httpParameters = http_build_query($params);
|
|
|
}
|
|
|
- // 4.生成HeaderList,HttpHeaders
|
|
|
- list($headerList, $httpHeaders) = ['', ''];
|
|
|
+ // 4.生成 HeaderList, HttpHeaders
|
|
|
+ [$headerList, $httpHeaders] = ['', ''];
|
|
|
if (!empty($header)) {
|
|
|
uksort($header, 'strnatcasecmp');
|
|
|
$headerList = join(';', array_keys($header));
|
|
|
$httpHeaders = http_build_query($header);
|
|
|
}
|
|
|
- // 5.生成HttpString
|
|
|
+ // 5.生成 HttpString
|
|
|
$httpString = strtolower($method) . "\n/{$parse_url['path']}\n{$httpParameters}\n{$httpHeaders}\n";
|
|
|
- // 6.生成StringToSign
|
|
|
+ // 6.生成 StringToSign
|
|
|
$httpStringSha1 = sha1($httpString);
|
|
|
$stringToSign = "sha1\n{$keyTime}\n{$httpStringSha1}\n";
|
|
|
- // 7.生成Signature
|
|
|
+ // 7.生成 Signature
|
|
|
$signature = hash_hmac('sha1', $stringToSign, $signKey);
|
|
|
// 8.生成签名
|
|
|
$signArray = [
|
|
@@ -273,11 +273,42 @@ class TxcosStorage extends Storage
|
|
|
'q-key-time' => $keyTime,
|
|
|
'q-header-list' => $headerList,
|
|
|
'q-url-param-list' => $urlParamList,
|
|
|
- 'q-signature' => $signature
|
|
|
+ 'q-signature' => $signature,
|
|
|
];
|
|
|
$header['Authorization'] = urldecode(http_build_query($signArray));
|
|
|
foreach ($header as $key => $value) $header[$key] = ucfirst($key) . ": {$value}";
|
|
|
return array_values($header);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 腾讯云COS存储区域
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function region()
|
|
|
+ {
|
|
|
+ return [
|
|
|
+ 'cos.ap-beijing-1.myqcloud.com' => '中国大陆 公有云地域 北京一区(已售罄)',
|
|
|
+ 'cos.ap-beijing.myqcloud.com' => '中国大陆 公有云地域 北京',
|
|
|
+ 'cos.ap-nanjing.myqcloud.com' => '中国大陆 公有云地域 南京',
|
|
|
+ 'cos.ap-shanghai.myqcloud.com' => '中国大陆 公有云地域 上海',
|
|
|
+ 'cos.ap-guangzhou.myqcloud.com' => '中国大陆 公有云地域 广州',
|
|
|
+ 'cos.ap-chengdu.myqcloud.com' => '中国大陆 公有云地域 成都',
|
|
|
+ 'cos.ap-chongqing.myqcloud.com' => '中国大陆 公有云地域 重庆',
|
|
|
+ 'cos.ap-shenzhen-fsi.myqcloud.com' => '中国大陆 金融云地域 深圳金融',
|
|
|
+ 'cos.ap-shanghai-fsi.myqcloud.com' => '中国大陆 金融云地域 上海金融',
|
|
|
+ 'cos.ap-beijing-fsi.myqcloud.com' => '中国大陆 金融云地域 北京金融',
|
|
|
+ 'cos.ap-hongkong.myqcloud.com' => '亚太地区 公有云地域 中国香港',
|
|
|
+ 'cos.ap-singapore.myqcloud.com' => '亚太地区 公有云地域 新加坡',
|
|
|
+ 'cos.ap-mumbai.myqcloud.com' => '亚太地区 公有云地域 孟买',
|
|
|
+ 'cos.ap-seoul.myqcloud.com' => '亚太地区 公有云地域 首尔',
|
|
|
+ 'cos.ap-bangkok.myqcloud.com' => '亚太地区 公有云地域 曼谷',
|
|
|
+ 'cos.ap-tokyo.myqcloud.com' => '亚太地区 公有云地域 东京',
|
|
|
+ 'cos.na-siliconvalley.myqcloud.com' => '北美地区 公有云地域 硅谷',
|
|
|
+ 'cos.na-ashburn.myqcloud.com' => '北美地区 公有云地域 弗吉尼亚',
|
|
|
+ 'cos.na-toronto.myqcloud.com' => '北美地区 公有云地域 多伦多',
|
|
|
+ 'cos.eu-frankfurt.myqcloud.com' => '欧洲地区 公有云地域 法兰克福',
|
|
|
+ 'cos.eu-moscow.myqcloud.com' => '欧洲地区 公有云地域 莫斯科 ',
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
}
|