Commit 33ba0c0f authored by 刘小敏's avatar 刘小敏

添加obs插件

parent f77ce5a6
{"files":["public\/assets\/addons\/hwobs\/js\/spark.js"],"license":"regular","licenseto":"114257","licensekey":"PU7pt6InOcy5uBLx arPepxrkrAYAk+oFniQY9g==","domains":["njing.net"],"licensecodes":[],"validations":["9fcdcf25151a9aa634504b416df25bf5"]}
\ No newline at end of file
<?php
namespace addons\hwobs;
use addons\hwobs\library\Auth;
use Obs\ObsClient;
use think\Addons;
use think\App;
use think\Loader;
/**
* 华为云存储插件
*/
class Hwobs extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
return true;
}
/**
* 判断是否来源于API上传
*/
public function moduleInit($request)
{
$config = $this->getConfig();
$module = strtolower($request->module());
if ($module == 'api' && ($config['apiupload'] ?? 0) &&
strtolower($request->controller()) == 'common' &&
strtolower($request->action()) == 'upload') {
request()->param('isApi', true);
App::invokeMethod(["\\addons\\hwobs\\controller\\Index", "upload"], ['isApi' => true]);
}
}
/**
* 上传配置初始化
*/
public function uploadConfigInit(&$upload)
{
$config = $this->getConfig();
$module = request()->module();
$module = $module ? strtolower($module) : 'index';
$data = ['deadline' => time() + $config['expire']];
$signature = hash_hmac('sha1', json_encode($data), $config['secretKey'], true);
$token = '';
if (Auth::isModuleAllow()) {
$token = $config['accessKey'] . ':' . base64_encode($signature) . ':' . base64_encode(json_encode($data));
}
$multipart = [
'hwobstoken' => $token
];
$upload = array_merge($upload, [
'cdnurl' => $config['cdnurl'],
'uploadurl' => $config['uploadmode'] == 'client' ? $config['uploadurl'] : addon_url('hwobs/index/upload', [], false, true),
'uploadmode' => $config['uploadmode'],
'bucket' => $config['bucket'],
'maxsize' => $config['maxsize'],
'mimetype' => $config['mimetype'],
'savekey' => $config['savekey'],
'chunking' => (bool)($config['chunking'] ?? $upload['chunking']),
'chunksize' => (int)($config['chunksize'] ?? $upload['chunksize']),
'multipart' => $multipart,
'storage' => $this->getName(),
'multiple' => (bool)$config['multiple'],
]);
}
/**
* 附件删除后
*/
public function uploadDelete($attachment)
{
$config = $this->getConfig();
if ($attachment['storage'] == 'hwobs' && isset($config['syncdelete']) && $config['syncdelete']) {
try {
//删除云储存文件
$config = get_addon_config('hwobs');
$obs = new ObsClient([
'key' => $config['accessKey'],
'secret' => $config['secretKey'],
'endpoint' => $config['endpoint']
]);
$result = $obs->deleteObject([
'Bucket' => $config['bucket'],
'Key' => ltrim($attachment->url, '/')
]);
} catch (\Exception $e) {
return false;
}
//如果是服务端中转,还需要删除本地文件
//if ($config['uploadmode'] == 'server') {
// $filePath = ROOT_PATH . 'public' . str_replace('/', DS, $attachment->url);
// if ($filePath) {
// @unlink($filePath);
// }
//}
}
return true;
}
/**
* 渲染命名空间配置信息
*/
public function appInit()
{
if (!class_exists('\Obs\ObsClient')) {
Loader::addNamespace('Obs', $this->addons_path . str_replace('/', DS, 'library/Obs/'));
}
}
}
(function(factory){if(typeof exports==="object"){module.exports=factory()}else if(typeof define==="function"&&define.amd){define(factory)}else{var glob;try{glob=window}catch(e){glob=self}glob.SparkMD5=factory()}})(function(undefined){"use strict";var add32=function(a,b){return a+b&4294967295},hex_chr=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function cmn(q,a,b,x,s,t){a=add32(add32(a,q),add32(x,t));return add32(a<<s|a>>>32-s,b)}function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a+=(b&c|~b&d)+k[0]-680876936|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[1]-389564586|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[2]+606105819|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[3]-1044525330|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[4]-176418897|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[5]+1200080426|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[6]-1473231341|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[7]-45705983|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[8]+1770035416|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[9]-1958414417|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[10]-42063|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[11]-1990404162|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[12]+1804603682|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[13]-40341101|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[14]-1502002290|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[15]+1236535329|0;b=(b<<22|b>>>10)+c|0;a+=(b&d|c&~d)+k[1]-165796510|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[6]-1069501632|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[11]+643717713|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[0]-373897302|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[5]-701558691|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[10]+38016083|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[15]-660478335|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[4]-405537848|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[9]+568446438|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[14]-1019803690|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[3]-187363961|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[8]+1163531501|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[13]-1444681467|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[2]-51403784|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[7]+1735328473|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[12]-1926607734|0;b=(b<<20|b>>>12)+c|0;a+=(b^c^d)+k[5]-378558|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[8]-2022574463|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[11]+1839030562|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[14]-35309556|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[1]-1530992060|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[4]+1272893353|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[7]-155497632|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[10]-1094730640|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[13]+681279174|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[0]-358537222|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[3]-722521979|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[6]+76029189|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[9]-640364487|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[12]-421815835|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[15]+530742520|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[2]-995338651|0;b=(b<<23|b>>>9)+c|0;a+=(c^(b|~d))+k[0]-198630844|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[7]+1126891415|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[14]-1416354905|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[5]-57434055|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[12]+1700485571|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[3]-1894986606|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[10]-1051523|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[1]-2054922799|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[8]+1873313359|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[15]-30611744|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[6]-1560198380|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[13]+1309151649|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[4]-145523070|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[11]-1120210379|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[2]+718787259|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[9]-343485551|0;b=(b<<21|b>>>11)+c|0;x[0]=a+x[0]|0;x[1]=b+x[1]|0;x[2]=c+x[2]|0;x[3]=d+x[3]|0}function md5blk(s){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24)}return md5blks}function md5blk_array(a){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=a[i]+(a[i+1]<<8)+(a[i+2]<<16)+(a[i+3]<<24)}return md5blks}function md51(s){var n=s.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk(s.substring(i-64,i)))}s=s.substring(i-64);length=s.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<length;i+=1){tail[i>>2]|=s.charCodeAt(i)<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function md51_array(a){var n=a.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk_array(a.subarray(i-64,i)))}a=i-64<n?a.subarray(i-64):new Uint8Array(0);length=a.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<length;i+=1){tail[i>>2]|=a[i]<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function rhex(n){var s="",j;for(j=0;j<4;j+=1){s+=hex_chr[n>>j*8+4&15]+hex_chr[n>>j*8&15]}return s}function hex(x){var i;for(i=0;i<x.length;i+=1){x[i]=rhex(x[i])}return x.join("")}if(hex(md51("hello"))!=="5d41402abc4b2a76b9719d911017c592"){add32=function(x,y){var lsw=(x&65535)+(y&65535),msw=(x>>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}}if(typeof ArrayBuffer!=="undefined"&&!ArrayBuffer.prototype.slice){(function(){function clamp(val,length){val=val|0||0;if(val<0){return Math.max(val+length,0)}return Math.min(val,length)}ArrayBuffer.prototype.slice=function(from,to){var length=this.byteLength,begin=clamp(from,length),end=length,num,target,targetArray,sourceArray;if(to!==undefined){end=clamp(to,length)}if(begin>end){return new ArrayBuffer(0)}num=end-begin;target=new ArrayBuffer(num);targetArray=new Uint8Array(target);sourceArray=new Uint8Array(this,begin,num);targetArray.set(sourceArray);return target}})()}function toUtf8(str){if(/[\u0080-\uFFFF]/.test(str)){str=unescape(encodeURIComponent(str))}return str}function utf8Str2ArrayBuffer(str,returnUInt8Array){var length=str.length,buff=new ArrayBuffer(length),arr=new Uint8Array(buff),i;for(i=0;i<length;i+=1){arr[i]=str.charCodeAt(i)}return returnUInt8Array?arr:buff}function arrayBuffer2Utf8Str(buff){return String.fromCharCode.apply(null,new Uint8Array(buff))}function concatenateArrayBuffers(first,second,returnUInt8Array){var result=new Uint8Array(first.byteLength+second.byteLength);result.set(new Uint8Array(first));result.set(new Uint8Array(second),first.byteLength);return returnUInt8Array?result:result.buffer}function hexToBinaryString(hex){var bytes=[],length=hex.length,x;for(x=0;x<length-1;x+=2){bytes.push(parseInt(hex.substr(x,2),16))}return String.fromCharCode.apply(String,bytes)}function SparkMD5(){this.reset()}SparkMD5.prototype.append=function(str){this.appendBinary(toUtf8(str));return this};SparkMD5.prototype.appendBinary=function(contents){this._buff+=contents;this._length+=contents.length;var length=this._buff.length,i;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk(this._buff.substring(i-64,i)))}this._buff=this._buff.substring(i-64);return this};SparkMD5.prototype.end=function(raw){var buff=this._buff,length=buff.length,i,tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],ret;for(i=0;i<length;i+=1){tail[i>>2]|=buff.charCodeAt(i)<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.prototype.reset=function(){this._buff="";this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}};SparkMD5.prototype.setState=function(state){this._buff=state.buff;this._length=state.length;this._hash=state.hash;return this};SparkMD5.prototype.destroy=function(){delete this._hash;delete this._buff;delete this._length};SparkMD5.prototype._finish=function(tail,length){var i=length,tmp,lo,hi;tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(this._hash,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=this._length*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(this._hash,tail)};SparkMD5.hash=function(str,raw){return SparkMD5.hashBinary(toUtf8(str),raw)};SparkMD5.hashBinary=function(content,raw){var hash=md51(content),ret=hex(hash);return raw?hexToBinaryString(ret):ret};SparkMD5.ArrayBuffer=function(){this.reset()};SparkMD5.ArrayBuffer.prototype.append=function(arr){var buff=concatenateArrayBuffers(this._buff.buffer,arr,true),length=buff.length,i;this._length+=arr.byteLength;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk_array(buff.subarray(i-64,i)))}this._buff=i-64<length?new Uint8Array(buff.buffer.slice(i-64)):new Uint8Array(0);return this};SparkMD5.ArrayBuffer.prototype.end=function(raw){var buff=this._buff,length=buff.length,tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],i,ret;for(i=0;i<length;i+=1){tail[i>>2]|=buff[i]<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.ArrayBuffer.prototype.reset=function(){this._buff=new Uint8Array(0);this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.ArrayBuffer.prototype.getState=function(){var state=SparkMD5.prototype.getState.call(this);state.buff=arrayBuffer2Utf8Str(state.buff);return state};SparkMD5.ArrayBuffer.prototype.setState=function(state){state.buff=utf8Str2ArrayBuffer(state.buff,true);return SparkMD5.prototype.setState.call(this,state)};SparkMD5.ArrayBuffer.prototype.destroy=SparkMD5.prototype.destroy;SparkMD5.ArrayBuffer.prototype._finish=SparkMD5.prototype._finish;SparkMD5.ArrayBuffer.hash=function(arr,raw){var hash=md51_array(new Uint8Array(arr)),ret=hex(hash);return raw?hexToBinaryString(ret):ret};return SparkMD5});
This diff is collapsed.
<?php
return array (
0 =>
array (
'name' => 'accessKey',
'title' => 'Access Key',
'type' => 'string',
'content' =>
array (
),
'value' => 'HPUAWU3GPS8HEWX9JFLG',
'rule' => 'required',
'msg' => '',
'tip' => '请前往华为云控制台->我的凭证->访问密钥中生成',
'ok' => '',
'extend' => '',
),
1 =>
array (
'name' => 'secretKey',
'title' => 'Secret Key',
'type' => 'string',
'content' =>
array (
),
'value' => 'Jj7Vt1WnU69pWG6QplBmHBkaw6WM4oLU1AZa9Z9n',
'rule' => 'required',
'msg' => '',
'tip' => '请前往华为云控制台->我的凭证->访问密钥中生成',
'ok' => '',
'extend' => '',
),
2 =>
array (
'name' => 'bucket',
'title' => '存储桶名称',
'type' => 'string',
'content' =>
array (
),
'value' => 'beevera',
'rule' => 'required',
'msg' => '',
'tip' => '存储桶名称',
'ok' => '',
'extend' => '',
),
3 =>
array (
'name' => 'endpoint',
'title' => 'Endpoint',
'type' => 'string',
'content' =>
array (
),
'value' => 'obs.cn-east-3.myhuaweicloud.com',
'rule' => 'required;endpoint',
'msg' => '',
'tip' => '请输入你的Endpoint',
'ok' => '',
'extend' => 'data-rule-endpoint="[/^(?!http(s)?:\\/\\/).*$/, \'不能以http(s)://开头\']"',
),
4 =>
array (
'name' => 'uploadurl',
'title' => '上传接口地址',
'type' => 'string',
'content' =>
array (
),
'value' => 'https://beevera.obs.cn-east-3.myhuaweicloud.com',
'rule' => 'required;uploadurl',
'msg' => '',
'tip' => '请使用存储桶->基本信息->访问域名的值,并在前面加上http://或https://',
'ok' => '',
'extend' => 'data-rule-uploadurl="[/^http(s)?:\\/\\/.*$/, \'必需以http(s)://开头\']"',
),
5 =>
array (
'name' => 'cdnurl',
'title' => 'CDN地址',
'type' => 'string',
'content' =>
array (
),
'value' => 'https://beevera.obs.cn-east-3.myhuaweicloud.com',
'rule' => 'required;cdnurl',
'msg' => '',
'tip' => '如果你的云存储有绑定自定义域名,请输入自定义域名',
'ok' => '',
'extend' => 'data-rule-cdnurl="[/^http(s)?:\\/\\/.*$/, \'必需以http(s)://开头\']"',
),
6 =>
array (
'name' => 'uploadmode',
'title' => '上传模式',
'type' => 'select',
'content' =>
array (
'client' => '客户端直传(速度快,无备份)',
'server' => '服务器中转(占用服务器带宽,有备份)',
),
'value' => 'client',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
7 =>
array (
'name' => 'serverbackup',
'title' => '服务器中转模式备份',
'type' => 'radio',
'content' =>
array (
1 => '备份(附件管理将产生2条记录)',
0 => '不备份',
),
'value' => '0',
'rule' => '',
'msg' => '',
'tip' => '服务器中转模式下是否备份文件',
'ok' => '',
'extend' => '',
),
8 =>
array (
'name' => 'savekey',
'title' => '保存文件名',
'type' => 'string',
'content' =>
array (
),
'value' => '/uploads/{year}{mon}{day}/{filemd5}{.suffix}',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
9 =>
array (
'name' => 'expire',
'title' => '上传有效时长',
'type' => 'string',
'content' =>
array (
),
'value' => '1200',
'rule' => 'required',
'msg' => '',
'tip' => '用户停留页面上传有效时长,单位秒',
'ok' => '',
'extend' => '',
),
10 =>
array (
'name' => 'maxsize',
'title' => '最大可上传',
'type' => 'string',
'content' =>
array (
),
'value' => '50M',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
11 =>
array (
'name' => 'mimetype',
'title' => '可上传后缀格式',
'type' => 'string',
'content' =>
array (
),
'value' => 'jpg,png,bmp,jpeg,gif,zip,rar,mp4,webp',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
12 =>
array (
'name' => 'multiple',
'title' => '多文件上传',
'type' => 'bool',
'content' =>
array (
),
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
13 =>
array (
'name' => 'thumbstyle',
'title' => '缩略图样式',
'type' => 'string',
'content' =>
array (
),
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '用于后台列表缩略图样式,可使用:?x-image-process=image/resize,m_fixed,h_90,w_120或?x-image-process=style/样式名称',
'ok' => '',
'extend' => '',
),
14 =>
array (
'name' => 'chunking',
'title' => '分片上传',
'type' => 'radio',
'content' =>
array (
1 => '开启',
0 => '关闭',
),
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
15 =>
array (
'name' => 'chunksize',
'title' => '分片大小',
'type' => 'number',
'content' =>
array (
),
'value' => '4194304',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
16 =>
array (
'name' => 'syncdelete',
'title' => '附件删除时是否同步删除云存储文件',
'type' => 'bool',
'content' =>
array (
),
'value' => '1',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
17 =>
array (
'name' => 'apiupload',
'title' => 'API接口使用云存储',
'type' => 'bool',
'content' =>
array (
),
'value' => '1',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
18 =>
array (
'name' => 'noneedlogin',
'title' => '免登录上传',
'type' => 'checkbox',
'content' =>
array (
'api' => 'API',
'index' => '前台',
'admin' => '后台',
),
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
);
This diff is collapsed.
name = hwobs
title = 华为OBS云储存
intro = 使用华为OBS作为默认云储存
author = FastAdmin
website =
version = 1.2.10
state = 0
url = /addons/hwobs
license = regular
licenseto = 114257
<?php
namespace addons\hwobs\library;
class Auth
{
public function __construct()
{
}
public static function isModuleAllow()
{
$config = get_addon_config('hwobs');
$module = request()->module();
$module = $module ? strtolower($module) : 'index';
$noNeedLogin = array_filter(explode(',', $config['noneedlogin'] ?? ''));
$isModuleLogin = false;
$tagName = 'upload_config_checklogin';
foreach (\think\Hook::get($tagName) as $index => $name) {
if (\think\Hook::exec($name, $tagName)) {
$isModuleLogin = true;
break;
}
}
if (in_array($module, $noNeedLogin)
|| ($module == 'admin' && \app\admin\library\Auth::instance()->id)
|| ($module != 'admin' && \app\common\library\Auth::instance()->id)
|| $isModuleLogin) {
return true;
} else {
return false;
}
}
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Common;
use Psr\Http\Message\StreamInterface;
use GuzzleHttp\Psr7\StreamDecoratorTrait;
use Obs\ObsException;
class CheckoutStream implements StreamInterface {
use StreamDecoratorTrait;
private $expectedLength;
private $readedCount = 0;
public function __construct(StreamInterface $stream, $expectedLength) {
$this->stream = $stream;
$this->expectedLength = $expectedLength;
}
public function getContents() {
$contents = $this->stream->getContents();
$length = strlen($contents);
if ($this->expectedLength !== null && floatval($length) !== $this->expectedLength) {
$this -> throwObsException($this->expectedLength, $length);
}
return $contents;
}
public function read($length) {
$string = $this->stream->read($length);
if ($this->expectedLength !== null) {
$this->readedCount += strlen($string);
if ($this->stream->eof()) {
if (floatval($this->readedCount) !== $this->expectedLength) {
$this -> throwObsException($this->expectedLength, $this->readedCount);
}
}
}
return $string;
}
public function throwObsException($expectedLength, $reaLength) {
$obsException = new ObsException('premature end of Content-Length delimiter message body (expected:' . $expectedLength . '; received:' . $reaLength . ')');
$obsException->setExceptionType('server');
throw $obsException;
}
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Common;
interface ITransform {
public function transform($sign, $para);
}
<?php
/**
* Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
namespace Obs\Internal\Common;
class Model implements \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInterface
{
protected $data;
public function __construct(array $data = [])
{
$this->data = $data;
}
public function count()
{
return count($this->data);
}
public function getIterator()
{
return new \ArrayIterator($this->data);
}
public function toArray()
{
return $this->data;
}
public function clear()
{
$this->data = [];
return $this;
}
public function getAll(array $keys = null)
{
return $keys ? array_intersect_key($this->data, array_flip($keys)) : $this->data;
}
public function get($key)
{
return isset($this->data[$key]) ? $this->data[$key] : null;
}
public function set($key, $value)
{
$this->data[$key] = $value;
return $this;
}
public function add($key, $value)
{
if (!array_key_exists($key, $this->data)) {
$this->data[$key] = $value;
} elseif (is_array($this->data[$key])) {
$this->data[$key][] = $value;
} else {
$this->data[$key] = [$this->data[$key], $value];
}
return $this;
}
public function remove($key)
{
unset($this->data[$key]);
return $this;
}
public function getKeys()
{
return array_keys($this->data);
}
public function hasKey($key)
{
return array_key_exists($key, $this->data);
}
public function keySearch($key)
{
foreach (array_keys($this->data) as $k) {
if (!strcasecmp($k, $key)) {
return $k;
}
}
return false;
}
public function hasValue($value)
{
return array_search($value, $this->data);
}
public function replace(array $data)
{
$this->data = $data;
return $this;
}
public function merge($data)
{
foreach ($data as $key => $value) {
$this->add($key, $value);
}
return $this;
}
public function overwriteWith($data)
{
if (is_array($data)) {
$this->data = $data + $this->data;
} else {
foreach ($data as $key => $value) {
$this->data[$key] = $value;
}
}
return $this;
}
public function map(\Closure $closure, array $context = [], $static = true)
{
$collection = $static ? new static() : new self();
foreach ($this as $key => $value) {
$collection->add($key, $closure($key, $value, $context));
}
return $collection;
}
public function filter(\Closure $closure, $static = true)
{
$collection = ($static) ? new static() : new self();
foreach ($this->data as $key => $value) {
if ($closure($key, $value)) {
$collection->add($key, $value);
}
}
return $collection;
}
public function offsetExists($offset)
{
return isset($this->data[$offset]);
}
public function offsetGet($offset)
{
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
public function offsetSet($offset, $value)
{
$this->data[$offset] = $value;
}
public function offsetUnset($offset)
{
unset($this->data[$offset]);
}
public function setPath($path, $value)
{
$current =& $this->data;
$queue = explode('/', $path);
while (null !== ($key = array_shift($queue))) {
if (!is_array($current)) {
throw new \RuntimeException("Trying to setPath {$path}, but {$key} is set and is not an array");
} elseif (!$queue) {
$current[$key] = $value;
} elseif (isset($current[$key])) {
$current =& $current[$key];
} else {
$current[$key] = [];
$current =& $current[$key];
}
}
return $this;
}
public function getPath($path, $separator = '/', $data = null)
{
if ($data === null) {
$data =& $this->data;
}
$path = is_array($path) ? $path : explode($separator, $path);
while (null !== ($part = array_shift($path))) {
if (!is_array($data)) {
return null;
} elseif (isset($data[$part])) {
$data =& $data[$part];
} elseif ($part != '*') {
return null;
} else {
// Perform a wildcard search by diverging and merging paths
$result = [];
foreach ($data as $value) {
if (!$path) {
$result = array_merge_recursive($result, (array) $value);
} elseif (null !== ($test = $this->getPath($path, $separator, $value))) {
$result = array_merge_recursive($result, (array) $test);
}
}
return $result;
}
}
return $data;
}
public function __toString()
{
$output = 'Debug output of ';
$output .= 'model';
$output = str_repeat('=', strlen($output)) . "\n" . $output . "\n" . str_repeat('=', strlen($output)) . "\n\n";
$output .= "Model data\n-----------\n\n";
$output .= "This data can be retrieved from the model object using the get() method of the model "
. "(e.g. \$model->get(\$key)) or accessing the model like an associative array (e.g. \$model['key']).\n\n";
$lines = array_slice(explode("\n", trim(print_r($this->toArray(), true))), 2, -1);
$output .= implode("\n", $lines);
return $output . "\n";
}
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Common;
use Obs\ObsClient;
class ObsTransform implements ITransform {
private static $instance;
private function __construct(){}
public static function getInstance() {
if (!(self::$instance instanceof ObsTransform)) {
self::$instance = new ObsTransform();
}
return self::$instance;
}
public function transform($sign, $para) {
if ($sign === 'aclHeader') {
$para = $this->transAclHeader($para);
} else if ($sign === 'aclUri') {
$para = $this->transAclGroupUri($para);
} else if ($sign == 'event') {
$para = $this->transNotificationEvent($para);
} else if ($sign == 'storageClass') {
$para = $this->transStorageClass($para);
}
return $para;
}
private function transAclHeader($para) {
if ($para === ObsClient::AclAuthenticatedRead || $para === ObsClient::AclBucketOwnerRead ||
$para === ObsClient::AclBucketOwnerFullControl || $para === ObsClient::AclLogDeliveryWrite) {
$para = null;
}
return $para;
}
private function transAclGroupUri($para) {
if ($para === ObsClient::GroupAllUsers) {
$para = ObsClient::AllUsers;
}
return $para;
}
private function transNotificationEvent($para) {
$pos = strpos($para, 's3:');
if ($pos !== false && $pos === 0) {
$para = substr($para, 3);
}
return $para;
}
private function transStorageClass($para) {
$search = array('STANDARD', 'STANDARD_IA', 'GLACIER');
$repalce = array(ObsClient::StorageClassStandard, ObsClient::StorageClassWarm, ObsClient::StorageClassCold);
$para = str_replace($search, $repalce, $para);
return $para;
}
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Common;
class SchemaFormatter
{
protected static $utcTimeZone;
public static function format($fmt, $value)
{
if($fmt === 'date-time'){
return self::formatDateTime($value);
}
if($fmt === 'data-time-http'){
return self::formatDateTimeHttp($value);
}
if($fmt === 'data-time-middle'){
return self::formatDateTimeMiddle($value);
}
if($fmt === 'date'){
return self::formatDate($value);
}
if($fmt === 'timestamp'){
return self::formatTimestamp($value);
}
if($fmt === 'boolean-string'){
return self::formatBooleanAsString($value);
}
return $value;
}
public static function formatDateTimeMiddle($dateTime)
{
if (is_string($dateTime)) {
$dateTime = new \DateTime($dateTime);
}
if ($dateTime instanceof \DateTime) {
return $dateTime -> format('Y-m-d\T00:00:00\Z');
}
return null;
}
public static function formatDateTime($value)
{
return self::dateFormatter($value, 'Y-m-d\TH:i:s\Z');
}
public static function formatDateTimeHttp($value)
{
return self::dateFormatter($value, 'D, d M Y H:i:s \G\M\T');
}
public static function formatDate($value)
{
return self::dateFormatter($value, 'Y-m-d');
}
public static function formatTime($value)
{
return self::dateFormatter($value, 'H:i:s');
}
public static function formatBooleanAsString($value)
{
return filter_var($value, FILTER_VALIDATE_BOOLEAN) ? 'true' : 'false';
}
public static function formatTimestamp($value)
{
return (int) self::dateFormatter($value, 'U');
}
private static function dateFormatter($dt, $fmt)
{
if (is_numeric($dt)) {
return gmdate($fmt, (int) $dt);
}
if (is_string($dt)) {
$dt = new \DateTime($dt);
}
if ($dt instanceof \DateTime) {
if (!self::$utcTimeZone) {
self::$utcTimeZone = new \DateTimeZone('UTC');
}
return $dt->setTimezone(self::$utcTimeZone)->format($fmt);
}
return null;
}
}
This diff is collapsed.
This diff is collapsed.
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Common;
interface ToArrayInterface
{
public function toArray();
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Common;
use Obs\ObsClient;
use Obs\Internal\Resource\V2Constants;
class V2Transform implements ITransform{
private static $instance;
private function __construct(){}
public static function getInstance() {
if (!(self::$instance instanceof V2Transform)) {
self::$instance = new V2Transform();
}
return self::$instance;
}
public function transform($sign, $para) {
if ($sign === 'storageClass') {
$para = $this->transStorageClass($para);
} else if ($sign === 'aclHeader') {
$para = $this->transAclHeader($para);
} else if ($sign === 'aclUri') {
$para = $this->transAclGroupUri($para);
} else if ($sign == 'event') {
$para = $this->transNotificationEvent($para);
}
return $para;
}
private function transStorageClass($para) {
$search = array(ObsClient::StorageClassStandard, ObsClient::StorageClassWarm, ObsClient::StorageClassCold);
$repalce = array('STANDARD', 'STANDARD_IA', 'GLACIER');
$para = str_replace($search, $repalce, $para);
return $para;
}
private function transAclHeader($para) {
if ($para === ObsClient::AclPublicReadDelivered || $para === ObsClient::AclPublicReadWriteDelivered) {
$para = null;
}
return $para;
}
private function transAclGroupUri($para) {
if ($para === ObsClient::GroupAllUsers) {
$para = V2Constants::GROUP_ALL_USERS_PREFIX . $para;
} else if ($para === ObsClient::GroupAuthenticatedUsers) {
$para = V2Constants::GROUP_AUTHENTICATED_USERS_PREFIX . $para;
} else if ($para === ObsClient::GroupLogDelivery) {
$para = V2Constants::GROUP_LOG_DELIVERY_PREFIX . $para;
} else if ($para === ObsClient::AllUsers) {
$para = V2Constants::GROUP_ALL_USERS_PREFIX . ObsClient::GroupAllUsers;
}
return $para;
}
private function transNotificationEvent($para) {
$pos = strpos($para, 's3:');
if ($pos === false || $pos !== 0) {
$para = 's3:' . $para;
}
return $para;
}
}
This diff is collapsed.
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Resource;
class Constants {
const ALLOWED_RESOURCE_PARAMTER_NAMES = [
'acl',
'policy',
'torrent',
'logging',
'location',
'storageinfo',
'quota',
'storagepolicy',
'requestpayment',
'versions',
'versioning',
'versionid',
'uploads',
'uploadid',
'partnumber',
'website',
'notification',
'lifecycle',
'deletebucket',
'delete',
'cors',
'restore',
'tagging',
'response-content-type',
'response-content-language',
'response-expires',
'response-cache-control',
'response-content-disposition',
'response-content-encoding',
'x-image-process',
'backtosource',
'storageclass',
'replication',
'append',
'position',
'x-oss-process'
];
const ALLOWED_REQUEST_HTTP_HEADER_METADATA_NAMES = [
'content-type',
'content-md5',
'content-length',
'content-language',
'expires',
'origin',
'cache-control',
'content-disposition',
'content-encoding',
'access-control-request-method',
'access-control-request-headers',
'x-default-storage-class',
'location',
'date',
'etag',
'range',
'host',
'if-modified-since',
'if-unmodified-since',
'if-match',
'if-none-match',
'last-modified',
'content-range',
'success-action-redirect'
];
const ALLOWED_RESPONSE_HTTP_HEADER_METADATA_NAMES = [
'content-type',
'content-md5',
'content-length',
'content-language',
'expires',
'origin',
'cache-control',
'content-disposition',
'content-encoding',
'x-default-storage-class',
'location',
'date',
'etag',
'host',
'last-modified',
'content-range',
'x-reserved',
'access-control-allow-origin',
'access-control-allow-headers',
'access-control-max-age',
'access-control-allow-methods',
'access-control-expose-headers',
'connection'
];
public static function selectConstants($signature) {
$signature = (strcasecmp ( $signature, 'obs' ) === 0) ? 'OBS' : 'V2';
return __NAMESPACE__ . '\\' . $signature . 'Constants';
}
public static function selectRequestResource($signature) {
$signature = (strcasecmp ( $signature, 'obs' ) === 0) ? 'OBS' : 'V2';
return (__NAMESPACE__ . '\\' . $signature . 'RequestResource');
}
}
\ No newline at end of file
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Resource;
class OBSConstants extends Constants {
const FLAG = 'OBS';
const METADATA_PREFIX = 'x-obs-meta-';
const HEADER_PREFIX = 'x-obs-';
const ALTERNATIVE_DATE_HEADER = 'x-obs-date';
const SECURITY_TOKEN_HEAD = 'x-obs-security-token';
const TEMPURL_AK_HEAD = 'AccessKeyId';
const COMMON_HEADERS = [
'content-length' => 'ContentLength',
'date' => 'Date',
'x-obs-request-id' => 'RequestId',
'x-obs-id-2' => 'Id2',
'x-reserved' => 'Reserved'
];
}
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Resource;
class V2Constants extends Constants {
const FLAG = 'AWS';
const METADATA_PREFIX = 'x-amz-meta-';
const HEADER_PREFIX = 'x-amz-';
const ALTERNATIVE_DATE_HEADER = 'x-amz-date';
const SECURITY_TOKEN_HEAD = 'x-amz-security-token';
const TEMPURL_AK_HEAD = 'AWSAccessKeyId';
const GROUP_ALL_USERS_PREFIX = 'http://acs.amazonaws.com/groups/global/';
const GROUP_AUTHENTICATED_USERS_PREFIX = 'http://acs.amazonaws.com/groups/global/';
const GROUP_LOG_DELIVERY_PREFIX = 'http://acs.amazonaws.com/groups/s3/';
const COMMON_HEADERS = [
'content-length' => 'ContentLength',
'date' => 'Date',
'x-amz-request-id' => 'RequestId',
'x-amz-id-2' => 'Id2',
'x-reserved' => 'Reserved'
];
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Signature;
use Obs\Internal\Resource\Constants;
use Obs\Internal\Common\Model;
use Obs\Internal\Resource\V2Constants;
class DefaultSignature extends AbstractSignature
{
const INTEREST_HEADER_KEY_LIST = array('content-type', 'content-md5', 'date');
public function __construct($ak, $sk, $pathStyle, $endpoint, $methodName, $signature, $securityToken=false, $isCname=false)
{
parent::__construct($ak, $sk, $pathStyle, $endpoint, $methodName, $signature, $securityToken, $isCname);
}
public function doAuth(array &$requestConfig, array &$params, Model $model)
{
$result = $this -> prepareAuth($requestConfig, $params, $model);
$result['headers']['Date'] = gmdate('D, d M Y H:i:s \G\M\T');
$canonicalstring = $this-> makeCanonicalstring($result['method'], $result['headers'], $result['pathArgs'], $result['dnsParam'], $result['uriParam']);
$result['cannonicalRequest'] = $canonicalstring;
//print_r($result);
$signature = base64_encode(hash_hmac('sha1', $canonicalstring, $this->sk, true));
$constants = Constants::selectConstants($this -> signature);
$signatureFlag = $constants::FLAG;
$authorization = $signatureFlag . ' ' . $this->ak . ':' . $signature;
$result['headers']['Authorization'] = $authorization;
return $result;
}
public function makeCanonicalstring($method, $headers, $pathArgs, $bucketName, $objectKey, $expires = null)
{
$buffer = [];
$buffer[] = $method;
$buffer[] = "\n";
$interestHeaders = [];
$constants = Constants::selectConstants($this -> signature);
foreach ($headers as $key => $value){
$key = strtolower($key);
if(in_array($key, self::INTEREST_HEADER_KEY_LIST) || strpos($key, $constants::HEADER_PREFIX) === 0){
$interestHeaders[$key] = $value;
}
}
if(array_key_exists($constants::ALTERNATIVE_DATE_HEADER, $interestHeaders)){
$interestHeaders['date'] = '';
}
if($expires !== null){
$interestHeaders['date'] = strval($expires);
}
if(!array_key_exists('content-type', $interestHeaders)){
$interestHeaders['content-type'] = '';
}
if(!array_key_exists('content-md5', $interestHeaders)){
$interestHeaders['content-md5'] = '';
}
ksort($interestHeaders);
foreach ($interestHeaders as $key => $value){
if(strpos($key, $constants::HEADER_PREFIX) === 0){
$buffer[] = $key . ':' . $value;
}else{
$buffer[] = $value;
}
$buffer[] = "\n";
}
$uri = '';
$bucketName = $this->isCname ? $headers['Host'] : $bucketName;
if($bucketName){
$uri .= '/';
$uri .= $bucketName;
if(!$this->pathStyle){
$uri .= '/';
}
}
if($objectKey){
if(!($pos=strripos($uri, '/')) || strlen($uri)-1 !== $pos){
$uri .= '/';
}
$uri .= $objectKey;
}
$buffer[] = $uri === ''? '/' : $uri;
if(!empty($pathArgs)){
ksort($pathArgs);
$_pathArgs = [];
foreach ($pathArgs as $key => $value){
if(in_array(strtolower($key), $constants::ALLOWED_RESOURCE_PARAMTER_NAMES) || strpos($key, $constants::HEADER_PREFIX) === 0){
$_pathArgs[] = $value === null || $value === '' ? $key : $key . '=' . urldecode($value);
}
}
if(!empty($_pathArgs)){
$buffer[] = '?';
$buffer[] = implode('&', $_pathArgs);
}
}
return implode('', $buffer);
}
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Signature;
use Obs\Internal\Common\Model;
interface SignatureInterface
{
function doAuth(array &$requestConfig, array &$params, Model $model);
}
\ No newline at end of file
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Internal\Signature;
use Obs\Internal\Common\Model;
class V4Signature extends AbstractSignature
{
const CONTENT_SHA256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
protected $region;
protected $utcTimeZone;
public function __construct($ak, $sk, $pathStyle, $endpoint, $region, $methodName, $signature, $securityToken=false, $isCname=false)
{
parent::__construct($ak, $sk, $pathStyle, $endpoint, $methodName, $signature, $securityToken, $isCname);
$this->region = $region;
$this->utcTimeZone = new \DateTimeZone ('UTC');
}
public function doAuth(array &$requestConfig, array &$params, Model $model)
{
$result = $this -> prepareAuth($requestConfig, $params, $model);
$result['headers']['x-amz-content-sha256'] = self::CONTENT_SHA256;
$bucketName = $result['dnsParam'];
$result['headers']['Host'] = $result['host'];
$time = null;
if(array_key_exists('x-amz-date', $result['headers'])){
$time = $result['headers']['x-amz-date'];
}else if(array_key_exists('X-Amz-Date', $result['headers'])){
$time = $result['headers']['X-Amz-Date'];
}
$timestamp = $time ? date_create_from_format('Ymd\THis\Z', $time, $this->utcTimeZone) -> getTimestamp()
:time();
$result['headers']['Date'] = gmdate('D, d M Y H:i:s \G\M\T', $timestamp);
$longDate = gmdate('Ymd\THis\Z', $timestamp);
$shortDate = substr($longDate, 0, 8);
$credential = $this-> getCredential($shortDate);
$signedHeaders = $this->getSignedHeaders($result['headers']);
$canonicalstring = $this-> makeCanonicalstring($result['method'], $result['headers'], $result['pathArgs'], $bucketName, $result['uriParam'], $signedHeaders);
$result['cannonicalRequest'] = $canonicalstring;
$signature = $this -> getSignature($canonicalstring, $longDate, $shortDate);
$authorization = 'AWS4-HMAC-SHA256 ' . 'Credential=' . $credential. ',' . 'SignedHeaders=' . $signedHeaders . ',' . 'Signature=' . $signature;
$result['headers']['Authorization'] = $authorization;
return $result;
}
public function getSignature($canonicalstring, $longDate, $shortDate)
{
$stringToSign = [];
$stringToSign[] = 'AWS4-HMAC-SHA256';
$stringToSign[] = "\n";
$stringToSign[] = $longDate;
$stringToSign[] = "\n";
$stringToSign[] = $this -> getScope($shortDate);
$stringToSign[] = "\n";
$stringToSign[] = hash('sha256', $canonicalstring);
$dateKey = hash_hmac('sha256', $shortDate, 'AWS4' . $this -> sk, true);
$regionKey = hash_hmac('sha256', $this->region, $dateKey, true);
$serviceKey = hash_hmac('sha256', 's3', $regionKey, true);
$signingKey = hash_hmac('sha256', 'aws4_request', $serviceKey, true);
$signature = hash_hmac('sha256', implode('', $stringToSign), $signingKey);
return $signature;
}
public function getCanonicalQueryString($pathArgs)
{
$queryStr = '';
ksort($pathArgs);
$index = 0;
foreach ($pathArgs as $key => $value){
$queryStr .= $key . '=' . $value;
if($index++ !== count($pathArgs) - 1){
$queryStr .= '&';
}
}
return $queryStr;
}
public function getCanonicalHeaders($headers)
{
$_headers = [];
foreach ($headers as $key => $value) {
$_headers[strtolower($key)] = $value;
}
ksort($_headers);
$canonicalHeaderStr = '';
foreach ($_headers as $key => $value){
$value = is_array($value) ? implode(',', $value) : $value;
$canonicalHeaderStr .= $key . ':' . $value;
$canonicalHeaderStr .= "\n";
}
return $canonicalHeaderStr;
}
public function getCanonicalURI($bucketName, $objectKey)
{
$uri = '';
if($this -> pathStyle && $bucketName){
$uri .= '/' . $bucketName;
}
if($objectKey){
$uri .= '/' . $objectKey;
}
if($uri === ''){
$uri = '/';
}
return $uri;
}
public function makeCanonicalstring($method, $headers, $pathArgs, $bucketName, $objectKey, $signedHeaders=null, $payload=null)
{
$buffer = [];
$buffer[] = $method;
$buffer[] = "\n";
$buffer[] = $this->getCanonicalURI($bucketName, $objectKey);
$buffer[] = "\n";
$buffer[] = $this->getCanonicalQueryString($pathArgs);
$buffer[] = "\n";
$buffer[] = $this->getCanonicalHeaders($headers);
$buffer[] = "\n";
$buffer[] = $signedHeaders ? $signedHeaders : $this->getSignedHeaders($headers);
$buffer[] = "\n";
$buffer[] = $payload ? strval($payload) : self::CONTENT_SHA256;
return implode('', $buffer);
}
public function getSignedHeaders($headers)
{
$_headers = [];
foreach ($headers as $key => $value) {
$_headers[] = strtolower($key);
}
sort($_headers);
$signedHeaders = '';
foreach ($_headers as $key => $value){
$signedHeaders .= $value;
if($key !== count($_headers) - 1){
$signedHeaders .= ';';
}
}
return $signedHeaders;
}
public function getScope($shortDate)
{
return $shortDate . '/' . $this->region . '/s3/aws4_request';
}
public function getCredential($shortDate)
{
return $this->ak . '/' . $this->getScope($shortDate);
}
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Log;
class ObsConfig
{
const LOG_FILE_CONFIG = [
'FilePath'=>'./logs',
'FileName'=>'eSDK-OBS-PHP.log',
'MaxFiles'=>10,
'Level'=>INFO
];
}
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs\Log;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
class ObsLog extends Logger
{
public static $log = null;
protected $log_path = './';
protected $log_name = null;
protected $log_level = Logger::DEBUG;
protected $log_maxFiles = 0;
private $formatter = null;
private $handler = null;
private $filepath = '';
public static function initLog($logConfig= [])
{
$s3log = new ObsLog('');
$s3log->setConfig($logConfig);
$s3log->cheakDir();
$s3log->setFilePath();
$s3log->setFormat();
$s3log->setHande();
}
private function setFormat()
{
$output = '[%datetime%][%level_name%]'.'%message%' . "\n";
$this->formatter = new LineFormatter($output);
}
private function setHande()
{
self::$log = new Logger('obs_logger');
$rotating = new RotatingFileHandler($this->filepath, $this->log_maxFiles, $this->log_level);
$rotating->setFormatter($this->formatter);
self::$log->pushHandler($rotating);
}
private function setConfig($logConfig= [])
{
$arr = empty($logConfig) ? ObsConfig::LOG_FILE_CONFIG : $logConfig;
$this->log_path = iconv('UTF-8', 'GBK',$arr['FilePath']);
$this->log_name = iconv('UTF-8', 'GBK',$arr['FileName']);
$this->log_maxFiles = is_numeric($arr['MaxFiles']) ? 0 : intval($arr['MaxFiles']);
$this->log_level = $arr['Level'];
}
private function cheakDir()
{
if (!is_dir($this->log_path)){
mkdir($this->log_path, 0755, true);
}
}
private function setFilePath()
{
$this->filepath = $this->log_path.'/'.$this->log_name;
}
private static function writeLog($level, $msg)
{
switch ($level) {
case DEBUG:
self::$log->debug($msg);
break;
case INFO:
self::$log->info($msg);
break;
case NOTICE:
self::$log->notice($msg);
break;
case WARNING:
self::$log->warning($msg);
break;
case ERROR:
self::$log->error($msg);
break;
case CRITICAL:
self::$log->critical($msg);
break;
case ALERT:
self::$log->alert($msg);
break;
case EMERGENCY:
self::$log->emergency($msg);
break;
default:
break;
}
}
public static function commonLog($level, $format, $args1 = null, $arg2 = null)
{
if(ObsLog::$log){
if ($args1 === null && $arg2 === null) {
$msg = urldecode($format);
} else {
$msg = sprintf($format, $args1, $arg2);
}
$back = debug_backtrace();
$line = $back[0]['line'];
$funcname = $back[1]['function'];
$filename = basename($back[0]['file']);
$message = '['.$filename.':'.$line.']: '.$msg;
ObsLog::writeLog($level, $message);
}
}
}
This diff is collapsed.
<?php
/**
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
namespace Obs;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Obs\Log\ObsLog;
class ObsException extends \RuntimeException
{
const CLIENT = 'client';
const SERVER = 'server';
private $response;
private $request;
private $requestId;
private $exceptionType;
private $exceptionCode;
private $exceptionMessage;
private $hostId;
public function __construct ($message = null, $code = null, $previous = null)
{
parent::__construct($message, $code, $previous);
}
public function setExceptionCode($exceptionCode)
{
$this->exceptionCode = $exceptionCode;
}
public function getExceptionCode()
{
return $this->exceptionCode;
}
public function setExceptionMessage($exceptionMessage)
{
$this->exceptionMessage = $exceptionMessage;
}
public function getExceptionMessage()
{
return $this->exceptionMessage ? $this->exceptionMessage : $this->message;
}
public function setExceptionType($exceptionType)
{
$this->exceptionType = $exceptionType;
}
public function getExceptionType()
{
return $this->exceptionType;
}
public function setRequestId($requestId)
{
$this->requestId = $requestId;
}
public function getRequestId()
{
return $this->requestId;
}
public function setResponse(Response $response)
{
$this->response = $response;
}
public function getResponse()
{
return $this->response;
}
public function setRequest(Request $request)
{
$this->request = $request;
}
public function getRequest()
{
return $this->request;
}
public function getStatusCode()
{
return $this->response ? $this->response->getStatusCode() : -1;
}
public function setHostId($hostId){
$this->hostId = $hostId;
}
public function getHostId(){
return $this->hostId;
}
public function __toString()
{
$message = get_class($this) . ': '
. 'OBS Error Code: ' . $this->getExceptionCode() . ', '
. 'Status Code: ' . $this->getStatusCode() . ', '
. 'OBS Error Type: ' . $this->getExceptionType() . ', '
. 'OBS Error Message: ' . ($this->getExceptionMessage() ? $this->getExceptionMessage():$this->getMessage());
// Add the User-Agent if available
if ($this->request) {
$message .= ', ' . 'User-Agent: ' . $this->request->getHeaderLine('User-Agent');
}
$message .= "\n";
ObsLog::commonLog(INFO, "http request:status:%d, %s",$this->getStatusCode(),"code:".$this->getExceptionCode().", message:".$this->getMessage());
return $message;
}
}
<?php
namespace addons\hwobs\library;
use Obs\Internal\Common\Model;
use Obs\Internal\Signature\DefaultSignature;
class Signer
{
public function __construct()
{
}
/**
* 获取分片文件的签名
* @param string $url
* @param string $uploadId
* @param int $fileSize
* @param int $partSize
* @param string $date
* @return array
*/
public static function getPartsAuthorization($url, $uploadId, $fileSize, $partSize, $date)
{
$config = get_addon_config('hwobs');
$i = 0;
$size_count = $fileSize;
$values = array();
while ($size_count > 0) {
$size_count -= $partSize;
$values[] = array(
$partSize * $i,
($size_count > 0) ? $partSize : ($size_count + $partSize),
);
$i++;
}
$httpMethod = "PUT";
$headers = [
"Host" => str_replace(['http://', 'https://'], '', $config['uploadurl']),
"Content-Length" => 0,
"x-amz-date" => $date,
];
$result = [];
foreach ($values as $index => $value) {
$headers['Content-Length'] = $value[1];
$params = ['partNumber' => $index + 1, 'uploadId' => $uploadId, 'uriParam' => $url, 'dnsParam' => $config['bucket'], 'x-amz-date' => $date];
$model = new Model($params);
$sign = new DefaultSignature($config['accessKey'], $config['secretKey'], false, $config['uploadurl'], $httpMethod, 'v2', false, false);
$requestConfig = [
'httpMethod' => $httpMethod,
'requestParameters' => [
'x-amz-date' => ['location' => 'header'],
'partNumber' => ['location' => 'query'],
'uploadId' => ['location' => 'query'],
'uriParam' => ['location' => 'uri'],
'dnsParam' => ['location' => 'dns'],
]
];
$sig = $sign->doAuth($requestConfig, $params, $model);
$result[] = $sig['headers']['Authorization'];
}
return $result;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment