first commit
This commit is contained in:
285
vendor/qiniu/php-sdk/src/Qiniu/Auth.php
vendored
Normal file
285
vendor/qiniu/php-sdk/src/Qiniu/Auth.php
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu;
|
||||
|
||||
use Qiniu\Http\Header;
|
||||
use Qiniu\Zone;
|
||||
|
||||
final class Auth
|
||||
{
|
||||
private $accessKey;
|
||||
private $secretKey;
|
||||
public $options;
|
||||
|
||||
public function __construct($accessKey, $secretKey, $options = null)
|
||||
{
|
||||
$this->accessKey = $accessKey;
|
||||
$this->secretKey = $secretKey;
|
||||
$defaultOptions = array(
|
||||
'disableQiniuTimestampSignature' => null
|
||||
);
|
||||
if ($options == null) {
|
||||
$options = $defaultOptions;
|
||||
}
|
||||
$this->options = array_merge($defaultOptions, $options);
|
||||
}
|
||||
|
||||
public function getAccessKey()
|
||||
{
|
||||
return $this->accessKey;
|
||||
}
|
||||
|
||||
public function sign($data)
|
||||
{
|
||||
$hmac = hash_hmac('sha1', $data, $this->secretKey, true);
|
||||
return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
|
||||
}
|
||||
|
||||
public function signWithData($data)
|
||||
{
|
||||
$encodedData = \Qiniu\base64_urlSafeEncode($data);
|
||||
return $this->sign($encodedData) . ':' . $encodedData;
|
||||
}
|
||||
|
||||
public function signRequest($urlString, $body, $contentType = null)
|
||||
{
|
||||
$url = parse_url($urlString);
|
||||
$data = '';
|
||||
if (array_key_exists('path', $url)) {
|
||||
$data = $url['path'];
|
||||
}
|
||||
if (array_key_exists('query', $url)) {
|
||||
$data .= '?' . $url['query'];
|
||||
}
|
||||
$data .= "\n";
|
||||
|
||||
if ($body !== null && $contentType === 'application/x-www-form-urlencoded') {
|
||||
$data .= $body;
|
||||
}
|
||||
return $this->sign($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $urlString
|
||||
* @param string $method
|
||||
* @param string $body
|
||||
* @param null|Header $headers
|
||||
*/
|
||||
public function signQiniuAuthorization($urlString, $method = "GET", $body = "", $headers = null)
|
||||
{
|
||||
$url = parse_url($urlString);
|
||||
if (!$url) {
|
||||
return array(null, new \Exception("parse_url error"));
|
||||
}
|
||||
|
||||
// append method, path and query
|
||||
if ($method === "") {
|
||||
$data = "GET ";
|
||||
} else {
|
||||
$data = $method . " ";
|
||||
}
|
||||
if (isset($url["path"])) {
|
||||
$data .= $url["path"];
|
||||
}
|
||||
if (isset($url["query"])) {
|
||||
$data .= "?" . $url["query"];
|
||||
}
|
||||
|
||||
// append Host
|
||||
$data .= "\n";
|
||||
$data .= "Host: ";
|
||||
if (isset($url["host"])) {
|
||||
$data .= $url["host"];
|
||||
}
|
||||
if (isset($url["port"]) && $url["port"] > 0) {
|
||||
$data .= ":" . $url["port"];
|
||||
}
|
||||
|
||||
// try to append content type
|
||||
if ($headers != null && isset($headers["Content-Type"])) {
|
||||
// append content type
|
||||
$data .= "\n";
|
||||
$data .= "Content-Type: " . $headers["Content-Type"];
|
||||
}
|
||||
|
||||
// try append xQiniuHeaders
|
||||
if ($headers != null) {
|
||||
$headerLines = array();
|
||||
$keyPrefix = "X-Qiniu-";
|
||||
foreach ($headers as $k => $v) {
|
||||
if (strlen($k) > strlen($keyPrefix) && strpos($k, $keyPrefix) === 0) {
|
||||
array_push(
|
||||
$headerLines,
|
||||
$k . ": " . $v
|
||||
);
|
||||
}
|
||||
}
|
||||
if (count($headerLines) > 0) {
|
||||
$data .= "\n";
|
||||
sort($headerLines);
|
||||
$data .= implode("\n", $headerLines);
|
||||
}
|
||||
}
|
||||
|
||||
// append body
|
||||
$data .= "\n\n";
|
||||
if (!is_null($body)
|
||||
&& strlen($body) > 0
|
||||
&& isset($headers["Content-Type"])
|
||||
&& $headers["Content-Type"] != "application/octet-stream"
|
||||
) {
|
||||
$data .= $body;
|
||||
}
|
||||
|
||||
return array($this->sign($data), null);
|
||||
}
|
||||
|
||||
public function verifyCallback(
|
||||
$contentType,
|
||||
$originAuthorization,
|
||||
$url,
|
||||
$body,
|
||||
$method = "GET",
|
||||
$headers = array()
|
||||
) {
|
||||
if (strpos($originAuthorization, 'Qiniu') === 0) {
|
||||
$qnHeaders = new Header($headers);
|
||||
if (!isset($qnHeaders['Content-Type'])) {
|
||||
$qnHeaders['Content-Type'] = $contentType;
|
||||
}
|
||||
list($sign, $err) = $this->signQiniuAuthorization(
|
||||
$url,
|
||||
$method,
|
||||
$body,
|
||||
$qnHeaders
|
||||
);
|
||||
if ($err !== null) {
|
||||
return false;
|
||||
}
|
||||
$authorization = 'Qiniu ' . $sign;
|
||||
} else {
|
||||
$authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
|
||||
}
|
||||
return $originAuthorization === $authorization;
|
||||
}
|
||||
|
||||
public function privateDownloadUrl($baseUrl, $expires = 3600)
|
||||
{
|
||||
$deadline = time() + $expires;
|
||||
|
||||
$pos = strpos($baseUrl, '?');
|
||||
if ($pos !== false) {
|
||||
$baseUrl .= '&e=';
|
||||
} else {
|
||||
$baseUrl .= '?e=';
|
||||
}
|
||||
$baseUrl .= $deadline;
|
||||
|
||||
$token = $this->sign($baseUrl);
|
||||
return "$baseUrl&token=$token";
|
||||
}
|
||||
|
||||
public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true)
|
||||
{
|
||||
$deadline = time() + $expires;
|
||||
$scope = $bucket;
|
||||
if ($key !== null) {
|
||||
$scope .= ':' . $key;
|
||||
}
|
||||
|
||||
$args = self::copyPolicy($args, $policy, $strictPolicy);
|
||||
$args['scope'] = $scope;
|
||||
$args['deadline'] = $deadline;
|
||||
|
||||
$b = json_encode($args);
|
||||
return $this->signWithData($b);
|
||||
}
|
||||
|
||||
/**
|
||||
*上传策略,参数规格详见
|
||||
*http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
|
||||
*/
|
||||
private static $policyFields = array(
|
||||
'callbackUrl',
|
||||
'callbackBody',
|
||||
'callbackHost',
|
||||
'callbackBodyType',
|
||||
'callbackFetchKey',
|
||||
|
||||
'returnUrl',
|
||||
'returnBody',
|
||||
|
||||
'endUser',
|
||||
'saveKey',
|
||||
'forceSaveKey',
|
||||
'insertOnly',
|
||||
|
||||
'detectMime',
|
||||
'mimeLimit',
|
||||
'fsizeMin',
|
||||
'fsizeLimit',
|
||||
|
||||
'persistentOps', // 与 persistentWorkflowTemplateID 二选一
|
||||
'persistentNotifyUrl',
|
||||
'persistentPipeline',
|
||||
'persistentType', // 为 `1` 时开启闲时任务
|
||||
'persistentWorkflowTemplateID', // 与 persistentOps 二选一
|
||||
|
||||
'deleteAfterDays',
|
||||
'fileType',
|
||||
'isPrefixalScope',
|
||||
|
||||
'transform', // deprecated
|
||||
'transformFallbackKey', // deprecated
|
||||
'transformFallbackMode', // deprecated
|
||||
);
|
||||
|
||||
private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
|
||||
{
|
||||
if ($originPolicy === null) {
|
||||
return array();
|
||||
}
|
||||
foreach ($originPolicy as $key => $value) {
|
||||
if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) {
|
||||
$policy[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $policy;
|
||||
}
|
||||
|
||||
public function authorization($url, $body = null, $contentType = null)
|
||||
{
|
||||
$authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
|
||||
return array('Authorization' => $authorization);
|
||||
}
|
||||
|
||||
public function authorizationV2($url, $method, $body = null, $contentType = null)
|
||||
{
|
||||
$headers = new Header();
|
||||
$result = array();
|
||||
if ($contentType != null) {
|
||||
$headers['Content-Type'] = $contentType;
|
||||
$result['Content-Type'] = $contentType;
|
||||
}
|
||||
|
||||
$signDate = gmdate('Ymd\THis\Z', time());
|
||||
if ($this->options['disableQiniuTimestampSignature'] !== null) {
|
||||
if (!$this->options['disableQiniuTimestampSignature']) {
|
||||
$headers['X-Qiniu-Date'] = $signDate;
|
||||
$result['X-Qiniu-Date'] = $signDate;
|
||||
}
|
||||
} elseif (getenv("DISABLE_QINIU_TIMESTAMP_SIGNATURE")) {
|
||||
if (strtolower(getenv("DISABLE_QINIU_TIMESTAMP_SIGNATURE")) !== "true") {
|
||||
$headers['X-Qiniu-Date'] = $signDate;
|
||||
$result['X-Qiniu-Date'] = $signDate;
|
||||
}
|
||||
} else {
|
||||
$headers['X-Qiniu-Date'] = $signDate;
|
||||
$result['X-Qiniu-Date'] = $signDate;
|
||||
}
|
||||
|
||||
list($sign) = $this->signQiniuAuthorization($url, $method, $body, $headers);
|
||||
$result['Authorization'] = 'Qiniu ' . $sign;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
263
vendor/qiniu/php-sdk/src/Qiniu/Cdn/CdnManager.php
vendored
Normal file
263
vendor/qiniu/php-sdk/src/Qiniu/Cdn/CdnManager.php
vendored
Normal file
@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Cdn;
|
||||
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Proxy;
|
||||
|
||||
final class CdnManager
|
||||
{
|
||||
|
||||
private $auth;
|
||||
private $server;
|
||||
private $proxy;
|
||||
|
||||
public function __construct(Auth $auth, $proxy = null, $proxy_auth = null, $proxy_user_password = null)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->server = 'http://fusion.qiniuapi.com';
|
||||
$this->proxy = new Proxy($proxy, $proxy_auth, $proxy_user_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $urls 待刷新的文件链接数组
|
||||
* @return array
|
||||
*/
|
||||
public function refreshUrls(array $urls)
|
||||
{
|
||||
return $this->refreshUrlsAndDirs($urls, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dirs 待刷新的文件链接数组
|
||||
* @return array
|
||||
* 目前客户默认没有目录刷新权限,刷新会有400038报错,参考:https://developer.qiniu.com/fusion/api/1229/cache-refresh
|
||||
* 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category
|
||||
*/
|
||||
public function refreshDirs(array $dirs)
|
||||
{
|
||||
return $this->refreshUrlsAndDirs(array(), $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $urls 待刷新的文件链接数组
|
||||
* @param array $dirs 待刷新的目录链接数组
|
||||
*
|
||||
* @return array 刷新的请求回复和错误,参考 examples/cdn_manager.php 代码
|
||||
* @link http://developer.qiniu.com/article/fusion/api/refresh.html
|
||||
*
|
||||
* 目前客户默认没有目录刷新权限,刷新会有400038报错,参考:https://developer.qiniu.com/fusion/api/1229/cache-refresh
|
||||
* 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category
|
||||
*/
|
||||
public function refreshUrlsAndDirs(array $urls, array $dirs)
|
||||
{
|
||||
$req = array();
|
||||
if (!empty($urls)) {
|
||||
$req['urls'] = $urls;
|
||||
}
|
||||
if (!empty($dirs)) {
|
||||
$req['dirs'] = $dirs;
|
||||
}
|
||||
|
||||
$url = $this->server . '/v2/tune/refresh';
|
||||
$body = json_encode($req);
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询 CDN 刷新记录
|
||||
*
|
||||
* @param string $requestId 指定要查询记录所在的刷新请求id
|
||||
* @param string $isDir 指定是否查询目录,取值为 yes/no,默认不填则为两种类型记录都查询
|
||||
* @param array $urls 要查询的url列表,每个url可以是文件url,也可以是目录url
|
||||
* @param string $state 指定要查询记录的状态,取值processing/success/failure
|
||||
* @param int $pageNo 要求返回的页号,默认为0
|
||||
* @param int $pageSize 要求返回的页长度,默认为100
|
||||
* @param string $startTime 指定查询的开始日期,格式2006-01-01
|
||||
* @param string $endTime 指定查询的结束日期,格式2006-01-01
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/fusion/api/1229/cache-refresh#4
|
||||
*/
|
||||
public function getCdnRefreshList(
|
||||
$requestId = null,
|
||||
$isDir = null,
|
||||
$urls = array(),
|
||||
$state = null,
|
||||
$pageNo = 0,
|
||||
$pageSize = 100,
|
||||
$startTime = null,
|
||||
$endTime = null
|
||||
) {
|
||||
$req = array();
|
||||
\Qiniu\setWithoutEmpty($req, 'requestId', $requestId);
|
||||
\Qiniu\setWithoutEmpty($req, 'isDir', $isDir);
|
||||
\Qiniu\setWithoutEmpty($req, 'urls', $urls);
|
||||
\Qiniu\setWithoutEmpty($req, 'state', $state);
|
||||
\Qiniu\setWithoutEmpty($req, 'pageNo', $pageNo);
|
||||
\Qiniu\setWithoutEmpty($req, 'pageSize', $pageSize);
|
||||
\Qiniu\setWithoutEmpty($req, 'startTime', $startTime);
|
||||
\Qiniu\setWithoutEmpty($req, 'endTime', $endTime);
|
||||
|
||||
$body = json_encode($req);
|
||||
$url = $this->server . '/v2/tune/refresh/list';
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $urls 待预取的文件链接数组
|
||||
*
|
||||
* @return array 预取的请求回复和错误,参考 examples/cdn_manager.php 代码
|
||||
*
|
||||
* @link http://developer.qiniu.com/article/fusion/api/refresh.html
|
||||
*/
|
||||
public function prefetchUrls(array $urls)
|
||||
{
|
||||
$req = array(
|
||||
'urls' => $urls,
|
||||
);
|
||||
|
||||
$url = $this->server . '/v2/tune/prefetch';
|
||||
$body = json_encode($req);
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询 CDN 预取记录
|
||||
*
|
||||
* @param string $requestId 指定要查询记录所在的刷新请求id
|
||||
* @param array $urls 要查询的url列表,每个url可以是文件url,也可以是目录url
|
||||
* @param string $state 指定要查询记录的状态,取值processing/success/failure
|
||||
* @param int $pageNo 要求返回的页号,默认为0
|
||||
* @param int $pageSize 要求返回的页长度,默认为100
|
||||
* @param string $startTime 指定查询的开始日期,格式2006-01-01
|
||||
* @param string $endTime 指定查询的结束日期,格式2006-01-01
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/fusion/api/1227/file-prefetching#4
|
||||
*/
|
||||
public function getCdnPrefetchList(
|
||||
$requestId = null,
|
||||
$urls = array(),
|
||||
$state = null,
|
||||
$pageNo = 0,
|
||||
$pageSize = 100,
|
||||
$startTime = null,
|
||||
$endTime = null
|
||||
) {
|
||||
$req = array();
|
||||
\Qiniu\setWithoutEmpty($req, 'requestId', $requestId);
|
||||
\Qiniu\setWithoutEmpty($req, 'urls', $urls);
|
||||
\Qiniu\setWithoutEmpty($req, 'state', $state);
|
||||
\Qiniu\setWithoutEmpty($req, 'pageNo', $pageNo);
|
||||
\Qiniu\setWithoutEmpty($req, 'pageSize', $pageSize);
|
||||
\Qiniu\setWithoutEmpty($req, 'startTime', $startTime);
|
||||
\Qiniu\setWithoutEmpty($req, 'endTime', $endTime);
|
||||
|
||||
$body = json_encode($req);
|
||||
$url = $this->server . '/v2/tune/prefetch/list';
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $domains 待获取带宽数据的域名数组
|
||||
* @param string $startDate 开始的日期,格式类似 2017-01-01
|
||||
* @param string $endDate 结束的日期,格式类似 2017-01-01
|
||||
* @param string $granularity 获取数据的时间间隔,可以是 5min, hour 或者 day
|
||||
*
|
||||
* @return array 带宽数据和错误信息,参考 examples/cdn_manager.php 代码
|
||||
*
|
||||
* @link http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
|
||||
*/
|
||||
public function getBandwidthData(array $domains, $startDate, $endDate, $granularity)
|
||||
{
|
||||
$req = array();
|
||||
$req['domains'] = implode(';', $domains);
|
||||
$req['startDate'] = $startDate;
|
||||
$req['endDate'] = $endDate;
|
||||
$req['granularity'] = $granularity;
|
||||
|
||||
$url = $this->server . '/v2/tune/bandwidth';
|
||||
$body = json_encode($req);
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $domains 待获取流量数据的域名数组
|
||||
* @param string $startDate 开始的日期,格式类似 2017-01-01
|
||||
* @param string $endDate 结束的日期,格式类似 2017-01-01
|
||||
* @param string $granularity 获取数据的时间间隔,可以是 5min, hour 或者 day
|
||||
*
|
||||
* @return array 流量数据和错误信息,参考 examples/cdn_manager.php 代码
|
||||
*
|
||||
* @link http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
|
||||
*/
|
||||
public function getFluxData(array $domains, $startDate, $endDate, $granularity)
|
||||
{
|
||||
$req = array();
|
||||
$req['domains'] = implode(';', $domains);
|
||||
$req['startDate'] = $startDate;
|
||||
$req['endDate'] = $endDate;
|
||||
$req['granularity'] = $granularity;
|
||||
|
||||
$url = $this->server . '/v2/tune/flux';
|
||||
$body = json_encode($req);
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $domains 待获取日志下载链接的域名数组
|
||||
* @param string $logDate 获取指定日期的日志下载链接,格式类似 2017-01-01
|
||||
*
|
||||
* @return array 日志下载链接数据和错误信息,参考 examples/cdn_manager.php 代码
|
||||
*
|
||||
* @link http://developer.qiniu.com/article/fusion/api/log.html
|
||||
*/
|
||||
public function getCdnLogList(array $domains, $logDate)
|
||||
{
|
||||
$req = array();
|
||||
$req['domains'] = implode(';', $domains);
|
||||
$req['day'] = $logDate;
|
||||
|
||||
$url = $this->server . '/v2/tune/log/list';
|
||||
$body = json_encode($req);
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
private function post($url, $body)
|
||||
{
|
||||
$headers = $this->auth->authorization($url, $body, 'application/json');
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
$ret = Client::post($url, $body, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
$r = ($ret->body === null) ? array() : $ret->json();
|
||||
return array($r, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建时间戳防盗链鉴权的访问外链
|
||||
*
|
||||
* @param string $rawUrl 需要签名的资源url
|
||||
* @param string $encryptKey 时间戳防盗链密钥
|
||||
* @param string $durationInSeconds 链接的有效期(以秒为单位)
|
||||
*
|
||||
* @return string 带鉴权信息的资源外链,参考 examples/cdn_timestamp_antileech.php 代码
|
||||
*/
|
||||
public static function createTimestampAntiLeechUrl($rawUrl, $encryptKey, $durationInSeconds)
|
||||
{
|
||||
$parsedUrl = parse_url($rawUrl);
|
||||
$deadline = time() + $durationInSeconds;
|
||||
$expireHex = dechex($deadline);
|
||||
$path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
|
||||
$strToSign = $encryptKey . $path . $expireHex;
|
||||
$signStr = md5($strToSign);
|
||||
if (isset($parsedUrl['query'])) {
|
||||
$signedUrl = $rawUrl . '&sign=' . $signStr . '&t=' . $expireHex;
|
||||
} else {
|
||||
$signedUrl = $rawUrl . '?sign=' . $signStr . '&t=' . $expireHex;
|
||||
}
|
||||
return $signedUrl;
|
||||
}
|
||||
}
|
||||
398
vendor/qiniu/php-sdk/src/Qiniu/Config.php
vendored
Normal file
398
vendor/qiniu/php-sdk/src/Qiniu/Config.php
vendored
Normal file
@ -0,0 +1,398 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu;
|
||||
|
||||
final class Config
|
||||
{
|
||||
const SDK_VER = '7.14.0';
|
||||
|
||||
const BLOCK_SIZE = 4194304; //4*1024*1024 分块上传块大小,该参数为接口规格,不能修改
|
||||
|
||||
const RSF_HOST = 'rsf.qiniuapi.com';
|
||||
const API_HOST = 'api.qiniuapi.com';
|
||||
const RS_HOST = 'rs.qiniuapi.com'; // RS Host
|
||||
const UC_HOST = 'uc.qiniuapi.com'; // UC Host
|
||||
const QUERY_REGION_HOST = Config::UC_HOST;
|
||||
const RTCAPI_HOST = 'http://rtc.qiniuapi.com';
|
||||
const ARGUS_HOST = 'ai.qiniuapi.com';
|
||||
const CASTER_HOST = 'pili-caster.qiniuapi.com';
|
||||
const SMS_HOST = "https://sms.qiniuapi.com";
|
||||
const RTCAPI_VERSION = 'v3';
|
||||
const SMS_VERSION = 'v1';
|
||||
|
||||
// Zone 空间对应的存储区域
|
||||
public $region;
|
||||
//BOOL 是否使用https域名
|
||||
public $useHTTPS;
|
||||
//BOOL 是否使用CDN加速上传域名
|
||||
public $useCdnDomains;
|
||||
/**
|
||||
* @var Region
|
||||
*/
|
||||
public $zone;
|
||||
// Zone Cache
|
||||
private $regionCache;
|
||||
// UC Host
|
||||
private $ucHost;
|
||||
private $queryRegionHost;
|
||||
// backup UC Hosts
|
||||
private $backupQueryRegionHosts;
|
||||
// backup UC Hosts max retry time
|
||||
public $backupUcHostsRetryTimes;
|
||||
|
||||
// 构造函数
|
||||
public function __construct(Region $z = null)
|
||||
{
|
||||
$this->zone = $z;
|
||||
$this->useHTTPS = false;
|
||||
$this->useCdnDomains = false;
|
||||
$this->regionCache = array();
|
||||
$this->ucHost = Config::UC_HOST;
|
||||
$this->queryRegionHost = Config::QUERY_REGION_HOST;
|
||||
$this->backupQueryRegionHosts = array(
|
||||
"kodo-config.qiniuapi.com",
|
||||
"uc.qbox.me",
|
||||
);
|
||||
$this->backupUcHostsRetryTimes = 2;
|
||||
}
|
||||
|
||||
public function setUcHost($ucHost)
|
||||
{
|
||||
$this->ucHost = $ucHost;
|
||||
$this->setQueryRegionHost($ucHost);
|
||||
}
|
||||
|
||||
public function getUcHost()
|
||||
{
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return $scheme . $this->ucHost;
|
||||
}
|
||||
|
||||
public function setQueryRegionHost($host, $backupHosts = array())
|
||||
{
|
||||
$this->queryRegionHost = $host;
|
||||
$this->backupQueryRegionHosts = $backupHosts;
|
||||
}
|
||||
|
||||
public function getQueryRegionHost()
|
||||
{
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return $scheme . $this->queryRegionHost;
|
||||
}
|
||||
|
||||
public function setBackupQueryRegionHosts($hosts = array())
|
||||
{
|
||||
$this->backupQueryRegionHosts = $hosts;
|
||||
}
|
||||
|
||||
public function getBackupQueryRegionHosts()
|
||||
{
|
||||
return $this->backupQueryRegionHosts;
|
||||
}
|
||||
|
||||
public function getUpHost($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
$region = $this->getRegion($accessKey, $bucket, $reqOpt);
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
$host = $region->srcUpHosts[0];
|
||||
if ($this->useCdnDomains === true) {
|
||||
$host = $region->cdnUpHosts[0];
|
||||
}
|
||||
|
||||
return $scheme . $host;
|
||||
}
|
||||
|
||||
public function getUpHostV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
list($region, $err) = $this->getRegionV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
$host = $region->srcUpHosts[0];
|
||||
if ($this->useCdnDomains === true) {
|
||||
$host = $region->cdnUpHosts[0];
|
||||
}
|
||||
|
||||
return array($scheme . $host, null);
|
||||
}
|
||||
|
||||
public function getUpBackupHost($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
$region = $this->getRegion($accessKey, $bucket, $reqOpt);
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
$host = $region->cdnUpHosts[0];
|
||||
if ($this->useCdnDomains === true) {
|
||||
$host = $region->srcUpHosts[0];
|
||||
}
|
||||
|
||||
return $scheme . $host;
|
||||
}
|
||||
|
||||
public function getUpBackupHostV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
list($region, $err) = $this->getRegionV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
$host = $region->cdnUpHosts[0];
|
||||
if ($this->useCdnDomains === true) {
|
||||
$host = $region->srcUpHosts[0];
|
||||
}
|
||||
|
||||
return array($scheme . $host, null);
|
||||
}
|
||||
|
||||
public function getRsHost($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
$region = $this->getRegion($accessKey, $bucket, $reqOpt);
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return $scheme . $region->rsHost;
|
||||
}
|
||||
|
||||
public function getRsHostV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
list($region, $err) = $this->getRegionV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return array($scheme . $region->rsHost, null);
|
||||
}
|
||||
|
||||
public function getRsfHost($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
$region = $this->getRegion($accessKey, $bucket, $reqOpt);
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return $scheme . $region->rsfHost;
|
||||
}
|
||||
|
||||
public function getRsfHostV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
list($region, $err) = $this->getRegionV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return array($scheme . $region->rsfHost, null);
|
||||
}
|
||||
|
||||
public function getIovipHost($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
$region = $this->getRegion($accessKey, $bucket, $reqOpt);
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return $scheme . $region->iovipHost;
|
||||
}
|
||||
|
||||
public function getIovipHostV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
list($region, $err) = $this->getRegionV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return array($scheme . $region->iovipHost, null);
|
||||
}
|
||||
|
||||
public function getApiHost($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
$region = $this->getRegion($accessKey, $bucket, $reqOpt);
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return $scheme . $region->apiHost;
|
||||
}
|
||||
|
||||
public function getApiHostV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
list($region, $err) = $this->getRegionV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
if ($this->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
} else {
|
||||
$scheme = "http://";
|
||||
}
|
||||
|
||||
return array($scheme . $region->apiHost, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从缓存中获取区域
|
||||
*
|
||||
* @param string $cacheId 缓存 ID
|
||||
* @return null|Region
|
||||
*/
|
||||
private function getRegionCache($cacheId)
|
||||
{
|
||||
if (isset($this->regionCache[$cacheId]) &&
|
||||
isset($this->regionCache[$cacheId]["deadline"]) &&
|
||||
time() < $this->regionCache[$cacheId]["deadline"]) {
|
||||
return $this->regionCache[$cacheId]["region"];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将区域设置到缓存中
|
||||
*
|
||||
* @param string $cacheId 缓存 ID
|
||||
* @param Region $region 缓存 ID
|
||||
* @return void
|
||||
*/
|
||||
private function setRegionCache($cacheId, $region)
|
||||
{
|
||||
$this->regionCache[$cacheId] = array(
|
||||
"region" => $region,
|
||||
);
|
||||
if (isset($region->ttl)) {
|
||||
$this->regionCache[$cacheId]["deadline"] = time() + $region->ttl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获取区域
|
||||
*
|
||||
* @param string $accessKey
|
||||
* @param string $bucket
|
||||
* @return Region
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getRegion($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
if (isset($this->zone)) {
|
||||
return $this->zone;
|
||||
}
|
||||
|
||||
$cacheId = "$accessKey:$bucket";
|
||||
$regionCache = $this->getRegionCache($cacheId);
|
||||
if ($regionCache) {
|
||||
return $regionCache;
|
||||
}
|
||||
|
||||
$region = Zone::queryZone(
|
||||
$accessKey,
|
||||
$bucket,
|
||||
$this->getQueryRegionHost(),
|
||||
$this->getBackupQueryRegionHosts(),
|
||||
$this->backupUcHostsRetryTimes,
|
||||
$reqOpt
|
||||
);
|
||||
if (is_array($region)) {
|
||||
list($region, $err) = $region;
|
||||
if ($err != null) {
|
||||
throw new \Exception($err->message());
|
||||
}
|
||||
}
|
||||
|
||||
$this->setRegionCache($cacheId, $region);
|
||||
return $region;
|
||||
}
|
||||
|
||||
private function getRegionV2($accessKey, $bucket, $reqOpt = null)
|
||||
{
|
||||
if (isset($this->zone)) {
|
||||
return array($this->zone, null);
|
||||
}
|
||||
|
||||
$cacheId = "$accessKey:$bucket";
|
||||
$regionCache = $this->getRegionCache($cacheId);
|
||||
if (isset($regionCache)) {
|
||||
return array($regionCache, null);
|
||||
}
|
||||
|
||||
$region = Zone::queryZone(
|
||||
$accessKey,
|
||||
$bucket,
|
||||
$this->getQueryRegionHost(),
|
||||
$this->getBackupQueryRegionHosts(),
|
||||
$this->backupUcHostsRetryTimes,
|
||||
$reqOpt
|
||||
);
|
||||
if (is_array($region)) {
|
||||
list($region, $err) = $region;
|
||||
return array($region, $err);
|
||||
}
|
||||
|
||||
$this->setRegionCache($cacheId, $region);
|
||||
return array($region, null);
|
||||
}
|
||||
}
|
||||
53
vendor/qiniu/php-sdk/src/Qiniu/Enum/QiniuEnum.php
vendored
Normal file
53
vendor/qiniu/php-sdk/src/Qiniu/Enum/QiniuEnum.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// @codingStandardsIgnoreStart
|
||||
// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
|
||||
namespace Qiniu\Enum;
|
||||
|
||||
use MyCLabs\Enum\Enum;
|
||||
|
||||
if (method_exists("MyCLabs\\Enum\\Enum", "from")) {
|
||||
abstract class QiniuEnum extends Enum
|
||||
{
|
||||
// @codingStandardsIgnoreEnd
|
||||
// @codingStandardsIgnoreStart
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* poly fill MyCLabs\Enum\Enum::from in low version
|
||||
*
|
||||
* @link https://github.com/myclabs/php-enum
|
||||
*/
|
||||
abstract class QiniuEnum extends Enum
|
||||
{
|
||||
// @codingStandardsIgnoreEnd
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return static
|
||||
*/
|
||||
public static function from($value)
|
||||
{
|
||||
$key = self::assertValidValueReturningKey($value);
|
||||
|
||||
return self::__callStatic($key, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts valid enum value
|
||||
*
|
||||
* @psalm-pure
|
||||
* @psalm-assert T $value
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
private static function assertValidValueReturningKey($value)
|
||||
{
|
||||
if (false === ($key = self::search($value))) {
|
||||
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . __CLASS__);
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
// @codingStandardsIgnoreStart
|
||||
}
|
||||
}
|
||||
9
vendor/qiniu/php-sdk/src/Qiniu/Enum/SplitUploadVersion.php
vendored
Normal file
9
vendor/qiniu/php-sdk/src/Qiniu/Enum/SplitUploadVersion.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Enum;
|
||||
|
||||
final class SplitUploadVersion extends QiniuEnum
|
||||
{
|
||||
const V1 = 'v1';
|
||||
const V2 = 'v2';
|
||||
}
|
||||
76
vendor/qiniu/php-sdk/src/Qiniu/Etag.php
vendored
Normal file
76
vendor/qiniu/php-sdk/src/Qiniu/Etag.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu;
|
||||
|
||||
use Qiniu\Config;
|
||||
|
||||
final class Etag
|
||||
{
|
||||
private static function packArray($v, $a)
|
||||
{
|
||||
return call_user_func_array('pack', array_merge(array($v), (array)$a));
|
||||
}
|
||||
|
||||
private static function blockCount($fsize)
|
||||
{
|
||||
return intval(($fsize + (Config::BLOCK_SIZE - 1)) / Config::BLOCK_SIZE);
|
||||
}
|
||||
|
||||
private static function calcSha1($data)
|
||||
{
|
||||
$sha1Str = sha1($data, true);
|
||||
$err = error_get_last();
|
||||
if ($err !== null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
$byteArray = unpack('C*', $sha1Str);
|
||||
return array($byteArray, null);
|
||||
}
|
||||
|
||||
|
||||
public static function sum($filename)
|
||||
{
|
||||
$fhandler = fopen($filename, 'r');
|
||||
$err = error_get_last();
|
||||
if ($err !== null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$fstat = fstat($fhandler);
|
||||
$fsize = $fstat['size'];
|
||||
if ((int)$fsize === 0) {
|
||||
fclose($fhandler);
|
||||
return array('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', null);
|
||||
}
|
||||
$blockCnt = self::blockCount($fsize);
|
||||
$sha1Buf = array();
|
||||
|
||||
if ($blockCnt <= 1) {
|
||||
array_push($sha1Buf, 0x16);
|
||||
$fdata = fread($fhandler, Config::BLOCK_SIZE);
|
||||
if ($err !== null) {
|
||||
fclose($fhandler);
|
||||
return array(null, $err);
|
||||
}
|
||||
list($sha1Code,) = self::calcSha1($fdata);
|
||||
$sha1Buf = array_merge($sha1Buf, $sha1Code);
|
||||
} else {
|
||||
array_push($sha1Buf, 0x96);
|
||||
$sha1BlockBuf = array();
|
||||
for ($i = 0; $i < $blockCnt; $i++) {
|
||||
$fdata = fread($fhandler, Config::BLOCK_SIZE);
|
||||
list($sha1Code, $err) = self::calcSha1($fdata);
|
||||
if ($err !== null) {
|
||||
fclose($fhandler);
|
||||
return array(null, $err);
|
||||
}
|
||||
$sha1BlockBuf = array_merge($sha1BlockBuf, $sha1Code);
|
||||
}
|
||||
$tmpData = self::packArray('C*', $sha1BlockBuf);
|
||||
list($sha1Final,) = self::calcSha1($tmpData);
|
||||
$sha1Buf = array_merge($sha1Buf, $sha1Final);
|
||||
}
|
||||
$etag = \Qiniu\base64_urlSafeEncode(self::packArray('C*', $sha1Buf));
|
||||
return array($etag, null);
|
||||
}
|
||||
}
|
||||
198
vendor/qiniu/php-sdk/src/Qiniu/Http/Client.php
vendored
Normal file
198
vendor/qiniu/php-sdk/src/Qiniu/Http/Client.php
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Http;
|
||||
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\Middleware;
|
||||
|
||||
final class Client
|
||||
{
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @param RequestOptions $opt
|
||||
* @return Response
|
||||
*/
|
||||
public static function get($url, array $headers = array(), $opt = null)
|
||||
{
|
||||
$request = new Request('GET', $url, $headers, null, $opt);
|
||||
return self::sendRequestWithMiddleware($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @param array $opt detail see {@see Request::$opt}
|
||||
* @return Response
|
||||
*/
|
||||
public static function delete($url, array $headers = array(), $opt = null)
|
||||
{
|
||||
$request = new Request('DELETE', $url, $headers, null, $opt);
|
||||
return self::sendRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @param RequestOptions $opt
|
||||
* @return Response
|
||||
*/
|
||||
public static function post($url, $body, array $headers = array(), $opt = null)
|
||||
{
|
||||
$request = new Request('POST', $url, $headers, $body, $opt);
|
||||
return self::sendRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @param RequestOptions $opt
|
||||
* @return Response
|
||||
*/
|
||||
public static function PUT($url, $body, array $headers = array(), $opt = null)
|
||||
{
|
||||
$request = new Request('PUT', $url, $headers, $body, $opt);
|
||||
return self::sendRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $fields
|
||||
* @param string $name
|
||||
* @param string $fileName
|
||||
* @param $fileBody
|
||||
* @param null $mimeType
|
||||
* @param array $headers
|
||||
* @param RequestOptions $opt
|
||||
* @return Response
|
||||
*/
|
||||
public static function multipartPost(
|
||||
$url,
|
||||
$fields,
|
||||
$name,
|
||||
$fileName,
|
||||
$fileBody,
|
||||
$mimeType = null,
|
||||
$headers = array(),
|
||||
$opt = null
|
||||
) {
|
||||
$data = array();
|
||||
$mimeBoundary = md5(microtime());
|
||||
|
||||
foreach ($fields as $key => $val) {
|
||||
array_push($data, '--' . $mimeBoundary);
|
||||
array_push($data, "Content-Disposition: form-data; name=\"$key\"");
|
||||
array_push($data, '');
|
||||
array_push($data, $val);
|
||||
}
|
||||
|
||||
array_push($data, '--' . $mimeBoundary);
|
||||
$finalMimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType;
|
||||
$finalFileName = self::escapeQuotes($fileName);
|
||||
array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$finalFileName\"");
|
||||
array_push($data, "Content-Type: $finalMimeType");
|
||||
array_push($data, '');
|
||||
array_push($data, $fileBody);
|
||||
|
||||
array_push($data, '--' . $mimeBoundary . '--');
|
||||
array_push($data, '');
|
||||
|
||||
$body = implode("\r\n", $data);
|
||||
$contentType = 'multipart/form-data; boundary=' . $mimeBoundary;
|
||||
$headers['Content-Type'] = $contentType;
|
||||
$request = new Request('POST', $url, $headers, $body, $opt);
|
||||
return self::sendRequest($request);
|
||||
}
|
||||
|
||||
private static function userAgent()
|
||||
{
|
||||
$sdkInfo = "QiniuPHP/" . Config::SDK_VER;
|
||||
|
||||
$systemInfo = php_uname("s");
|
||||
$machineInfo = php_uname("m");
|
||||
|
||||
$envInfo = "($systemInfo/$machineInfo)";
|
||||
|
||||
$phpVer = phpversion();
|
||||
|
||||
$ua = "$sdkInfo $envInfo PHP/$phpVer";
|
||||
return $ua;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public static function sendRequestWithMiddleware($request)
|
||||
{
|
||||
$middlewares = $request->opt->middlewares;
|
||||
$handle = Middleware\compose($middlewares, function ($req) {
|
||||
return Client::sendRequest($req);
|
||||
});
|
||||
return $handle($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public static function sendRequest($request)
|
||||
{
|
||||
$t1 = microtime(true);
|
||||
$ch = curl_init();
|
||||
$options = array(
|
||||
CURLOPT_USERAGENT => self::userAgent(),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_NOBODY => false,
|
||||
CURLOPT_CUSTOMREQUEST => $request->method,
|
||||
CURLOPT_URL => $request->url,
|
||||
);
|
||||
foreach ($request->opt->getCurlOpt() as $k => $v) {
|
||||
$options[$k] = $v;
|
||||
}
|
||||
// Handle open_basedir & safe mode
|
||||
if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
|
||||
$options[CURLOPT_FOLLOWLOCATION] = true;
|
||||
}
|
||||
if (!empty($request->headers)) {
|
||||
$headers = array();
|
||||
foreach ($request->headers as $key => $val) {
|
||||
array_push($headers, "$key: $val");
|
||||
}
|
||||
$options[CURLOPT_HTTPHEADER] = $headers;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
|
||||
if (!empty($request->body)) {
|
||||
$options[CURLOPT_POSTFIELDS] = $request->body;
|
||||
}
|
||||
curl_setopt_array($ch, $options);
|
||||
$result = curl_exec($ch);
|
||||
$t2 = microtime(true);
|
||||
$duration = round($t2 - $t1, 3);
|
||||
$ret = curl_errno($ch);
|
||||
if ($ret !== 0) {
|
||||
$r = new Response(-1, $duration, array(), null, curl_error($ch));
|
||||
curl_close($ch);
|
||||
return $r;
|
||||
}
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$headers = Header::parseRawText(substr($result, 0, $header_size));
|
||||
$body = substr($result, $header_size);
|
||||
curl_close($ch);
|
||||
return new Response($code, $duration, $headers, $body, null);
|
||||
}
|
||||
|
||||
private static function escapeQuotes($str)
|
||||
{
|
||||
if (is_null($str)) {
|
||||
return null;
|
||||
}
|
||||
$find = array("\\", "\"");
|
||||
$replace = array("\\\\", "\\\"");
|
||||
return str_replace($find, $replace, $str);
|
||||
}
|
||||
}
|
||||
38
vendor/qiniu/php-sdk/src/Qiniu/Http/Error.php
vendored
Normal file
38
vendor/qiniu/php-sdk/src/Qiniu/Http/Error.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace Qiniu\Http;
|
||||
|
||||
/**
|
||||
* 七牛业务请求逻辑错误封装类,主要用来解析API请求返回如下的内容:
|
||||
* <pre>
|
||||
* {"error" : "detailed error message"}
|
||||
* </pre>
|
||||
*/
|
||||
final class Error
|
||||
{
|
||||
private $url;
|
||||
/**
|
||||
* @var Response
|
||||
*/
|
||||
private $response;
|
||||
|
||||
public function __construct($url, $response)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
public function code()
|
||||
{
|
||||
return $this->response->statusCode;
|
||||
}
|
||||
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function message()
|
||||
{
|
||||
return $this->response->error;
|
||||
}
|
||||
}
|
||||
291
vendor/qiniu/php-sdk/src/Qiniu/Http/Header.php
vendored
Normal file
291
vendor/qiniu/php-sdk/src/Qiniu/Http/Header.php
vendored
Normal file
@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Http;
|
||||
|
||||
/**
|
||||
* field name case-insensitive Header
|
||||
*/
|
||||
class Header implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
{
|
||||
/** @var array normalized key name map */
|
||||
private $data = array();
|
||||
|
||||
/**
|
||||
* @param array $obj non-normalized header object
|
||||
*/
|
||||
public function __construct($obj = array())
|
||||
{
|
||||
foreach ($obj as $key => $values) {
|
||||
$normalizedKey = self::normalizeKey($key);
|
||||
$normalizedValues = array();
|
||||
if (!is_array($values)) {
|
||||
array_push(
|
||||
$normalizedValues,
|
||||
self::normalizeValue($values)
|
||||
);
|
||||
} else {
|
||||
foreach ($values as $value) {
|
||||
array_push(
|
||||
$normalizedValues,
|
||||
self::normalizeValue($value)
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->data[$normalizedKey] = $normalizedValues;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* return origin headers, which is field name case-sensitive
|
||||
*
|
||||
* @param string $raw
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parseRawText($raw)
|
||||
{
|
||||
$multipleHeaders = explode("\r\n\r\n", trim($raw));
|
||||
$headers = array();
|
||||
$headerLines = explode("\r\n", end($multipleHeaders));
|
||||
foreach ($headerLines as $line) {
|
||||
$headerLine = trim($line);
|
||||
$kv = explode(':', $headerLine);
|
||||
if (count($kv) <= 1) {
|
||||
continue;
|
||||
}
|
||||
// for http2 [Pseudo-Header Fields](https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.1)
|
||||
if ($kv[0] == "") {
|
||||
$fieldName = ":" . $kv[1];
|
||||
} else {
|
||||
$fieldName = $kv[0];
|
||||
}
|
||||
$fieldValue = trim(substr($headerLine, strlen($fieldName . ":")));
|
||||
if (isset($headers[$fieldName])) {
|
||||
array_push($headers[$fieldName], $fieldValue);
|
||||
} else {
|
||||
$headers[$fieldName] = array($fieldValue);
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $raw
|
||||
*
|
||||
* @return Header
|
||||
*/
|
||||
public static function fromRawText($raw)
|
||||
{
|
||||
return new Header(self::parseRawText($raw));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function normalizeKey($key)
|
||||
{
|
||||
$key = trim($key);
|
||||
|
||||
if (!self::isValidKeyName($key)) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
return \Qiniu\ucwords(strtolower($key), '-');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|numeric $value
|
||||
*
|
||||
* @return string|numeric
|
||||
*/
|
||||
public static function normalizeValue($value)
|
||||
{
|
||||
if (is_numeric($value)) {
|
||||
return $value + 0;
|
||||
}
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRawData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset string
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
#[\ReturnTypeWillChange] // temporarily suppress the type check of php 8.x
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$key = self::normalizeKey($offset);
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset string
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange] // temporarily suppress the type check of php 8.x
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$key = self::normalizeKey($offset);
|
||||
if (isset($this->data[$key]) && count($this->data[$key])) {
|
||||
return $this->data[$key][0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset string
|
||||
* @param $value string
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange] // temporarily suppress the type check of php 8.x
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$key = self::normalizeKey($offset);
|
||||
if (isset($this->data[$key]) && count($this->data[$key]) > 0) {
|
||||
$this->data[$key][0] = self::normalizeValue($value);
|
||||
} else {
|
||||
$this->data[$key] = array(self::normalizeValue($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange] // temporarily suppress the type check of php 8.x
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$key = self::normalizeKey($offset);
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange] // temporarily suppress the type check of php 8.x
|
||||
public function getIterator()
|
||||
{
|
||||
$arr = array();
|
||||
foreach ($this->data as $k => $v) {
|
||||
$arr[$k] = $v[0];
|
||||
}
|
||||
return new \ArrayIterator($arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange] // temporarily suppress the type check of php 8.x
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
private static $isTokenTable = array(
|
||||
'!' => true,
|
||||
'#' => true,
|
||||
'$' => true,
|
||||
'%' => true,
|
||||
'&' => true,
|
||||
'\'' => true,
|
||||
'*' => true,
|
||||
'+' => true,
|
||||
'-' => true,
|
||||
'.' => true,
|
||||
'0' => true,
|
||||
'1' => true,
|
||||
'2' => true,
|
||||
'3' => true,
|
||||
'4' => true,
|
||||
'5' => true,
|
||||
'6' => true,
|
||||
'7' => true,
|
||||
'8' => true,
|
||||
'9' => true,
|
||||
'A' => true,
|
||||
'B' => true,
|
||||
'C' => true,
|
||||
'D' => true,
|
||||
'E' => true,
|
||||
'F' => true,
|
||||
'G' => true,
|
||||
'H' => true,
|
||||
'I' => true,
|
||||
'J' => true,
|
||||
'K' => true,
|
||||
'L' => true,
|
||||
'M' => true,
|
||||
'N' => true,
|
||||
'O' => true,
|
||||
'P' => true,
|
||||
'Q' => true,
|
||||
'R' => true,
|
||||
'S' => true,
|
||||
'T' => true,
|
||||
'U' => true,
|
||||
'W' => true,
|
||||
'V' => true,
|
||||
'X' => true,
|
||||
'Y' => true,
|
||||
'Z' => true,
|
||||
'^' => true,
|
||||
'_' => true,
|
||||
'`' => true,
|
||||
'a' => true,
|
||||
'b' => true,
|
||||
'c' => true,
|
||||
'd' => true,
|
||||
'e' => true,
|
||||
'f' => true,
|
||||
'g' => true,
|
||||
'h' => true,
|
||||
'i' => true,
|
||||
'j' => true,
|
||||
'k' => true,
|
||||
'l' => true,
|
||||
'm' => true,
|
||||
'n' => true,
|
||||
'o' => true,
|
||||
'p' => true,
|
||||
'q' => true,
|
||||
'r' => true,
|
||||
's' => true,
|
||||
't' => true,
|
||||
'u' => true,
|
||||
'v' => true,
|
||||
'w' => true,
|
||||
'x' => true,
|
||||
'y' => true,
|
||||
'z' => true,
|
||||
'|' => true,
|
||||
'~' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private static function isValidKeyName($str)
|
||||
{
|
||||
for ($i = 0; $i < strlen($str); $i += 1) {
|
||||
if (!isset(self::$isTokenTable[$str[$i]])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
31
vendor/qiniu/php-sdk/src/Qiniu/Http/Middleware/Middleware.php
vendored
Normal file
31
vendor/qiniu/php-sdk/src/Qiniu/Http/Middleware/Middleware.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace Qiniu\Http\Middleware;
|
||||
|
||||
use Qiniu\Http\Request;
|
||||
use Qiniu\Http\Response;
|
||||
|
||||
interface Middleware
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param callable(Request): Response $next
|
||||
* @return Response
|
||||
*/
|
||||
public function send($request, $next);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<Middleware> $middlewares
|
||||
* @param callable(Request): Response $handler
|
||||
* @return callable(Request): Response
|
||||
*/
|
||||
function compose($middlewares, $handler)
|
||||
{
|
||||
$next = $handler;
|
||||
foreach (array_reverse($middlewares) as $middleware) {
|
||||
$next = function ($request) use ($middleware, $next) {
|
||||
return $middleware->send($request, $next);
|
||||
};
|
||||
}
|
||||
return $next;
|
||||
}
|
||||
76
vendor/qiniu/php-sdk/src/Qiniu/Http/Middleware/RetryDomainsMiddleware.php
vendored
Normal file
76
vendor/qiniu/php-sdk/src/Qiniu/Http/Middleware/RetryDomainsMiddleware.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace Qiniu\Http\Middleware;
|
||||
|
||||
use Qiniu\Http\Request;
|
||||
use Qiniu\Http\Response;
|
||||
|
||||
class RetryDomainsMiddleware implements Middleware
|
||||
{
|
||||
/**
|
||||
* @var array<string> backup domains.
|
||||
*/
|
||||
private $backupDomains;
|
||||
|
||||
/**
|
||||
* @var numeric max retry times for each backup domains.
|
||||
*/
|
||||
private $maxRetryTimes;
|
||||
|
||||
/**
|
||||
* @var callable args response and request; returns bool; If true will retry with backup domains.
|
||||
*/
|
||||
private $retryCondition;
|
||||
|
||||
/**
|
||||
* @param array<string> $backupDomains
|
||||
* @param numeric $maxRetryTimes
|
||||
*/
|
||||
public function __construct($backupDomains, $maxRetryTimes = 2, $retryCondition = null)
|
||||
{
|
||||
$this->backupDomains = $backupDomains;
|
||||
$this->maxRetryTimes = $maxRetryTimes;
|
||||
$this->retryCondition = $retryCondition;
|
||||
}
|
||||
|
||||
private function shouldRetry($resp, $req)
|
||||
{
|
||||
if (is_callable($this->retryCondition)) {
|
||||
return call_user_func($this->retryCondition, $resp, $req);
|
||||
}
|
||||
|
||||
return !$resp || $resp->needRetry();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param callable(Request): Response $next
|
||||
* @return Response
|
||||
*/
|
||||
public function send($request, $next)
|
||||
{
|
||||
$response = null;
|
||||
$urlComponents = parse_url($request->url);
|
||||
|
||||
foreach (array_merge(array($urlComponents["host"]), $this->backupDomains) as $backupDomain) {
|
||||
$urlComponents["host"] = $backupDomain;
|
||||
$request->url = \Qiniu\unparse_url($urlComponents);
|
||||
$retriedTimes = 0;
|
||||
|
||||
while ($retriedTimes < $this->maxRetryTimes) {
|
||||
$response = $next($request);
|
||||
|
||||
$retriedTimes += 1;
|
||||
|
||||
if (!$this->shouldRetry($response, $request)) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$response) {
|
||||
$response = $next($request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
34
vendor/qiniu/php-sdk/src/Qiniu/Http/Proxy.php
vendored
Normal file
34
vendor/qiniu/php-sdk/src/Qiniu/Http/Proxy.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Http;
|
||||
|
||||
use Qiniu\Http\RequestOptions;
|
||||
|
||||
final class Proxy
|
||||
{
|
||||
private $proxy;
|
||||
private $proxy_auth;
|
||||
private $proxy_user_password;
|
||||
|
||||
public function __construct($proxy = null, $proxy_auth = null, $proxy_user_password = null)
|
||||
{
|
||||
$this->proxy = $proxy;
|
||||
$this->proxy_auth = $proxy_auth;
|
||||
$this->proxy_user_password = $proxy_user_password;
|
||||
}
|
||||
|
||||
public function makeReqOpt()
|
||||
{
|
||||
$reqOpt = new RequestOptions();
|
||||
if ($this->proxy !== null) {
|
||||
$reqOpt->proxy = $this->proxy;
|
||||
}
|
||||
if ($this->proxy_auth !== null) {
|
||||
$reqOpt->proxy_auth = $this->proxy_auth;
|
||||
}
|
||||
if ($this->proxy_user_password !== null) {
|
||||
$reqOpt->proxy_user_password = $this->proxy_user_password;
|
||||
}
|
||||
return $reqOpt;
|
||||
}
|
||||
}
|
||||
42
vendor/qiniu/php-sdk/src/Qiniu/Http/Request.php
vendored
Normal file
42
vendor/qiniu/php-sdk/src/Qiniu/Http/Request.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace Qiniu\Http;
|
||||
|
||||
final class Request
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public $headers;
|
||||
|
||||
/**
|
||||
* @var mixed|null
|
||||
*/
|
||||
public $body;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $method;
|
||||
|
||||
/**
|
||||
* @var RequestOptions
|
||||
*/
|
||||
public $opt;
|
||||
|
||||
public function __construct($method, $url, array $headers = array(), $body = null, $opt = null)
|
||||
{
|
||||
$this->method = strtoupper($method);
|
||||
$this->url = $url;
|
||||
$this->headers = $headers;
|
||||
$this->body = $body;
|
||||
if ($opt === null) {
|
||||
$opt = new RequestOptions();
|
||||
}
|
||||
$this->opt = $opt;
|
||||
}
|
||||
}
|
||||
104
vendor/qiniu/php-sdk/src/Qiniu/Http/RequestOptions.php
vendored
Normal file
104
vendor/qiniu/php-sdk/src/Qiniu/Http/RequestOptions.php
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Http;
|
||||
|
||||
use Qiniu\Http\Middleware\Middleware;
|
||||
|
||||
final class RequestOptions
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* http 请求的超时时间,单位:秒,默认:0,不超时
|
||||
*/
|
||||
public $connection_timeout;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* http 请求的超时时间,单位:毫秒,默认:0,不超时
|
||||
*/
|
||||
public $connection_timeout_ms;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* http 请求的超时时间,单位:秒,默认:0,不超时
|
||||
*/
|
||||
public $timeout;
|
||||
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* http 请求的超时时间,单位:毫秒,默认:0,不超时
|
||||
*/
|
||||
public $timeout_ms;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
* 代理URL,默认:空
|
||||
*/
|
||||
public $proxy;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* 代理鉴权方式,默认:空
|
||||
*/
|
||||
public $proxy_auth;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
* 代理鉴权参数,默认:空
|
||||
*/
|
||||
public $proxy_user_password;
|
||||
|
||||
/**
|
||||
* @var array<Middleware>
|
||||
*/
|
||||
public $middlewares;
|
||||
|
||||
public function __construct(
|
||||
$connection_timeout = null,
|
||||
$connection_timeout_ms = null,
|
||||
$timeout = null,
|
||||
$timeout_ms = null,
|
||||
$middlewares = array(),
|
||||
$proxy = null,
|
||||
$proxy_auth = null,
|
||||
$proxy_user_password = null
|
||||
) {
|
||||
$this->connection_timeout = $connection_timeout;
|
||||
$this->connection_timeout_ms = $connection_timeout_ms;
|
||||
$this->timeout = $timeout;
|
||||
$this->timeout_ms = $timeout_ms;
|
||||
$this->proxy = $proxy;
|
||||
$this->proxy_auth = $proxy_auth;
|
||||
$this->proxy_user_password = $proxy_user_password;
|
||||
$this->middlewares = $middlewares;
|
||||
}
|
||||
|
||||
public function getCurlOpt()
|
||||
{
|
||||
$result = array();
|
||||
if ($this->connection_timeout != null) {
|
||||
$result[CURLOPT_CONNECTTIMEOUT] = $this->connection_timeout;
|
||||
}
|
||||
if ($this->connection_timeout_ms != null) {
|
||||
$result[CURLOPT_CONNECTTIMEOUT_MS] = $this->connection_timeout_ms;
|
||||
}
|
||||
if ($this->timeout != null) {
|
||||
$result[CURLOPT_TIMEOUT] = $this->timeout;
|
||||
}
|
||||
if ($this->timeout_ms != null) {
|
||||
$result[CURLOPT_TIMEOUT_MS] = $this->timeout_ms;
|
||||
}
|
||||
if ($this->proxy != null) {
|
||||
$result[CURLOPT_PROXY] = $this->proxy;
|
||||
}
|
||||
if ($this->proxy_auth != null) {
|
||||
$result[CURLOPT_PROXYAUTH] = $this->proxy_auth;
|
||||
}
|
||||
if ($this->proxy_user_password != null) {
|
||||
$result[CURLOPT_PROXYUSERPWD] = $this->proxy_user_password;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
220
vendor/qiniu/php-sdk/src/Qiniu/Http/Response.php
vendored
Normal file
220
vendor/qiniu/php-sdk/src/Qiniu/Http/Response.php
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Http;
|
||||
|
||||
/**
|
||||
* HTTP response Object
|
||||
*/
|
||||
final class Response
|
||||
{
|
||||
public $statusCode;
|
||||
/**
|
||||
* deprecated because of field names case-sensitive.
|
||||
* use $normalizedHeaders instead which field names are case-insensitive.
|
||||
* but be careful not to use $normalizedHeaders with `array_*` functions,
|
||||
* such as `array_key_exists`, `array_keys`, `array_values`.
|
||||
*
|
||||
* use `isset` instead of `array_key_exists`,
|
||||
* and should never use `array_key_exists` at http header.
|
||||
*
|
||||
* use `foreach` instead of `array_keys`, `array_values`.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public $headers;
|
||||
public $normalizedHeaders;
|
||||
public $body;
|
||||
public $error;
|
||||
private $jsonData;
|
||||
public $duration;
|
||||
|
||||
/** @var array Mapping of status codes to reason phrases */
|
||||
private static $statusTexts = array(
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
102 => 'Processing',
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
207 => 'Multi-Status',
|
||||
208 => 'Already Reported',
|
||||
226 => 'IM Used',
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
308 => 'Permanent Redirect',
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
422 => 'Unprocessable Entity',
|
||||
423 => 'Locked',
|
||||
424 => 'Failed Dependency',
|
||||
425 => 'Reserved for WebDAV advanced collections expired proposal',
|
||||
426 => 'Upgrade required',
|
||||
428 => 'Precondition Required',
|
||||
429 => 'Too Many Requests',
|
||||
431 => 'Request Header Fields Too Large',
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
506 => 'Variant Also Negotiates (Experimental)',
|
||||
507 => 'Insufficient Storage',
|
||||
508 => 'Loop Detected',
|
||||
510 => 'Not Extended',
|
||||
511 => 'Network Authentication Required',
|
||||
);
|
||||
|
||||
/**
|
||||
* @param int $code 状态码
|
||||
* @param double $duration 请求时长
|
||||
* @param array $headers 响应头部
|
||||
* @param string $body 响应内容
|
||||
* @param string $error 错误描述
|
||||
*/
|
||||
public function __construct($code, $duration, array $headers = array(), $body = null, $error = null)
|
||||
{
|
||||
$this->statusCode = $code;
|
||||
$this->duration = $duration;
|
||||
$this->headers = array();
|
||||
$this->body = $body;
|
||||
$this->error = $error;
|
||||
$this->jsonData = null;
|
||||
|
||||
if ($error !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($headers as $k => $vs) {
|
||||
if (is_array($vs)) {
|
||||
$this->headers[$k] = $vs[count($vs) - 1];
|
||||
} else {
|
||||
$this->headers[$k] = $vs;
|
||||
}
|
||||
}
|
||||
$this->normalizedHeaders = new Header($headers);
|
||||
|
||||
if ($body === null) {
|
||||
if ($code >= 400) {
|
||||
$this->error = self::$statusTexts[$code];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (self::isJson($this->normalizedHeaders)) {
|
||||
try {
|
||||
$jsonData = self::bodyJson($body);
|
||||
if ($code >= 400) {
|
||||
$this->error = $body;
|
||||
if ($jsonData['error'] !== null) {
|
||||
$this->error = $jsonData['error'];
|
||||
}
|
||||
}
|
||||
$this->jsonData = $jsonData;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$this->error = $body;
|
||||
if ($code >= 200 && $code < 300) {
|
||||
$this->error = $e->getMessage();
|
||||
}
|
||||
}
|
||||
} elseif ($code >= 400) {
|
||||
$this->error = $body;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public function json()
|
||||
{
|
||||
return $this->jsonData;
|
||||
}
|
||||
|
||||
public function headers($normalized = false)
|
||||
{
|
||||
if ($normalized) {
|
||||
return $this->normalizedHeaders;
|
||||
}
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
private static function bodyJson($body)
|
||||
{
|
||||
return \Qiniu\json_decode((string) $body, true, 512);
|
||||
}
|
||||
|
||||
public function xVia()
|
||||
{
|
||||
$via = $this->normalizedHeaders['X-Via'];
|
||||
if ($via === null) {
|
||||
$via = $this->normalizedHeaders['X-Px'];
|
||||
}
|
||||
if ($via === null) {
|
||||
$via = $this->normalizedHeaders['Fw-Via'];
|
||||
}
|
||||
return $via;
|
||||
}
|
||||
|
||||
public function xLog()
|
||||
{
|
||||
return $this->normalizedHeaders['X-Log'];
|
||||
}
|
||||
|
||||
public function xReqId()
|
||||
{
|
||||
return $this->normalizedHeaders['X-Reqid'];
|
||||
}
|
||||
|
||||
public function ok()
|
||||
{
|
||||
return $this->statusCode >= 200 && $this->statusCode < 300 && $this->error === null;
|
||||
}
|
||||
|
||||
public function needRetry()
|
||||
{
|
||||
if ($this->statusCode > 0 && $this->statusCode < 500) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://developer.qiniu.com/fusion/kb/1352/the-http-request-return-a-status-code
|
||||
if (in_array($this->statusCode, array(
|
||||
501, 509, 573, 579, 608, 612, 614, 616, 618, 630, 631, 632, 640, 701
|
||||
))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function isJson($headers)
|
||||
{
|
||||
return isset($headers['Content-Type']) && strpos($headers['Content-Type'], 'application/json') === 0;
|
||||
}
|
||||
}
|
||||
292
vendor/qiniu/php-sdk/src/Qiniu/Processing/ImageUrlBuilder.php
vendored
Normal file
292
vendor/qiniu/php-sdk/src/Qiniu/Processing/ImageUrlBuilder.php
vendored
Normal file
@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Processing;
|
||||
|
||||
use Qiniu;
|
||||
|
||||
/**
|
||||
* 主要涉及图片链接拼接
|
||||
*
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
|
||||
*/
|
||||
final class ImageUrlBuilder
|
||||
{
|
||||
/**
|
||||
* mode合法范围值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $modeArr = array(0, 1, 2, 3, 4, 5);
|
||||
|
||||
/**
|
||||
* format合法值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $formatArr = array('psd', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'bmp');
|
||||
|
||||
/**
|
||||
* 水印图片位置合法值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $gravityArr = array(
|
||||
'NorthWest',
|
||||
'North',
|
||||
'NorthEast',
|
||||
'West',
|
||||
'Center',
|
||||
'East',
|
||||
'SouthWest',
|
||||
'South',
|
||||
'SouthEast'
|
||||
);
|
||||
|
||||
/**
|
||||
* 缩略图链接拼接
|
||||
*
|
||||
* @param string $url 图片链接
|
||||
* @param int $mode 缩略模式
|
||||
* @param int $width 宽度
|
||||
* @param int $height 长度
|
||||
* @param string $format 输出类型
|
||||
* @param int $quality 图片质量
|
||||
* @param int $interlace 是否支持渐进显示
|
||||
* @param int $ignoreError 忽略结果
|
||||
* @return string
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
public function thumbnail(
|
||||
$url,
|
||||
$mode,
|
||||
$width,
|
||||
$height,
|
||||
$format = null,
|
||||
$interlace = null,
|
||||
$quality = null,
|
||||
$ignoreError = 1
|
||||
) {
|
||||
|
||||
// url合法效验
|
||||
if (!$this->isUrl($url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// 参数合法性效验
|
||||
if (!in_array(intval($mode), $this->modeArr, true)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (!$width || !$height) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$thumbStr = 'imageView2/' . $mode . '/w/' . $width . '/h/' . $height . '/';
|
||||
|
||||
// 拼接输出格式
|
||||
if (!is_null($format)
|
||||
&& in_array($format, $this->formatArr)
|
||||
) {
|
||||
$thumbStr .= 'format/' . $format . '/';
|
||||
}
|
||||
|
||||
// 拼接渐进显示
|
||||
if (!is_null($interlace)
|
||||
&& in_array(intval($interlace), array(0, 1), true)
|
||||
) {
|
||||
$thumbStr .= 'interlace/' . $interlace . '/';
|
||||
}
|
||||
|
||||
// 拼接图片质量
|
||||
if (!is_null($quality)
|
||||
&& intval($quality) >= 0
|
||||
&& intval($quality) <= 100
|
||||
) {
|
||||
$thumbStr .= 'q/' . $quality . '/';
|
||||
}
|
||||
|
||||
$thumbStr .= 'ignore-error/' . $ignoreError . '/';
|
||||
|
||||
// 如果有query_string用|线分割实现多参数
|
||||
return $url . ($this->hasQuery($url) ? '|' : '?') . $thumbStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片水印
|
||||
*
|
||||
* @param string $url 图片链接
|
||||
* @param string $image 水印图片链接
|
||||
* @param int $dissolve 透明度
|
||||
* @param string $gravity 水印位置
|
||||
* @param int $dx 横轴边距
|
||||
* @param int $dy 纵轴边距
|
||||
* @param int $watermarkScale 自适应原图的短边比例
|
||||
* @return string
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
public function waterImg(
|
||||
$url,
|
||||
$image,
|
||||
$dissolve = 100,
|
||||
$gravity = 'SouthEast',
|
||||
$dx = null,
|
||||
$dy = null,
|
||||
$watermarkScale = null
|
||||
) {
|
||||
// url合法效验
|
||||
if (!$this->isUrl($url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$waterStr = 'watermark/1/image/' . \Qiniu\base64_urlSafeEncode($image) . '/';
|
||||
|
||||
// 拼接水印透明度
|
||||
if (is_numeric($dissolve)
|
||||
&& $dissolve <= 100
|
||||
) {
|
||||
$waterStr .= 'dissolve/' . $dissolve . '/';
|
||||
}
|
||||
|
||||
// 拼接水印位置
|
||||
if (in_array($gravity, $this->gravityArr, true)) {
|
||||
$waterStr .= 'gravity/' . $gravity . '/';
|
||||
}
|
||||
|
||||
// 拼接横轴边距
|
||||
if (!is_null($dx)
|
||||
&& is_numeric($dx)
|
||||
) {
|
||||
$waterStr .= 'dx/' . $dx . '/';
|
||||
}
|
||||
|
||||
// 拼接纵轴边距
|
||||
if (!is_null($dy)
|
||||
&& is_numeric($dy)
|
||||
) {
|
||||
$waterStr .= 'dy/' . $dy . '/';
|
||||
}
|
||||
|
||||
// 拼接自适应原图的短边比例
|
||||
if (!is_null($watermarkScale)
|
||||
&& is_numeric($watermarkScale)
|
||||
&& $watermarkScale > 0
|
||||
&& $watermarkScale < 1
|
||||
) {
|
||||
$waterStr .= 'ws/' . $watermarkScale . '/';
|
||||
}
|
||||
|
||||
// 如果有query_string用|线分割实现多参数
|
||||
return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文字水印
|
||||
*
|
||||
* @param string $url 图片链接
|
||||
* @param string $text 文字
|
||||
* @param string $font 文字字体
|
||||
* @param string $fontSize 文字字号
|
||||
* @param string $fontColor 文字颜色
|
||||
* @param int $dissolve 透明度
|
||||
* @param string $gravity 水印位置
|
||||
* @param int $dx 横轴边距
|
||||
* @param int $dy 纵轴边距
|
||||
* @return string
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
public function waterText(
|
||||
$url,
|
||||
$text,
|
||||
$font = '黑体',
|
||||
$fontSize = 0,
|
||||
$fontColor = null,
|
||||
$dissolve = 100,
|
||||
$gravity = 'SouthEast',
|
||||
$dx = null,
|
||||
$dy = null
|
||||
) {
|
||||
// url合法效验
|
||||
if (!$this->isUrl($url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$waterStr = 'watermark/2/text/'
|
||||
. \Qiniu\base64_urlSafeEncode($text) . '/font/'
|
||||
. \Qiniu\base64_urlSafeEncode($font) . '/';
|
||||
|
||||
// 拼接文字大小
|
||||
if (is_int($fontSize)) {
|
||||
$waterStr .= 'fontsize/' . $fontSize . '/';
|
||||
}
|
||||
|
||||
// 拼接文字颜色
|
||||
if (!is_null($fontColor)
|
||||
&& $fontColor
|
||||
) {
|
||||
$waterStr .= 'fill/' . \Qiniu\base64_urlSafeEncode($fontColor) . '/';
|
||||
}
|
||||
|
||||
// 拼接水印透明度
|
||||
if (is_numeric($dissolve)
|
||||
&& $dissolve <= 100
|
||||
) {
|
||||
$waterStr .= 'dissolve/' . $dissolve . '/';
|
||||
}
|
||||
|
||||
// 拼接水印位置
|
||||
if (in_array($gravity, $this->gravityArr, true)) {
|
||||
$waterStr .= 'gravity/' . $gravity . '/';
|
||||
}
|
||||
|
||||
// 拼接横轴边距
|
||||
if (!is_null($dx)
|
||||
&& is_numeric($dx)
|
||||
) {
|
||||
$waterStr .= 'dx/' . $dx . '/';
|
||||
}
|
||||
|
||||
// 拼接纵轴边距
|
||||
if (!is_null($dy)
|
||||
&& is_numeric($dy)
|
||||
) {
|
||||
$waterStr .= 'dy/' . $dy . '/';
|
||||
}
|
||||
|
||||
// 如果有query_string用|线分割实现多参数
|
||||
return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 效验url合法性
|
||||
*
|
||||
* @param string $url url链接
|
||||
* @return string
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
protected function isUrl($url)
|
||||
{
|
||||
$urlArr = parse_url($url);
|
||||
|
||||
return $urlArr['scheme']
|
||||
&& in_array($urlArr['scheme'], array('http', 'https'))
|
||||
&& $urlArr['host']
|
||||
&& $urlArr['path'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否有query
|
||||
*
|
||||
* @param string $url url链接
|
||||
* @return string
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
protected function hasQuery($url)
|
||||
{
|
||||
$urlArr = parse_url($url);
|
||||
|
||||
return !empty($urlArr['query']);
|
||||
}
|
||||
}
|
||||
69
vendor/qiniu/php-sdk/src/Qiniu/Processing/Operation.php
vendored
Normal file
69
vendor/qiniu/php-sdk/src/Qiniu/Processing/Operation.php
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Processing;
|
||||
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Proxy;
|
||||
|
||||
final class Operation
|
||||
{
|
||||
|
||||
private $auth;
|
||||
private $token_expire;
|
||||
private $domain;
|
||||
private $proxy;
|
||||
|
||||
public function __construct(
|
||||
$domain,
|
||||
$auth = null,
|
||||
$token_expire = 3600,
|
||||
$proxy = null,
|
||||
$proxy_auth = null,
|
||||
$proxy_user_password = null
|
||||
) {
|
||||
$this->auth = $auth;
|
||||
$this->domain = $domain;
|
||||
$this->token_expire = $token_expire;
|
||||
$this->proxy = new Proxy($proxy, $proxy_auth, $proxy_user_password);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对资源文件进行处理
|
||||
*
|
||||
* @param string $key 待处理的资源文件名
|
||||
* @param string $fops string|array fop操作,多次fop操作以array的形式传入。
|
||||
* eg. imageView2/1/w/200/h/200, imageMogr2/thumbnail/!75px
|
||||
*
|
||||
* @return array 文件处理后的结果及错误。
|
||||
*
|
||||
* @link http://developer.qiniu.com/docs/v6/api/reference/fop/
|
||||
*/
|
||||
public function execute($key, $fops)
|
||||
{
|
||||
$url = $this->buildUrl($key, $fops);
|
||||
$resp = Client::get($url, array(), $this->proxy->makeReqOpt());
|
||||
if (!$resp->ok()) {
|
||||
return array(null, new Error($url, $resp));
|
||||
}
|
||||
if ($resp->json() !== null) {
|
||||
return array($resp->json(), null);
|
||||
}
|
||||
return array($resp->body, null);
|
||||
}
|
||||
|
||||
public function buildUrl($key, $fops, $protocol = 'http')
|
||||
{
|
||||
if (is_array($fops)) {
|
||||
$fops = implode('|', $fops);
|
||||
}
|
||||
|
||||
$url = $protocol . "://$this->domain/$key?$fops";
|
||||
if ($this->auth !== null) {
|
||||
$url = $this->auth->privateDownloadUrl($url, $this->token_expire);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
135
vendor/qiniu/php-sdk/src/Qiniu/Processing/PersistentFop.php
vendored
Normal file
135
vendor/qiniu/php-sdk/src/Qiniu/Processing/PersistentFop.php
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Processing;
|
||||
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Proxy;
|
||||
use Qiniu\Zone;
|
||||
|
||||
/**
|
||||
* 持久化处理类,该类用于主动触发异步持久化操作.
|
||||
*
|
||||
* @link http://developer.qiniu.com/docs/v6/api/reference/fop/pfop/pfop.html
|
||||
*/
|
||||
final class PersistentFop
|
||||
{
|
||||
/**
|
||||
* @var 账号管理密钥对,Auth对象
|
||||
*/
|
||||
private $auth;
|
||||
|
||||
/*
|
||||
* @var 配置对象,Config 对象
|
||||
* */
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var 代理信息
|
||||
*/
|
||||
private $proxy;
|
||||
|
||||
|
||||
public function __construct($auth, $config = null, $proxy = null, $proxy_auth = null, $proxy_user_password = null)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
if ($config == null) {
|
||||
$this->config = new Config();
|
||||
} else {
|
||||
$this->config = $config;
|
||||
}
|
||||
$this->proxy = new Proxy($proxy, $proxy_auth, $proxy_user_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对资源文件进行异步持久化处理
|
||||
* @param string $bucket 资源所在空间
|
||||
* @param string $key 待处理的源文件
|
||||
* @param string|array $fops 待处理的pfop操作,多个pfop操作以array的形式传入。
|
||||
* eg. avthumb/mp3/ab/192k, vframe/jpg/offset/7/w/480/h/360
|
||||
* @param string $pipeline 资源处理队列
|
||||
* @param string $notify_url 处理结果通知地址
|
||||
* @param bool $force 是否强制执行一次新的指令
|
||||
* @param int $type 为 `1` 时开启闲时任务
|
||||
*
|
||||
*
|
||||
* @return array 返回持久化处理的 persistentId 与可能出现的错误。
|
||||
*
|
||||
* @link http://developer.qiniu.com/docs/v6/api/reference/fop/
|
||||
*/
|
||||
public function execute(
|
||||
$bucket,
|
||||
$key,
|
||||
$fops = null,
|
||||
$pipeline = null,
|
||||
$notify_url = null,
|
||||
$force = false,
|
||||
$type = null,
|
||||
$workflow_template_id = null
|
||||
) {
|
||||
if (is_array($fops)) {
|
||||
$fops = implode(';', $fops);
|
||||
}
|
||||
|
||||
if (!$fops && !$workflow_template_id) {
|
||||
throw new \InvalidArgumentException('Must provide one of fops or template_id');
|
||||
}
|
||||
|
||||
$params = array('bucket' => $bucket, 'key' => $key);
|
||||
\Qiniu\setWithoutEmpty($params, 'fops', $fops);
|
||||
\Qiniu\setWithoutEmpty($params, 'pipeline', $pipeline);
|
||||
\Qiniu\setWithoutEmpty($params, 'notifyURL', $notify_url);
|
||||
\Qiniu\setWithoutEmpty($params, 'type', $type);
|
||||
\Qiniu\setWithoutEmpty($params, 'workflowTemplateID', $workflow_template_id);
|
||||
if ($force) {
|
||||
$params['force'] = 1;
|
||||
}
|
||||
$data = http_build_query($params);
|
||||
$scheme = "http://";
|
||||
if ($this->config->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
}
|
||||
$apiHost = $this->getApiHost();
|
||||
$url = $scheme . $apiHost . '/pfop/';
|
||||
$headers = $this->auth->authorization($url, $data, 'application/x-www-form-urlencoded');
|
||||
$headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
$response = Client::post($url, $data, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($url, $response));
|
||||
}
|
||||
$r = $response->json();
|
||||
$id = $r['persistentId'];
|
||||
return array($id, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return array 返回任务状态与可能出现的错误
|
||||
*/
|
||||
public function status($id)
|
||||
{
|
||||
$scheme = "http://";
|
||||
|
||||
if ($this->config->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
}
|
||||
$apiHost = $this->getApiHost();
|
||||
$url = $scheme . $apiHost . "/status/get/prefop?id=$id";
|
||||
$response = Client::get($url, array(), $this->proxy->makeReqOpt());
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($url, $response));
|
||||
}
|
||||
return array($response->json(), null);
|
||||
}
|
||||
|
||||
private function getApiHost()
|
||||
{
|
||||
if (!empty($this->config->zone) && !empty($this->config->zone->apiHost)) {
|
||||
$apiHost = $this->config->zone->apiHost;
|
||||
} else {
|
||||
$apiHost = Config::API_HOST;
|
||||
}
|
||||
return $apiHost;
|
||||
}
|
||||
}
|
||||
229
vendor/qiniu/php-sdk/src/Qiniu/Region.php
vendored
Normal file
229
vendor/qiniu/php-sdk/src/Qiniu/Region.php
vendored
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu;
|
||||
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Middleware\RetryDomainsMiddleware;
|
||||
use Qiniu\Http\RequestOptions;
|
||||
|
||||
class Region
|
||||
{
|
||||
|
||||
//源站上传域名
|
||||
public $srcUpHosts;
|
||||
//CDN加速上传域名
|
||||
public $cdnUpHosts;
|
||||
//资源管理域名
|
||||
public $rsHost;
|
||||
//资源列举域名
|
||||
public $rsfHost;
|
||||
//资源处理域名
|
||||
public $apiHost;
|
||||
//IOVIP域名
|
||||
public $iovipHost;
|
||||
// TTL
|
||||
public $ttl;
|
||||
|
||||
//构造一个Region对象
|
||||
public function __construct(
|
||||
$srcUpHosts = array(),
|
||||
$cdnUpHosts = array(),
|
||||
$rsHost = "rs-z0.qiniuapi.com",
|
||||
$rsfHost = "rsf-z0.qiniuapi.com",
|
||||
$apiHost = "api.qiniuapi.com",
|
||||
$iovipHost = null,
|
||||
$ttl = null
|
||||
) {
|
||||
|
||||
$this->srcUpHosts = $srcUpHosts;
|
||||
$this->cdnUpHosts = $cdnUpHosts;
|
||||
$this->rsHost = $rsHost;
|
||||
$this->rsfHost = $rsfHost;
|
||||
$this->apiHost = $apiHost;
|
||||
$this->iovipHost = $iovipHost;
|
||||
$this->ttl = $ttl;
|
||||
}
|
||||
|
||||
//华东机房
|
||||
public static function regionHuadong()
|
||||
{
|
||||
$regionHuadong = new Region(
|
||||
array("up.qiniup.com"),
|
||||
array('upload.qiniup.com'),
|
||||
'rs-z0.qiniuapi.com',
|
||||
'rsf-z0.qiniuapi.com',
|
||||
'api.qiniuapi.com',
|
||||
'iovip.qbox.me'
|
||||
);
|
||||
return $regionHuadong;
|
||||
}
|
||||
|
||||
//华东机房内网上传
|
||||
public static function qvmRegionHuadong()
|
||||
{
|
||||
$qvmRegionHuadong = new Region(
|
||||
array("free-qvm-z0-xs.qiniup.com"),
|
||||
'rs-z0.qiniuapi.com',
|
||||
'rsf-z0.qiniuapi.com',
|
||||
'api.qiniuapi.com',
|
||||
'iovip.qbox.me'
|
||||
);
|
||||
return $qvmRegionHuadong;
|
||||
}
|
||||
|
||||
//华北机房内网上传
|
||||
public static function qvmRegionHuabei()
|
||||
{
|
||||
$qvmRegionHuabei = new Region(
|
||||
array("free-qvm-z1-zz.qiniup.com"),
|
||||
"rs-z1.qiniuapi.com",
|
||||
"rsf-z1.qiniuapi.com",
|
||||
"api-z1.qiniuapi.com",
|
||||
"iovip-z1.qbox.me"
|
||||
);
|
||||
return $qvmRegionHuabei;
|
||||
}
|
||||
|
||||
//华北机房
|
||||
public static function regionHuabei()
|
||||
{
|
||||
$regionHuabei = new Region(
|
||||
array('up-z1.qiniup.com'),
|
||||
array('upload-z1.qiniup.com'),
|
||||
"rs-z1.qiniuapi.com",
|
||||
"rsf-z1.qiniuapi.com",
|
||||
"api-z1.qiniuapi.com",
|
||||
"iovip-z1.qbox.me"
|
||||
);
|
||||
|
||||
return $regionHuabei;
|
||||
}
|
||||
|
||||
//华南机房
|
||||
public static function regionHuanan()
|
||||
{
|
||||
$regionHuanan = new Region(
|
||||
array('up-z2.qiniup.com'),
|
||||
array('upload-z2.qiniup.com'),
|
||||
"rs-z2.qiniuapi.com",
|
||||
"rsf-z2.qiniuapi.com",
|
||||
"api-z2.qiniuapi.com",
|
||||
"iovip-z2.qbox.me"
|
||||
);
|
||||
return $regionHuanan;
|
||||
}
|
||||
|
||||
//华东2 机房
|
||||
public static function regionHuadong2()
|
||||
{
|
||||
return new Region(
|
||||
array('up-cn-east-2.qiniup.com'),
|
||||
array('upload-cn-east-2.qiniup.com'),
|
||||
"rs-cn-east-2.qiniuapi.com",
|
||||
"rsf-cn-east-2.qiniuapi.com",
|
||||
"api-cn-east-2.qiniuapi.com",
|
||||
"iovip-cn-east-2.qiniuio.com"
|
||||
);
|
||||
}
|
||||
|
||||
//北美机房
|
||||
public static function regionNorthAmerica()
|
||||
{
|
||||
//北美机房
|
||||
$regionNorthAmerica = new Region(
|
||||
array('up-na0.qiniup.com'),
|
||||
array('upload-na0.qiniup.com'),
|
||||
"rs-na0.qiniuapi.com",
|
||||
"rsf-na0.qiniuapi.com",
|
||||
"api-na0.qiniuapi.com",
|
||||
"iovip-na0.qbox.me"
|
||||
);
|
||||
return $regionNorthAmerica;
|
||||
}
|
||||
|
||||
//新加坡机房
|
||||
public static function regionSingapore()
|
||||
{
|
||||
//新加坡机房
|
||||
$regionSingapore = new Region(
|
||||
array('up-as0.qiniup.com'),
|
||||
array('upload-as0.qiniup.com'),
|
||||
"rs-as0.qiniuapi.com",
|
||||
"rsf-as0.qiniuapi.com",
|
||||
"api-as0.qiniuapi.com",
|
||||
"iovip-as0.qbox.me"
|
||||
);
|
||||
return $regionSingapore;
|
||||
}
|
||||
|
||||
/*
|
||||
* GET /v4/query?ak=<ak>&bucket=<bucket>
|
||||
* @param string $ak
|
||||
* @param string $bucket
|
||||
* @param string $ucHost|null
|
||||
* @param array $backupUcHosts
|
||||
* @param int $retryTimes
|
||||
* @param RequestOptions|null $reqOpt
|
||||
* @return Response
|
||||
**/
|
||||
public static function queryRegion(
|
||||
$ak,
|
||||
$bucket,
|
||||
$ucHost = null,
|
||||
$backupUcHosts = array(),
|
||||
$retryTimes = 2,
|
||||
$reqOpt = null
|
||||
) {
|
||||
$region = new Region();
|
||||
if (!$ucHost) {
|
||||
$ucHost = "https://" . Config::QUERY_REGION_HOST;
|
||||
}
|
||||
$url = $ucHost . '/v4/query' . "?ak=$ak&bucket=$bucket";
|
||||
if ($reqOpt == null) {
|
||||
$reqOpt = new RequestOptions();
|
||||
}
|
||||
$reqOpt->middlewares = array(
|
||||
new RetryDomainsMiddleware(
|
||||
$backupUcHosts,
|
||||
$retryTimes
|
||||
)
|
||||
);
|
||||
$ret = Client::get($url, array(), $reqOpt);
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
$r = ($ret->body === null) ? array() : $ret->json();
|
||||
if (!is_array($r["hosts"]) || count($r["hosts"]) == 0) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
|
||||
// parse region;
|
||||
$regionHost = $r["hosts"][0];
|
||||
$region->cdnUpHosts = array_merge($region->cdnUpHosts, $regionHost['up']['domains']);
|
||||
$region->srcUpHosts = array_merge($region->srcUpHosts, $regionHost['up']['domains']);
|
||||
|
||||
// set specific hosts
|
||||
$region->iovipHost = $regionHost['io']['domains'][0];
|
||||
if (isset($regionHost['rs']['domains']) && count($regionHost['rs']['domains']) > 0) {
|
||||
$region->rsHost = $regionHost['rs']['domains'][0];
|
||||
} else {
|
||||
$region->rsHost = Config::RS_HOST;
|
||||
}
|
||||
if (isset($regionHost['rsf']['domains']) && count($regionHost['rsf']['domains']) > 0) {
|
||||
$region->rsfHost = $regionHost['rsf']['domains'][0];
|
||||
} else {
|
||||
$region->rsfHost = Config::RSF_HOST;
|
||||
}
|
||||
if (isset($regionHost['api']['domains']) && count($regionHost['api']['domains']) > 0) {
|
||||
$region->apiHost = $regionHost['api']['domains'][0];
|
||||
} else {
|
||||
$region->apiHost = Config::API_HOST;
|
||||
}
|
||||
|
||||
// set ttl
|
||||
$region->ttl = $regionHost['ttl'];
|
||||
|
||||
return $region;
|
||||
}
|
||||
}
|
||||
236
vendor/qiniu/php-sdk/src/Qiniu/Rtc/AppClient.php
vendored
Executable file
236
vendor/qiniu/php-sdk/src/Qiniu/Rtc/AppClient.php
vendored
Executable file
@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Rtc;
|
||||
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Proxy;
|
||||
|
||||
class AppClient
|
||||
{
|
||||
private $auth;
|
||||
private $baseURL;
|
||||
private $proxy;
|
||||
|
||||
public function __construct(Auth $auth, $proxy = null, $proxy_auth = null, $proxy_user_password = null)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->baseURL = sprintf("%s/%s/apps", Config::RTCAPI_HOST, Config::RTCAPI_VERSION);
|
||||
$this->proxy = new Proxy($proxy, $proxy_auth, $proxy_user_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建应用
|
||||
*
|
||||
* @param string $hub 绑定的直播 hub
|
||||
* @param string $title app 的名称 注意,Title 不是唯一标识,重复 create 动作将生成多个 app
|
||||
* @param int $maxUsers 连麦房间支持的最大在线人数
|
||||
* @param bool $noAutoKickUser 禁止自动踢人(抢流),默认为 false
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_1
|
||||
*/
|
||||
public function createApp($hub, $title, $maxUsers = null, $noAutoKickUser = null)
|
||||
{
|
||||
$params = array();
|
||||
$params['hub'] = $hub;
|
||||
$params['title'] = $title;
|
||||
if (!empty($maxUsers)) {
|
||||
$params['maxUsers'] = $maxUsers;
|
||||
}
|
||||
if ($noAutoKickUser !== null) {
|
||||
$params['noAutoKickUser'] = $noAutoKickUser;
|
||||
}
|
||||
$body = json_encode($params);
|
||||
return $this->post($this->baseURL, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新一个应用的配置信息
|
||||
*
|
||||
* @param string $appId app 的唯一标识,创建的时候由系统生成
|
||||
* @param string $hub app 的名称,可选
|
||||
* @param string $title 绑定的直播 hub,可选,用于合流后 rtmp 推流
|
||||
* @param int $maxUsers 连麦房间支持的最大在线人数,可选
|
||||
* @param bool $noAutoKickUser 禁止自动踢人,可选
|
||||
* @param null $mergePublishRtmp 连麦合流转推 RTMP 的配置,可选择。其详细配置可以参考文档
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_1
|
||||
*/
|
||||
public function updateApp($appId, $hub, $title, $maxUsers = null, $noAutoKickUser = null, $mergePublishRtmp = null)
|
||||
{
|
||||
$url = $this->baseURL . '/' . $appId;
|
||||
$params = array();
|
||||
$params['hub'] = $hub;
|
||||
$params['title'] = $title;
|
||||
if (!empty($maxUsers)) {
|
||||
$params['maxUsers'] = $maxUsers;
|
||||
}
|
||||
if ($noAutoKickUser !== null) {
|
||||
$params['noAutoKickUser'] = $noAutoKickUser;
|
||||
}
|
||||
if (!empty($mergePublishRtmp)) {
|
||||
$params['mergePublishRtmp'] = $mergePublishRtmp;
|
||||
}
|
||||
$body = json_encode($params);
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用信息
|
||||
*
|
||||
* @param string $appId
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_1
|
||||
*/
|
||||
public function getApp($appId)
|
||||
{
|
||||
$url = $this->baseURL . '/' . $appId;
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除应用
|
||||
*
|
||||
* @param string $appId app 的唯一标识,创建的时候由系统生成
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_1
|
||||
*/
|
||||
public function deleteApp($appId)
|
||||
{
|
||||
$url = $this->baseURL . '/' . $appId;
|
||||
return $this->delete($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取房间内用户列表
|
||||
*
|
||||
* @param string $appId app 的唯一标识,创建的时候由系统生成
|
||||
* @param string $roomName 操作所查询的连麦房间
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
|
||||
*/
|
||||
public function listUser($appId, $roomName)
|
||||
{
|
||||
$url = sprintf("%s/%s/rooms/%s/users", $this->baseURL, $appId, $roomName);
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定一个用户踢出房间
|
||||
*
|
||||
* @param string $appId app 的唯一标识,创建的时候由系统生成
|
||||
* @param string $roomName 连麦房间
|
||||
* @param string $userId 操作所剔除的用户
|
||||
* @return mixed
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
|
||||
*/
|
||||
public function kickUser($appId, $roomName, $userId)
|
||||
{
|
||||
$url = sprintf("%s/%s/rooms/%s/users/%s", $this->baseURL, $appId, $roomName, $userId);
|
||||
return $this->delete($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止一个房间的合流转推
|
||||
*
|
||||
* @param string $appId
|
||||
* @param string $roomName
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
|
||||
*/
|
||||
public function stopMerge($appId, $roomName)
|
||||
{
|
||||
$url = sprintf("%s/%s/rooms/%s/merge", $this->baseURL, $appId, $roomName);
|
||||
return $this->delete($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用中活跃房间
|
||||
*
|
||||
* @param string $appId 连麦房间所属的 app
|
||||
* @param null $prefix 所查询房间名的前缀索引,可以为空。
|
||||
* @param int $offset 分页查询的位移标记
|
||||
* @param int $limit 此次查询的最大长度
|
||||
* @return array
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
|
||||
*/
|
||||
public function listActiveRooms($appId, $prefix = null, $offset = null, $limit = null)
|
||||
{
|
||||
$query = array();
|
||||
if (isset($prefix)) {
|
||||
$query['prefix'] = $prefix;
|
||||
}
|
||||
if (isset($offset)) {
|
||||
$query['offset'] = $offset;
|
||||
}
|
||||
if (isset($limit)) {
|
||||
$query['limit'] = $limit;
|
||||
}
|
||||
if (isset($query) && !empty($query)) {
|
||||
$query = '?' . http_build_query($query);
|
||||
$url = sprintf("%s/%s/rooms%s", $this->baseURL, $appId, $query);
|
||||
} else {
|
||||
$url = sprintf("%s/%s/rooms", $this->baseURL, $appId);
|
||||
}
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成加入房间的令牌
|
||||
*
|
||||
* @param string $appId app 的唯一标识,创建的时候由系统生成
|
||||
* @param string $roomName 房间名称,需满足规格 ^[a-zA-Z0-9_-]{3,64}$
|
||||
* @param string $userId 请求加入房间的用户 ID,需满足规格 ^[a-zA-Z0-9_-]{3,50}$
|
||||
* @param int $expireAt 鉴权的有效时间,传入以秒为单位的64位 Unix 绝对时间
|
||||
* @param string $permission 该用户的房间管理权限,"admin" 或 "user",默认为 "user"
|
||||
* @return string
|
||||
* @link https://doc.qnsdk.com/rtn/docs/server_overview#1
|
||||
*/
|
||||
public function appToken($appId, $roomName, $userId, $expireAt, $permission)
|
||||
{
|
||||
$params = array();
|
||||
$params['appId'] = $appId;
|
||||
$params['userId'] = $userId;
|
||||
$params['roomName'] = $roomName;
|
||||
$params['permission'] = $permission;
|
||||
$params['expireAt'] = $expireAt;
|
||||
$appAccessString = json_encode($params);
|
||||
return $this->auth->signWithData($appAccessString);
|
||||
}
|
||||
|
||||
private function get($url, $cType = null)
|
||||
{
|
||||
$rtcToken = $this->auth->authorizationV2($url, "GET", null, $cType);
|
||||
$rtcToken['Content-Type'] = $cType;
|
||||
$ret = Client::get($url, $rtcToken, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
return array($ret->json(), null);
|
||||
}
|
||||
|
||||
private function delete($url, $contentType = 'application/json')
|
||||
{
|
||||
$rtcToken = $this->auth->authorizationV2($url, "DELETE", null, $contentType);
|
||||
$rtcToken['Content-Type'] = $contentType;
|
||||
$ret = Client::delete($url, $rtcToken, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
return array($ret->json(), null);
|
||||
}
|
||||
|
||||
private function post($url, $body, $contentType = 'application/json')
|
||||
{
|
||||
$rtcToken = $this->auth->authorizationV2($url, "POST", $body, $contentType);
|
||||
$rtcToken['Content-Type'] = $contentType;
|
||||
$ret = Client::post($url, $body, $rtcToken, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
$r = ($ret->body === null) ? array() : $ret->json();
|
||||
return array($r, null);
|
||||
}
|
||||
}
|
||||
382
vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php
vendored
Normal file
382
vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php
vendored
Normal file
@ -0,0 +1,382 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Sms;
|
||||
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Proxy;
|
||||
|
||||
class Sms
|
||||
{
|
||||
private $auth;
|
||||
private $baseURL;
|
||||
private $proxy;
|
||||
|
||||
public function __construct(Auth $auth, $proxy = null, $proxy_auth = null, $proxy_user_password = null)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->baseURL = sprintf("%s/%s/", Config::SMS_HOST, Config::SMS_VERSION);
|
||||
$this->proxy = new Proxy($proxy, $proxy_auth, $proxy_user_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建签名
|
||||
*
|
||||
* @param string $signature 签名
|
||||
* @param string $source 签名来源,申请签名时必须指定签名来源
|
||||
* @param string $pics 签名对应的资质证明图片进行 base64 编码格式转换后的字符串,可选
|
||||
* @return array
|
||||
*
|
||||
* @link https://developer.qiniu.com/sms/api/5844/sms-api-create-signature
|
||||
*/
|
||||
public function createSignature($signature, $source, $pics = null)
|
||||
{
|
||||
$params = array();
|
||||
$params['signature'] = $signature;
|
||||
$params['source'] = $source;
|
||||
if (!empty($pics)) {
|
||||
$params['pics'] = array($this->imgToBase64($pics));
|
||||
}
|
||||
$body = json_encode($params);
|
||||
$url = $this->baseURL . 'signature';
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑签名
|
||||
*
|
||||
* @param string $id 签名 ID
|
||||
* @param string $signature 签名
|
||||
* @param string $source 签名来源
|
||||
* @param string $pics 签名对应的资质证明图片进行 base64 编码格式转换后的字符串,可选
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5890/sms-api-edit-signature
|
||||
*/
|
||||
public function updateSignature($id, $signature, $source, $pics = null)
|
||||
{
|
||||
$params = array();
|
||||
$params['signature'] = $signature;
|
||||
$params['source'] = $source;
|
||||
if (!empty($pics)) {
|
||||
$params['pics'] = array($this->imgToBase64($pics));
|
||||
}
|
||||
$body = json_encode($params);
|
||||
$url = $this->baseURL . 'signature/' . $id;
|
||||
return $this->PUT($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出签名
|
||||
*
|
||||
* @param string $audit_status 审核状态:"passed"(通过), "rejected"(未通过), "reviewing"(审核中)
|
||||
* @param int $page 页码。默认为 1
|
||||
* @param int $page_size 分页大小。默认为 20
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5889/sms-api-query-signature
|
||||
*/
|
||||
public function querySignature($audit_status = null, $page = 1, $page_size = 20)
|
||||
{
|
||||
|
||||
$url = sprintf(
|
||||
"%s?audit_status=%s&page=%s&page_size=%s",
|
||||
$this->baseURL . 'signature',
|
||||
$audit_status,
|
||||
$page,
|
||||
$page_size
|
||||
);
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个签名
|
||||
*
|
||||
* @param string $signature_id
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5970/query-a-single-signature
|
||||
*/
|
||||
public function checkSingleSignature($signature_id)
|
||||
{
|
||||
|
||||
$url = sprintf(
|
||||
"%s/%s",
|
||||
$this->baseURL . 'signature',
|
||||
$signature_id
|
||||
);
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除签名
|
||||
*
|
||||
* @param string $signature_id 签名 ID
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5891/sms-api-delete-signature
|
||||
*/
|
||||
public function deleteSignature($signature_id)
|
||||
{
|
||||
$url = $this->baseURL . 'signature/' . $signature_id;
|
||||
return $this->delete($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模板
|
||||
*
|
||||
* @param string $name 模板名称
|
||||
* @param string $template 模板内容 可设置自定义变量,发送短信时候使用,参考:${code}
|
||||
* @param string $type notification:通知类,verification:验证码,marketing:营销类,voice:语音类
|
||||
* @param string $description 申请理由简述
|
||||
* @param string $signature_id 已经审核通过的签名
|
||||
* @return array array
|
||||
* @link https://developer.qiniu.com/sms/api/5893/sms-api-create-template
|
||||
*/
|
||||
public function createTemplate(
|
||||
$name,
|
||||
$template,
|
||||
$type,
|
||||
$description,
|
||||
$signature_id
|
||||
) {
|
||||
$params = array();
|
||||
$params['name'] = $name;
|
||||
$params['template'] = $template;
|
||||
$params['type'] = $type;
|
||||
$params['description'] = $description;
|
||||
$params['signature_id'] = $signature_id;
|
||||
|
||||
$body = json_encode($params);
|
||||
$url = $this->baseURL . 'template';
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出模板
|
||||
*
|
||||
* @param string $audit_status 审核状态:passed (通过), rejected (未通过), reviewing (审核中)
|
||||
* @param int $page 页码。默认为 1
|
||||
* @param int $page_size 分页大小。默认为 20
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5894/sms-api-query-template
|
||||
*/
|
||||
public function queryTemplate($audit_status = null, $page = 1, $page_size = 20)
|
||||
{
|
||||
|
||||
$url = sprintf(
|
||||
"%s?audit_status=%s&page=%s&page_size=%s",
|
||||
$this->baseURL . 'template',
|
||||
$audit_status,
|
||||
$page,
|
||||
$page_size
|
||||
);
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个模版
|
||||
*
|
||||
* @param string $template_id 模版ID
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5969/query-a-single-template
|
||||
*/
|
||||
public function querySingleTemplate($template_id)
|
||||
{
|
||||
|
||||
$url = sprintf(
|
||||
"%s/%s",
|
||||
$this->baseURL . 'template',
|
||||
$template_id
|
||||
);
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑模板
|
||||
*
|
||||
* @param string $id 模板 ID
|
||||
* @param string $name 模板名称
|
||||
* @param string $template 模板内容
|
||||
* @param string $description 申请理由简述
|
||||
* @param string $signature_id 已经审核通过的签名 ID
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5895/sms-api-edit-template
|
||||
*/
|
||||
public function updateTemplate(
|
||||
$id,
|
||||
$name,
|
||||
$template,
|
||||
$description,
|
||||
$signature_id
|
||||
) {
|
||||
$params = array();
|
||||
$params['name'] = $name;
|
||||
$params['template'] = $template;
|
||||
$params['description'] = $description;
|
||||
$params['signature_id'] = $signature_id;
|
||||
$body = json_encode($params);
|
||||
$url = $this->baseURL . 'template/' . $id;
|
||||
return $this->PUT($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板
|
||||
*
|
||||
* @param string $template_id 模板 ID
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5896/sms-api-delete-template
|
||||
*/
|
||||
public function deleteTemplate($template_id)
|
||||
{
|
||||
$url = $this->baseURL . 'template/' . $template_id;
|
||||
return $this->delete($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
*
|
||||
* @param string $template_id 模板 ID
|
||||
* @param array $mobiles 手机号
|
||||
* @param array $parameters 自定义模板变量,变量设置在创建模板时,参数template指定
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5897/sms-api-send-message
|
||||
*/
|
||||
public function sendMessage($template_id, $mobiles, $parameters = null)
|
||||
{
|
||||
$params = array();
|
||||
$params['template_id'] = $template_id;
|
||||
$params['mobiles'] = $mobiles;
|
||||
if (!empty($parameters)) {
|
||||
$params['parameters'] = $parameters;
|
||||
}
|
||||
$body = json_encode($params);
|
||||
$url = $this->baseURL . 'message';
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询发送记录
|
||||
*
|
||||
* @param string $job_id 发送任务返回的 id
|
||||
* @param string $message_id 单条短信发送接口返回的 id
|
||||
* @param string $mobile 接收短信的手机号码
|
||||
* @param string $status sending: 发送中,success: 发送成功,failed: 发送失败,waiting: 等待发送
|
||||
* @param string $template_id 模版 id
|
||||
* @param string $type marketing:营销,notification:通知,verification:验证码,voice:语音
|
||||
* @param string $start 开始时间,timestamp,例如: 1563280448
|
||||
* @param int $end 结束时间,timestamp,例如: 1563280471
|
||||
* @param int $page 页码,默认为 1
|
||||
* @param int $page_size 每页返回的数据条数,默认20,最大200
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/sms/api/5852/query-send-sms
|
||||
*/
|
||||
public function querySendSms(
|
||||
$job_id = null,
|
||||
$message_id = null,
|
||||
$mobile = null,
|
||||
$status = null,
|
||||
$template_id = null,
|
||||
$type = null,
|
||||
$start = null,
|
||||
$end = null,
|
||||
$page = 1,
|
||||
$page_size = 20
|
||||
) {
|
||||
$query = array();
|
||||
\Qiniu\setWithoutEmpty($query, 'job_id', $job_id);
|
||||
\Qiniu\setWithoutEmpty($query, 'message_id', $message_id);
|
||||
\Qiniu\setWithoutEmpty($query, 'mobile', $mobile);
|
||||
\Qiniu\setWithoutEmpty($query, 'status', $status);
|
||||
\Qiniu\setWithoutEmpty($query, 'template_id', $template_id);
|
||||
\Qiniu\setWithoutEmpty($query, 'type', $type);
|
||||
\Qiniu\setWithoutEmpty($query, 'start', $start);
|
||||
\Qiniu\setWithoutEmpty($query, 'end', $end);
|
||||
\Qiniu\setWithoutEmpty($query, 'page', $page);
|
||||
\Qiniu\setWithoutEmpty($query, 'page_size', $page_size);
|
||||
|
||||
$url = $this->baseURL . 'messages?' . http_build_query($query);
|
||||
return $this->get($url);
|
||||
}
|
||||
|
||||
|
||||
public function imgToBase64($img_file)
|
||||
{
|
||||
$img_base64 = '';
|
||||
if (file_exists($img_file)) {
|
||||
$app_img_file = $img_file; // 图片路径
|
||||
$img_info = getimagesize($app_img_file); // 取得图片的大小,类型等
|
||||
$fp = fopen($app_img_file, "r"); // 图片是否可读权限
|
||||
if ($fp) {
|
||||
$filesize = filesize($app_img_file);
|
||||
if ($filesize > 5 * 1024 * 1024) {
|
||||
die("pic size < 5M !");
|
||||
}
|
||||
$img_type = null;
|
||||
$content = fread($fp, $filesize);
|
||||
$file_content = chunk_split(base64_encode($content)); // base64编码
|
||||
switch ($img_info[2]) { //判读图片类型
|
||||
case 1:
|
||||
$img_type = 'gif';
|
||||
break;
|
||||
case 2:
|
||||
$img_type = 'jpg';
|
||||
break;
|
||||
case 3:
|
||||
$img_type = 'png';
|
||||
break;
|
||||
}
|
||||
//合成图片的base64编码
|
||||
$img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
return $img_base64;
|
||||
}
|
||||
|
||||
private function get($url, $contentType = 'application/x-www-form-urlencoded')
|
||||
{
|
||||
$headers = $this->auth->authorizationV2($url, "GET", null, $contentType);
|
||||
$headers['Content-Type'] = $contentType;
|
||||
$ret = Client::get($url, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
return array($ret->json(), null);
|
||||
}
|
||||
|
||||
private function delete($url, $contentType = 'application/json')
|
||||
{
|
||||
$headers = $this->auth->authorizationV2($url, "DELETE", null, $contentType);
|
||||
$headers['Content-Type'] = $contentType;
|
||||
$ret = Client::delete($url, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
return array($ret->json(), null);
|
||||
}
|
||||
|
||||
private function post($url, $body, $contentType = 'application/json')
|
||||
{
|
||||
$headers = $this->auth->authorizationV2($url, "POST", $body, $contentType);
|
||||
|
||||
$headers['Content-Type'] = $contentType;
|
||||
$ret = Client::post($url, $body, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
$r = ($ret->body === null) ? array() : $ret->json();
|
||||
return array($r, null);
|
||||
}
|
||||
|
||||
private function PUT($url, $body, $contentType = 'application/json')
|
||||
{
|
||||
$headers = $this->auth->authorizationV2($url, "PUT", $body, $contentType);
|
||||
$headers['Content-Type'] = $contentType;
|
||||
$ret = Client::put($url, $body, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
$r = ($ret->body === null) ? array() : $ret->json();
|
||||
return array($r, null);
|
||||
}
|
||||
}
|
||||
129
vendor/qiniu/php-sdk/src/Qiniu/Storage/ArgusManager.php
vendored
Normal file
129
vendor/qiniu/php-sdk/src/Qiniu/Storage/ArgusManager.php
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Storage;
|
||||
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Zone;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Proxy;
|
||||
|
||||
/**
|
||||
* 主要涉及了内容审核接口的实现,具体的接口规格可以参考
|
||||
*
|
||||
* @link https://developer.qiniu.com/censor/api/5620/video-censor
|
||||
*/
|
||||
final class ArgusManager
|
||||
{
|
||||
private $auth;
|
||||
private $config;
|
||||
private $proxy;
|
||||
|
||||
public function __construct(
|
||||
Auth $auth,
|
||||
Config $config = null,
|
||||
$proxy = null,
|
||||
$proxy_auth = null,
|
||||
$proxy_user_password = null
|
||||
) {
|
||||
$this->auth = $auth;
|
||||
if ($config == null) {
|
||||
$this->config = new Config();
|
||||
} else {
|
||||
$this->config = $config;
|
||||
}
|
||||
$this->proxy = new Proxy($proxy, $proxy_auth, $proxy_user_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频审核
|
||||
*
|
||||
* @param string $body body信息
|
||||
*
|
||||
* @return array 成功返回NULL,失败返回对象Qiniu\Http\Error
|
||||
* @link https://developer.qiniu.com/censor/api/5620/video-censor
|
||||
*/
|
||||
public function censorVideo($body)
|
||||
{
|
||||
$path = '/v3/video/censor';
|
||||
|
||||
return $this->arPost($path, $body);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 图片审核
|
||||
*
|
||||
* @param string $body
|
||||
*
|
||||
* @return array 成功返回NULL,失败返回对象Qiniu\Http\Error
|
||||
* @link https://developer.qiniu.com/censor/api/5588/image-censor
|
||||
*/
|
||||
public function censorImage($body)
|
||||
{
|
||||
$path = '/v3/image/censor';
|
||||
|
||||
return $this->arPost($path, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询视频审核结果
|
||||
*
|
||||
* @param string $jobid 任务ID
|
||||
* @return array
|
||||
* @link https://developer.qiniu.com/censor/api/5620/video-censor
|
||||
*/
|
||||
public function censorStatus($jobid)
|
||||
{
|
||||
$scheme = "http://";
|
||||
|
||||
if ($this->config->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
}
|
||||
$url = $scheme . Config::ARGUS_HOST . "/v3/jobs/video/$jobid";
|
||||
$response = $this->get($url);
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($url, $response));
|
||||
}
|
||||
return array($response->json(), null);
|
||||
}
|
||||
|
||||
private function getArHost()
|
||||
{
|
||||
$scheme = "http://";
|
||||
if ($this->config->useHTTPS === true) {
|
||||
$scheme = "https://";
|
||||
}
|
||||
return $scheme . Config::ARGUS_HOST;
|
||||
}
|
||||
|
||||
private function arPost($path, $body = null)
|
||||
{
|
||||
$url = $this->getArHost() . $path;
|
||||
return $this->post($url, $body);
|
||||
}
|
||||
|
||||
private function get($url)
|
||||
{
|
||||
$headers = $this->auth->authorizationV2($url, 'GET');
|
||||
|
||||
return Client::get($url, $headers, $this->proxy->makeReqOpt());
|
||||
}
|
||||
|
||||
private function post($url, $body)
|
||||
{
|
||||
$headers = $this->auth->authorizationV2($url, 'POST', $body, 'application/json');
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
$ret = Client::post($url, $body, $headers, $this->proxy->makeReqOpt());
|
||||
if (!$ret->ok()) {
|
||||
return array(null, new Error($url, $ret));
|
||||
}
|
||||
$r = ($ret->body === null) ? array() : $ret->json();
|
||||
if (strstr($url, "video")) {
|
||||
$jobid = $r['job'];
|
||||
return array($jobid, null);
|
||||
}
|
||||
return array($r, null);
|
||||
}
|
||||
}
|
||||
1324
vendor/qiniu/php-sdk/src/Qiniu/Storage/BucketManager.php
vendored
Normal file
1324
vendor/qiniu/php-sdk/src/Qiniu/Storage/BucketManager.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
165
vendor/qiniu/php-sdk/src/Qiniu/Storage/FormUploader.php
vendored
Normal file
165
vendor/qiniu/php-sdk/src/Qiniu/Storage/FormUploader.php
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Storage;
|
||||
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\RequestOptions;
|
||||
|
||||
final class FormUploader
|
||||
{
|
||||
|
||||
/**
|
||||
* 上传二进制流到七牛, 内部使用
|
||||
*
|
||||
* @param string $upToken 上传凭证
|
||||
* @param string $key 上传文件名
|
||||
* @param string $data 上传二进制流
|
||||
* @param Config $config 上传配置
|
||||
* @param string $params 自定义变量,规格参考
|
||||
* {@link https://developer.qiniu.com/kodo/manual/1235/vars#xvar}
|
||||
* @param string $mime 上传数据的mimeType
|
||||
* @param string $fname
|
||||
* @param RequestOptions $reqOpt
|
||||
*
|
||||
* @return array 包含已上传文件的信息,类似:
|
||||
* [
|
||||
* "hash" => "<Hash string>",
|
||||
* "key" => "<Key string>"
|
||||
* ]
|
||||
*/
|
||||
public static function put(
|
||||
$upToken,
|
||||
$key,
|
||||
$data,
|
||||
$config,
|
||||
$params,
|
||||
$mime,
|
||||
$fname,
|
||||
$reqOpt = null
|
||||
) {
|
||||
if ($reqOpt == null) {
|
||||
$reqOpt = new RequestOptions();
|
||||
}
|
||||
$fields = array('token' => $upToken);
|
||||
if ($key === null) {
|
||||
} else {
|
||||
$fields['key'] = $key;
|
||||
}
|
||||
|
||||
//enable crc32 check by default
|
||||
$fields['crc32'] = \Qiniu\crc32_data($data);
|
||||
|
||||
if ($params) {
|
||||
foreach ($params as $k => $v) {
|
||||
$fields[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
list($upHost, $err) = $config->getUpHostV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
|
||||
$response = Client::multipartPost(
|
||||
$upHost,
|
||||
$fields,
|
||||
'file',
|
||||
$fname,
|
||||
$data,
|
||||
$mime,
|
||||
array(),
|
||||
$reqOpt
|
||||
);
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($upHost, $response));
|
||||
}
|
||||
return array($response->json(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到七牛,内部使用
|
||||
*
|
||||
* @param string $upToken 上传凭证
|
||||
* @param string $key 上传文件名
|
||||
* @param string $filePath 上传文件的路径
|
||||
* @param Config $config 上传配置
|
||||
* @param string $params 自定义变量,规格参考
|
||||
* https://developer.qiniu.com/kodo/manual/1235/vars#xvar
|
||||
* @param string $mime 上传数据的mimeType
|
||||
*
|
||||
* @return array 包含已上传文件的信息,类似:
|
||||
* [
|
||||
* "hash" => "<Hash string>",
|
||||
* "key" => "<Key string>"
|
||||
* ]
|
||||
*/
|
||||
public static function putFile(
|
||||
$upToken,
|
||||
$key,
|
||||
$filePath,
|
||||
$config,
|
||||
$params,
|
||||
$mime,
|
||||
$reqOpt = null
|
||||
) {
|
||||
if ($reqOpt == null) {
|
||||
$reqOpt = new RequestOptions();
|
||||
}
|
||||
|
||||
$fields = array('token' => $upToken, 'file' => self::createFile($filePath, $mime));
|
||||
if ($key !== null) {
|
||||
$fields['key'] = $key;
|
||||
}
|
||||
|
||||
$fields['crc32'] = \Qiniu\crc32_file($filePath);
|
||||
|
||||
if ($params) {
|
||||
foreach ($params as $k => $v) {
|
||||
$fields[$k] = $v;
|
||||
}
|
||||
}
|
||||
$fields['key'] = $key;
|
||||
$headers = array('Content-Type' => 'multipart/form-data');
|
||||
|
||||
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
list($upHost, $err) = $config->getUpHostV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$response = Client::post($upHost, $fields, $headers, $reqOpt);
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($upHost, $response));
|
||||
}
|
||||
return array($response->json(), null);
|
||||
}
|
||||
|
||||
private static function createFile($filename, $mime)
|
||||
{
|
||||
// PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax
|
||||
// See: https://wiki.php.net/rfc/curl-file-upload
|
||||
if (function_exists('curl_file_create')) {
|
||||
return curl_file_create($filename, $mime);
|
||||
}
|
||||
|
||||
// Use the old style if using an older version of PHP
|
||||
$value = "@{$filename}";
|
||||
if (!empty($mime)) {
|
||||
$value .= ';type=' . $mime;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
580
vendor/qiniu/php-sdk/src/Qiniu/Storage/ResumeUploader.php
vendored
Normal file
580
vendor/qiniu/php-sdk/src/Qiniu/Storage/ResumeUploader.php
vendored
Normal file
@ -0,0 +1,580 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu\Storage;
|
||||
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\Client;
|
||||
use Qiniu\Http\Error;
|
||||
use Qiniu\Enum\SplitUploadVersion;
|
||||
use Qiniu\Http\RequestOptions;
|
||||
|
||||
/**
|
||||
* 断点续上传类, 该类主要实现了断点续上传中的分块上传,
|
||||
* 以及相应地创建块和创建文件过程.
|
||||
*
|
||||
* @link http://developer.qiniu.com/docs/v6/api/reference/up/mkblk.html
|
||||
* @link http://developer.qiniu.com/docs/v6/api/reference/up/mkfile.html
|
||||
*/
|
||||
final class ResumeUploader
|
||||
{
|
||||
private $upToken;
|
||||
private $key;
|
||||
private $inputStream;
|
||||
private $size;
|
||||
private $params;
|
||||
private $mime;
|
||||
private $contexts;
|
||||
private $finishedEtags;
|
||||
private $host;
|
||||
private $bucket;
|
||||
private $currentUrl;
|
||||
private $config;
|
||||
private $resumeRecordFile;
|
||||
private $version;
|
||||
private $partSize;
|
||||
/**
|
||||
* @var RequestOptions
|
||||
*/
|
||||
private $reqOpt;
|
||||
|
||||
/**
|
||||
* 上传二进制流到七牛
|
||||
*
|
||||
* @param string $upToken 上传凭证
|
||||
* @param string $key 上传文件名
|
||||
* @param resource $inputStream 上传二进制流
|
||||
* @param int $size 上传流的大小
|
||||
* @param array<string, string> $params 自定义变量
|
||||
* @param string $mime 上传数据的mimeType
|
||||
* @param Config $config
|
||||
* @param string $resumeRecordFile 断点续传的已上传的部分信息记录文件
|
||||
* @param string $version 分片上传版本 目前支持v1/v2版本 默认v1
|
||||
* @param int $partSize 分片上传v2字段 默认大小为4MB 分片大小范围为1 MB - 1 GB
|
||||
* @param RequestOptions $reqOpt 分片上传v2字段 默认大小为4MB 分片大小范围为1 MB - 1 GB
|
||||
* @throws \Exception
|
||||
*
|
||||
* @link http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
|
||||
*/
|
||||
public function __construct(
|
||||
$upToken,
|
||||
$key,
|
||||
$inputStream,
|
||||
$size,
|
||||
$params,
|
||||
$mime,
|
||||
$config,
|
||||
$resumeRecordFile = null,
|
||||
$version = 'v1',
|
||||
$partSize = config::BLOCK_SIZE,
|
||||
$reqOpt = null
|
||||
) {
|
||||
|
||||
$this->upToken = $upToken;
|
||||
$this->key = $key;
|
||||
$this->inputStream = $inputStream;
|
||||
$this->size = $size;
|
||||
$this->params = $params;
|
||||
$this->mime = $mime;
|
||||
$this->contexts = array();
|
||||
$this->finishedEtags = array("etags" => array(), "uploadId" => "", "expiredAt" => 0, "uploaded" => 0);
|
||||
$this->config = $config;
|
||||
$this->resumeRecordFile = $resumeRecordFile ? $resumeRecordFile : null;
|
||||
$this->partSize = $partSize ? $partSize : config::BLOCK_SIZE;
|
||||
|
||||
if ($reqOpt === null) {
|
||||
$reqOpt = new RequestOptions();
|
||||
}
|
||||
$this->reqOpt = $reqOpt;
|
||||
|
||||
try {
|
||||
$this->version = SplitUploadVersion::from($version ? $version : 'v1');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("only support v1/v2 now!", 0, $e);
|
||||
}
|
||||
|
||||
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
|
||||
$this->bucket = $bucket;
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
list($upHost, $err) = $config->getUpHostV2($accessKey, $bucket, $reqOpt);
|
||||
if ($err != null) {
|
||||
throw new \Exception($err->message(), 1);
|
||||
}
|
||||
$this->host = $upHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传操作
|
||||
* @param $fname string 文件名
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function upload($fname)
|
||||
{
|
||||
$blkputRets = null;
|
||||
// get upload record from resumeRecordFile
|
||||
if ($this->resumeRecordFile != null) {
|
||||
if (file_exists($this->resumeRecordFile)) {
|
||||
$stream = fopen($this->resumeRecordFile, 'r');
|
||||
if ($stream) {
|
||||
$streamLen = filesize($this->resumeRecordFile);
|
||||
if ($streamLen > 0) {
|
||||
$contents = fread($stream, $streamLen);
|
||||
fclose($stream);
|
||||
if ($contents) {
|
||||
$blkputRets = json_decode($contents, true);
|
||||
if ($blkputRets === null) {
|
||||
error_log("resumeFile contents decode error");
|
||||
}
|
||||
} else {
|
||||
error_log("read resumeFile failed");
|
||||
}
|
||||
} else {
|
||||
error_log("resumeFile is empty");
|
||||
}
|
||||
} else {
|
||||
error_log("resumeFile open failed");
|
||||
}
|
||||
} else {
|
||||
error_log("resumeFile not exists");
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->version == SplitUploadVersion::V1) {
|
||||
return $this->uploadV1($fname, $blkputRets);
|
||||
} elseif ($this->version == SplitUploadVersion::V2) {
|
||||
return $this->uploadV2($fname, $blkputRets);
|
||||
} else {
|
||||
throw new \Exception("only support v1/v2 now!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fname 文件名
|
||||
* @param null|array $blkputRets
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function uploadV1($fname, $blkputRets = null)
|
||||
{
|
||||
// 尝试恢复恢复已上传的数据
|
||||
$isResumeUpload = $blkputRets !== null;
|
||||
$this->contexts = array();
|
||||
|
||||
if ($blkputRets) {
|
||||
if (isset($blkputRets['contexts']) && isset($blkputRets['uploaded']) &&
|
||||
is_array($blkputRets['contexts']) && is_int($blkputRets['uploaded'])
|
||||
) {
|
||||
$this->contexts = array_map(function ($ctx) {
|
||||
if (is_array($ctx)) {
|
||||
return $ctx;
|
||||
} else {
|
||||
// 兼容旧版本(旧版本没有存储 expireAt)
|
||||
return array(
|
||||
"ctx" => $ctx,
|
||||
"expiredAt" => 0,
|
||||
);
|
||||
}
|
||||
}, $blkputRets['contexts']);
|
||||
}
|
||||
}
|
||||
|
||||
// 上传分片
|
||||
$uploaded = 0;
|
||||
while ($uploaded < $this->size) {
|
||||
$blockSize = $this->blockSize($uploaded);
|
||||
$blockIndex = $uploaded / $this->partSize;
|
||||
if (!is_int($blockIndex)) {
|
||||
throw new \Exception("v1 part size changed");
|
||||
}
|
||||
// 如果已上传该分片且没有过期
|
||||
if (isset($this->contexts[$blockIndex]) && $this->contexts[$blockIndex]["expiredAt"] >= time()) {
|
||||
$uploaded += $blockSize;
|
||||
fseek($this->inputStream, $blockSize, SEEK_CUR);
|
||||
continue;
|
||||
}
|
||||
$data = fread($this->inputStream, $blockSize);
|
||||
if ($data === false) {
|
||||
throw new \Exception("file read failed", 1);
|
||||
}
|
||||
$crc = \Qiniu\crc32_data($data);
|
||||
$response = $this->makeBlock($data, $blockSize);
|
||||
|
||||
|
||||
$ret = null;
|
||||
if ($response->ok() && $response->json() != null) {
|
||||
$ret = $response->json();
|
||||
}
|
||||
if ($response->statusCode < 0) {
|
||||
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($this->upToken);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
list($upHostBackup, $err) = $this->config->getUpBackupHostV2($accessKey, $bucket, $this->reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
$this->host = $upHostBackup;
|
||||
}
|
||||
|
||||
if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
|
||||
$response = $this->makeBlock($data, $blockSize);
|
||||
$ret = $response->json();
|
||||
}
|
||||
if (!$response->ok() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
|
||||
return array(null, new Error($this->currentUrl, $response));
|
||||
}
|
||||
|
||||
// 如果可以在已上传取到说明是过期分片直接修改已上传信息,否则是新的片添加到已上传分片尾部
|
||||
if (isset($this->contexts[$blockIndex])) {
|
||||
$this->contexts[$blockIndex] = array(
|
||||
'ctx' => $ret['ctx'],
|
||||
'expiredAt' => $ret['expired_at'],
|
||||
);
|
||||
} else {
|
||||
array_push($this->contexts, array(
|
||||
'ctx' => $ret['ctx'],
|
||||
'expiredAt' => $ret['expired_at'],
|
||||
));
|
||||
}
|
||||
$uploaded += $blockSize;
|
||||
|
||||
// 记录断点
|
||||
if ($this->resumeRecordFile !== null) {
|
||||
$recordData = array(
|
||||
'contexts' => $this->contexts,
|
||||
'uploaded' => $uploaded
|
||||
);
|
||||
$recordData = json_encode($recordData);
|
||||
|
||||
if ($recordData) {
|
||||
$isWritten = file_put_contents($this->resumeRecordFile, $recordData);
|
||||
if ($isWritten === false) {
|
||||
error_log("write resumeRecordFile failed");
|
||||
}
|
||||
} else {
|
||||
error_log('resumeRecordData encode failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 完成上传
|
||||
list($ret, $err) = $this->makeFile($fname);
|
||||
if ($err !== null) {
|
||||
$response = $err->getResponse();
|
||||
if ($isResumeUpload && $response->statusCode === 701) {
|
||||
fseek($this->inputStream, 0);
|
||||
return $this->uploadV1($fname);
|
||||
}
|
||||
}
|
||||
return array($ret, $err);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fname 文件名
|
||||
* @param null|array $blkputRets
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function uploadV2($fname, $blkputRets = null)
|
||||
{
|
||||
$uploaded = 0;
|
||||
$partNumber = 1;
|
||||
$encodedObjectName = $this->key ? \Qiniu\base64_urlSafeEncode($this->key) : '~';
|
||||
$isResumeUpload = $blkputRets !== null;
|
||||
|
||||
// 初始化 upload id
|
||||
$err = null;
|
||||
if ($blkputRets) {
|
||||
if (isset($blkputRets["etags"]) && isset($blkputRets["uploadId"]) &&
|
||||
isset($blkputRets["expiredAt"]) && $blkputRets["expiredAt"] > time() &&
|
||||
$blkputRets["uploaded"] > 0 && is_array($blkputRets["etags"]) &&
|
||||
is_string($blkputRets["uploadId"]) && is_int($blkputRets["expiredAt"])
|
||||
) {
|
||||
$this->finishedEtags['etags'] = $blkputRets["etags"];
|
||||
$this->finishedEtags["uploadId"] = $blkputRets["uploadId"];
|
||||
$this->finishedEtags["expiredAt"] = $blkputRets["expiredAt"];
|
||||
$this->finishedEtags["uploaded"] = $blkputRets["uploaded"];
|
||||
$uploaded = $blkputRets["uploaded"];
|
||||
$partNumber = count($this->finishedEtags["etags"]) + 1;
|
||||
} else {
|
||||
$err = $this->makeInitReq($encodedObjectName);
|
||||
}
|
||||
} else {
|
||||
$err = $this->makeInitReq($encodedObjectName);
|
||||
}
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
// 上传分片
|
||||
fseek($this->inputStream, $uploaded);
|
||||
while ($uploaded < $this->size) {
|
||||
$blockSize = $this->blockSize($uploaded);
|
||||
$data = fread($this->inputStream, $blockSize);
|
||||
if ($data === false) {
|
||||
throw new \Exception("file read failed", 1);
|
||||
}
|
||||
$md5 = md5($data);
|
||||
$response = $this->uploadPart(
|
||||
$data,
|
||||
$partNumber,
|
||||
$this->finishedEtags["uploadId"],
|
||||
$encodedObjectName,
|
||||
$md5
|
||||
);
|
||||
|
||||
$ret = null;
|
||||
if ($response->ok() && $response->json() != null) {
|
||||
$ret = $response->json();
|
||||
}
|
||||
if ($response->statusCode < 0) {
|
||||
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($this->upToken);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
list($upHostBackup, $err) = $this->config->getUpBackupHostV2($accessKey, $bucket, $this->reqOpt);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
$this->host = $upHostBackup;
|
||||
}
|
||||
|
||||
if ($response->needRetry() || !isset($ret['md5']) || $md5 != $ret['md5']) {
|
||||
$response = $this->uploadPart(
|
||||
$data,
|
||||
$partNumber,
|
||||
$this->finishedEtags["uploadId"],
|
||||
$encodedObjectName,
|
||||
$md5
|
||||
);
|
||||
$ret = $response->json();
|
||||
}
|
||||
if ($isResumeUpload && $response->statusCode === 612) {
|
||||
return $this->uploadV2($fname);
|
||||
}
|
||||
if (!$response->ok() || !isset($ret['md5']) || $md5 != $ret['md5']) {
|
||||
return array(null, new Error($this->currentUrl, $response));
|
||||
}
|
||||
$blockStatus = array('etag' => $ret['etag'], 'partNumber' => $partNumber);
|
||||
array_push($this->finishedEtags['etags'], $blockStatus);
|
||||
$partNumber += 1;
|
||||
|
||||
$uploaded += $blockSize;
|
||||
$this->finishedEtags['uploaded'] = $uploaded;
|
||||
|
||||
if ($this->resumeRecordFile !== null) {
|
||||
$recordData = json_encode($this->finishedEtags);
|
||||
if ($recordData) {
|
||||
$isWritten = file_put_contents($this->resumeRecordFile, $recordData);
|
||||
if ($isWritten === false) {
|
||||
error_log("write resumeRecordFile failed");
|
||||
}
|
||||
} else {
|
||||
error_log('resumeRecordData encode failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list($ret, $err) = $this->completeParts($fname, $this->finishedEtags['uploadId'], $encodedObjectName);
|
||||
if ($err !== null) {
|
||||
$response = $err->getResponse();
|
||||
if ($isResumeUpload && $response->statusCode === 612) {
|
||||
return $this->uploadV2($fname);
|
||||
}
|
||||
}
|
||||
return array($ret, $err);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建块
|
||||
*/
|
||||
private function makeBlock($block, $blockSize)
|
||||
{
|
||||
$url = $this->host . '/mkblk/' . $blockSize;
|
||||
return $this->post($url, $block);
|
||||
}
|
||||
|
||||
private function fileUrl($fname)
|
||||
{
|
||||
$url = $this->host . '/mkfile/' . $this->size;
|
||||
$url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime);
|
||||
if ($this->key != null) {
|
||||
$url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key);
|
||||
}
|
||||
$url .= '/fname/' . \Qiniu\base64_urlSafeEncode($fname);
|
||||
if (!empty($this->params)) {
|
||||
foreach ($this->params as $key => $value) {
|
||||
$val = \Qiniu\base64_urlSafeEncode($value);
|
||||
$url .= "/$key/$val";
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
*
|
||||
* @param string $fname 文件名
|
||||
* @return array{array | null, Error | null}
|
||||
*/
|
||||
private function makeFile($fname)
|
||||
{
|
||||
$url = $this->fileUrl($fname);
|
||||
$body = implode(',', array_map(function ($ctx) {
|
||||
return $ctx['ctx'];
|
||||
}, $this->contexts));
|
||||
$response = $this->post($url, $body);
|
||||
if ($response->needRetry()) {
|
||||
$response = $this->post($url, $body);
|
||||
}
|
||||
if ($response->statusCode === 200 || $response->statusCode === 701) {
|
||||
if ($this->resumeRecordFile !== null) {
|
||||
@unlink($this->resumeRecordFile);
|
||||
}
|
||||
}
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($this->currentUrl, $response));
|
||||
}
|
||||
return array($response->json(), null);
|
||||
}
|
||||
|
||||
private function post($url, $data)
|
||||
{
|
||||
$this->currentUrl = $url;
|
||||
$headers = array('Authorization' => 'UpToken ' . $this->upToken);
|
||||
return Client::post($url, $data, $headers, $this->reqOpt);
|
||||
}
|
||||
|
||||
private function blockSize($uploaded)
|
||||
{
|
||||
if ($this->size < $uploaded + $this->partSize) {
|
||||
return $this->size - $uploaded;
|
||||
}
|
||||
return $this->partSize;
|
||||
}
|
||||
|
||||
private function makeInitReq($encodedObjectName)
|
||||
{
|
||||
list($ret, $err) = $this->initReq($encodedObjectName);
|
||||
|
||||
if ($ret == null) {
|
||||
return $err;
|
||||
}
|
||||
|
||||
$this->finishedEtags["uploadId"] = $ret['uploadId'];
|
||||
$this->finishedEtags["expiredAt"] = $ret['expireAt'];
|
||||
return $err;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化上传任务
|
||||
*/
|
||||
private function initReq($encodedObjectName)
|
||||
{
|
||||
$url = $this->host . '/buckets/' . $this->bucket . '/objects/' . $encodedObjectName . '/uploads';
|
||||
$headers = array(
|
||||
'Authorization' => 'UpToken ' . $this->upToken,
|
||||
'Content-Type' => 'application/json'
|
||||
);
|
||||
$response = $this->postWithHeaders($url, null, $headers);
|
||||
$ret = $response->json();
|
||||
if ($response->ok() && $ret != null) {
|
||||
return array($ret, null);
|
||||
}
|
||||
|
||||
return array(null, new Error($url, $response));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分块上传v2
|
||||
*/
|
||||
private function uploadPart($block, $partNumber, $uploadId, $encodedObjectName, $md5)
|
||||
{
|
||||
$headers = array(
|
||||
'Authorization' => 'UpToken ' . $this->upToken,
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-MD5' => $md5
|
||||
);
|
||||
$url = $this->host . '/buckets/' . $this->bucket . '/objects/' . $encodedObjectName .
|
||||
'/uploads/' . $uploadId . '/' . $partNumber;
|
||||
$response = $this->put($url, $block, $headers);
|
||||
if ($response->statusCode === 612) {
|
||||
if ($this->resumeRecordFile !== null) {
|
||||
@unlink($this->resumeRecordFile);
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成分片上传V2
|
||||
*
|
||||
* @param string $fname 文件名
|
||||
* @param int $uploadId 由 {@see initReq} 获取
|
||||
* @param string $encodedObjectName 经过编码的存储路径
|
||||
* @return array{array | null, Error | null}
|
||||
*/
|
||||
private function completeParts($fname, $uploadId, $encodedObjectName)
|
||||
{
|
||||
$headers = array(
|
||||
'Authorization' => 'UpToken ' . $this->upToken,
|
||||
'Content-Type' => 'application/json'
|
||||
);
|
||||
$etags = $this->finishedEtags['etags'];
|
||||
$sortedEtags = \Qiniu\arraySort($etags, 'partNumber');
|
||||
$metadata = array();
|
||||
$customVars = array();
|
||||
if ($this->params) {
|
||||
foreach ($this->params as $k => $v) {
|
||||
if (strpos($k, 'x:') === 0) {
|
||||
$customVars[$k] = $v;
|
||||
} elseif (strpos($k, 'x-qn-meta-') === 0) {
|
||||
$metadata[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($metadata)) {
|
||||
$metadata = null;
|
||||
}
|
||||
if (empty($customVars)) {
|
||||
$customVars = null;
|
||||
}
|
||||
$body = array(
|
||||
'fname' => $fname,
|
||||
'mimeType' => $this->mime,
|
||||
'metadata' => $metadata,
|
||||
'customVars' => $customVars,
|
||||
'parts' => $sortedEtags
|
||||
);
|
||||
$jsonBody = json_encode($body);
|
||||
$url = $this->host . '/buckets/' . $this->bucket . '/objects/' . $encodedObjectName . '/uploads/' . $uploadId;
|
||||
$response = $this->postWithHeaders($url, $jsonBody, $headers);
|
||||
if ($response->needRetry()) {
|
||||
$response = $this->postWithHeaders($url, $jsonBody, $headers);
|
||||
}
|
||||
if ($response->statusCode === 200 || $response->statusCode === 612) {
|
||||
if ($this->resumeRecordFile !== null) {
|
||||
@unlink($this->resumeRecordFile);
|
||||
}
|
||||
}
|
||||
if (!$response->ok()) {
|
||||
return array(null, new Error($this->currentUrl, $response));
|
||||
}
|
||||
return array($response->json(), null);
|
||||
}
|
||||
|
||||
private function put($url, $data, $headers)
|
||||
{
|
||||
$this->currentUrl = $url;
|
||||
return Client::put($url, $data, $headers, $this->reqOpt);
|
||||
}
|
||||
|
||||
private function postWithHeaders($url, $data, $headers)
|
||||
{
|
||||
$this->currentUrl = $url;
|
||||
return Client::post($url, $data, $headers, $this->reqOpt);
|
||||
}
|
||||
}
|
||||
176
vendor/qiniu/php-sdk/src/Qiniu/Storage/UploadManager.php
vendored
Normal file
176
vendor/qiniu/php-sdk/src/Qiniu/Storage/UploadManager.php
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
namespace Qiniu\Storage;
|
||||
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Http\HttpClient;
|
||||
use Qiniu\Http\RequestOptions;
|
||||
use Qiniu\Storage\ResumeUploader;
|
||||
use Qiniu\Storage\FormUploader;
|
||||
|
||||
/**
|
||||
* 主要涉及了资源上传接口的实现
|
||||
*
|
||||
* @link http://developer.qiniu.com/docs/v6/api/reference/up/
|
||||
*/
|
||||
final class UploadManager
|
||||
{
|
||||
private $config;
|
||||
/**
|
||||
* @var RequestOptions
|
||||
*/
|
||||
private $reqOpt;
|
||||
|
||||
/**
|
||||
* @param Config|null $config
|
||||
* @param RequestOptions|null $reqOpt
|
||||
*/
|
||||
public function __construct(Config $config = null, RequestOptions $reqOpt = null)
|
||||
{
|
||||
if ($config === null) {
|
||||
$config = new Config();
|
||||
}
|
||||
$this->config = $config;
|
||||
|
||||
if ($reqOpt === null) {
|
||||
$reqOpt = new RequestOptions();
|
||||
}
|
||||
|
||||
$this->reqOpt = $reqOpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传二进制流到七牛
|
||||
*
|
||||
* @param string $upToken 上传凭证
|
||||
* @param string $key 上传文件名
|
||||
* @param string $data 上传二进制流
|
||||
* @param array<string, string> $params 自定义变量,规格参考
|
||||
* http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
|
||||
* @param string $mime 上传数据的mimeType
|
||||
* @param string $fname
|
||||
* @param RequestOptions $reqOpt
|
||||
* @return array 包含已上传文件的信息,类似:
|
||||
* [
|
||||
* "hash" => "<Hash string>",
|
||||
* "key" => "<Key string>"
|
||||
* ]
|
||||
*/
|
||||
public function put(
|
||||
$upToken,
|
||||
$key,
|
||||
$data,
|
||||
$params = null,
|
||||
$mime = 'application/octet-stream',
|
||||
$fname = "default_filename",
|
||||
$reqOpt = null
|
||||
) {
|
||||
$reqOpt = $reqOpt === null ? $this->reqOpt : $reqOpt;
|
||||
|
||||
$params = self::trimParams($params);
|
||||
return FormUploader::put(
|
||||
$upToken,
|
||||
$key,
|
||||
$data,
|
||||
$this->config,
|
||||
$params,
|
||||
$mime,
|
||||
$fname,
|
||||
$reqOpt
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到七牛
|
||||
*
|
||||
* @param string $upToken 上传凭证
|
||||
* @param string $key 上传文件名
|
||||
* @param string $filePath 上传文件的路径
|
||||
* @param array<string, mixed> $params 定义变量,规格参考
|
||||
* http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
|
||||
* @param boolean $mime 上传数据的mimeType
|
||||
* @param string $checkCrc 是否校验crc32
|
||||
* @param string $resumeRecordFile 断点续传文件路径 默认为null
|
||||
* @param string $version 分片上传版本 目前支持v1/v2版本 默认v1
|
||||
* @param int $partSize 分片上传v2字段 默认大小为4MB 分片大小范围为1 MB - 1 GB
|
||||
*
|
||||
* @return array<string, mixed> 包含已上传文件的信息,类似:
|
||||
* [
|
||||
* "hash" => "<Hash string>",
|
||||
* "key" => "<Key string>"
|
||||
* ]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function putFile(
|
||||
$upToken,
|
||||
$key,
|
||||
$filePath,
|
||||
$params = null,
|
||||
$mime = 'application/octet-stream',
|
||||
$checkCrc = false,
|
||||
$resumeRecordFile = null,
|
||||
$version = 'v1',
|
||||
$partSize = config::BLOCK_SIZE,
|
||||
$reqOpt = null
|
||||
) {
|
||||
$reqOpt = $reqOpt === null ? $this->reqOpt : $reqOpt;
|
||||
|
||||
$file = fopen($filePath, 'rb');
|
||||
if ($file === false) {
|
||||
throw new \Exception("file can not open", 1);
|
||||
}
|
||||
$params = self::trimParams($params);
|
||||
$stat = fstat($file);
|
||||
$size = $stat['size'];
|
||||
if ($size <= Config::BLOCK_SIZE) {
|
||||
$data = fread($file, $size);
|
||||
fclose($file);
|
||||
if ($data === false) {
|
||||
throw new \Exception("file can not read", 1);
|
||||
}
|
||||
return FormUploader::put(
|
||||
$upToken,
|
||||
$key,
|
||||
$data,
|
||||
$this->config,
|
||||
$params,
|
||||
$mime,
|
||||
basename($filePath),
|
||||
$reqOpt
|
||||
);
|
||||
}
|
||||
|
||||
$up = new ResumeUploader(
|
||||
$upToken,
|
||||
$key,
|
||||
$file,
|
||||
$size,
|
||||
$params,
|
||||
$mime,
|
||||
$this->config,
|
||||
$resumeRecordFile,
|
||||
$version,
|
||||
$partSize,
|
||||
$reqOpt
|
||||
);
|
||||
$ret = $up->upload(basename($filePath));
|
||||
fclose($file);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function trimParams($params)
|
||||
{
|
||||
if ($params === null) {
|
||||
return null;
|
||||
}
|
||||
$ret = array();
|
||||
foreach ($params as $k => $v) {
|
||||
$pos1 = strpos($k, 'x:');
|
||||
$pos2 = strpos($k, 'x-qn-meta-');
|
||||
if (($pos1 === 0 || $pos2 === 0) && !empty($v)) {
|
||||
$ret[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
58
vendor/qiniu/php-sdk/src/Qiniu/Zone.php
vendored
Normal file
58
vendor/qiniu/php-sdk/src/Qiniu/Zone.php
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace Qiniu;
|
||||
|
||||
use Qiniu\Region;
|
||||
|
||||
class Zone extends Region
|
||||
{
|
||||
public static function zonez0()
|
||||
{
|
||||
return parent::regionHuadong();
|
||||
}
|
||||
|
||||
public static function zonez1()
|
||||
{
|
||||
return parent::regionHuabei();
|
||||
}
|
||||
|
||||
public static function zonez2()
|
||||
{
|
||||
return parent::regionHuanan();
|
||||
}
|
||||
|
||||
public static function zoneCnEast2()
|
||||
{
|
||||
return parent::regionHuadong2();
|
||||
}
|
||||
|
||||
public static function zoneAs0()
|
||||
{
|
||||
return parent::regionSingapore();
|
||||
}
|
||||
|
||||
public static function zoneNa0()
|
||||
{
|
||||
return parent::regionNorthAmerica();
|
||||
}
|
||||
|
||||
public static function qvmZonez0()
|
||||
{
|
||||
return parent::qvmRegionHuadong();
|
||||
}
|
||||
|
||||
public static function qvmZonez1()
|
||||
{
|
||||
return parent::qvmRegionHuabei();
|
||||
}
|
||||
|
||||
public static function queryZone(
|
||||
$ak,
|
||||
$bucket,
|
||||
$ucHost = null,
|
||||
$backupUcHosts = array(),
|
||||
$retryTimes = 2,
|
||||
$reqOpt = null
|
||||
) {
|
||||
return parent::queryRegion($ak, $bucket, $ucHost, $backupUcHosts, $retryTimes, $reqOpt);
|
||||
}
|
||||
}
|
||||
346
vendor/qiniu/php-sdk/src/Qiniu/functions.php
vendored
Normal file
346
vendor/qiniu/php-sdk/src/Qiniu/functions.php
vendored
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
|
||||
namespace Qiniu;
|
||||
|
||||
use Qiniu\Config;
|
||||
|
||||
if (!defined('QINIU_FUNCTIONS_VERSION')) {
|
||||
define('QINIU_FUNCTIONS_VERSION', Config::SDK_VER);
|
||||
|
||||
/**
|
||||
* 计算文件的crc32检验码:
|
||||
*
|
||||
* @param $file string 待计算校验码的文件路径
|
||||
*
|
||||
* @return string 文件内容的crc32校验码
|
||||
*/
|
||||
function crc32_file($file)
|
||||
{
|
||||
$hash = hash_file('crc32b', $file);
|
||||
$array = unpack('N', pack('H*', $hash));
|
||||
return sprintf('%u', $array[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算输入流的crc32检验码
|
||||
*
|
||||
* @param $data string 待计算校验码的字符串
|
||||
*
|
||||
* @return string 输入字符串的crc32校验码
|
||||
*/
|
||||
function crc32_data($data)
|
||||
{
|
||||
$hash = hash('crc32b', $data);
|
||||
$array = unpack('N', pack('H*', $hash));
|
||||
return sprintf('%u', $array[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对提供的数据进行urlsafe的base64编码。
|
||||
*
|
||||
* @param string $data 待编码的数据,一般为字符串
|
||||
*
|
||||
* @return string 编码后的字符串
|
||||
* @link http://developer.qiniu.com/docs/v6/api/overview/appendix.html#urlsafe-base64
|
||||
*/
|
||||
function base64_urlSafeEncode($data)
|
||||
{
|
||||
$find = array('+', '/');
|
||||
$replace = array('-', '_');
|
||||
return str_replace($find, $replace, base64_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对提供的urlsafe的base64编码的数据进行解码
|
||||
*
|
||||
* @param string $str 待解码的数据,一般为字符串
|
||||
*
|
||||
* @return string 解码后的字符串
|
||||
*/
|
||||
function base64_urlSafeDecode($str)
|
||||
{
|
||||
$find = array('-', '_');
|
||||
$replace = array('+', '/');
|
||||
return base64_decode(str_replace($find, $replace, $str));
|
||||
}
|
||||
|
||||
/**
|
||||
* 二维数组根据某个字段排序
|
||||
* @param array $array 要排序的数组
|
||||
* @param string $key 要排序的键
|
||||
* @param string $sort 排序类型 SORT_ASC SORT_DESC
|
||||
* return array 排序后的数组
|
||||
*/
|
||||
function arraySort($array, $key, $sort = SORT_ASC)
|
||||
{
|
||||
$keysValue = array();
|
||||
foreach ($array as $k => $v) {
|
||||
$keysValue[$k] = $v[$key];
|
||||
}
|
||||
array_multisort($keysValue, $sort, $array);
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for JSON decode that implements error detection with helpful
|
||||
* error messages.
|
||||
*
|
||||
* @param string $json JSON data to parse
|
||||
* @param bool $assoc When true, returned objects will be converted
|
||||
* into associative arrays.
|
||||
* @param int $depth User specified recursion depth.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException if the JSON cannot be parsed.
|
||||
* @link http://www.php.net/manual/en/function.json-decode.php
|
||||
*/
|
||||
function json_decode($json, $assoc = false, $depth = 512)
|
||||
{
|
||||
static $jsonErrors = array(
|
||||
JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
|
||||
JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
|
||||
JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
|
||||
JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
|
||||
JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
|
||||
);
|
||||
|
||||
if (empty($json)) {
|
||||
return null;
|
||||
}
|
||||
$data = \json_decode($json, $assoc, $depth);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
$last = json_last_error();
|
||||
throw new \InvalidArgumentException(
|
||||
'Unable to parse JSON data: '
|
||||
. (isset($jsonErrors[$last])
|
||||
? $jsonErrors[$last]
|
||||
: 'Unknown error')
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算七牛API中的数据格式
|
||||
*
|
||||
* @param string $bucket 待操作的空间名
|
||||
* @param string $key 待操作的文件名
|
||||
*
|
||||
* @return string 符合七牛API规格的数据格式
|
||||
* @link https://developer.qiniu.com/kodo/api/data-format
|
||||
*/
|
||||
function entry($bucket, $key = null)
|
||||
{
|
||||
$en = $bucket;
|
||||
if ($key !== null) {
|
||||
$en = $bucket . ':' . $key;
|
||||
}
|
||||
return base64_urlSafeEncode($en);
|
||||
}
|
||||
|
||||
function decodeEntry($entry)
|
||||
{
|
||||
$en = base64_urlSafeDecode($entry);
|
||||
$en = explode(':', $en);
|
||||
if (count($en) == 1) {
|
||||
return array($en[0], null);
|
||||
}
|
||||
return array($en[0], $en[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* array 辅助方法,无值时不set
|
||||
*
|
||||
* @param array $array 待操作array
|
||||
* @param string $key key
|
||||
* @param string $value value 为null时 不设置
|
||||
*
|
||||
* @return array 原来的array,便于连续操作
|
||||
*/
|
||||
function setWithoutEmpty(&$array, $key, $value)
|
||||
{
|
||||
if (!empty($value)) {
|
||||
$array[$key] = $value;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩略图链接拼接
|
||||
*
|
||||
* @param string $url 图片链接
|
||||
* @param int $mode 缩略模式
|
||||
* @param int $width 宽度
|
||||
* @param int $height 长度
|
||||
* @param string $format 输出类型
|
||||
* @param int $quality 图片质量
|
||||
* @param int $interlace 是否支持渐进显示
|
||||
* @param int $ignoreError 忽略结果
|
||||
* @return string
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
function thumbnail(
|
||||
$url,
|
||||
$mode,
|
||||
$width,
|
||||
$height,
|
||||
$format = null,
|
||||
$quality = null,
|
||||
$interlace = null,
|
||||
$ignoreError = 1
|
||||
) {
|
||||
|
||||
static $imageUrlBuilder = null;
|
||||
if (is_null($imageUrlBuilder)) {
|
||||
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
|
||||
}
|
||||
|
||||
return call_user_func_array(array($imageUrlBuilder, 'thumbnail'), func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片水印
|
||||
*
|
||||
* @param string $url 图片链接
|
||||
* @param string $image 水印图片链接
|
||||
* @param numeric $dissolve 透明度
|
||||
* @param string $gravity 水印位置
|
||||
* @param numeric $dx 横轴边距
|
||||
* @param numeric $dy 纵轴边距
|
||||
* @param numeric $watermarkScale 自适应原图的短边比例
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
|
||||
* @return string
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
function waterImg(
|
||||
$url,
|
||||
$image,
|
||||
$dissolve = 100,
|
||||
$gravity = 'SouthEast',
|
||||
$dx = null,
|
||||
$dy = null,
|
||||
$watermarkScale = null
|
||||
) {
|
||||
|
||||
static $imageUrlBuilder = null;
|
||||
if (is_null($imageUrlBuilder)) {
|
||||
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
|
||||
}
|
||||
|
||||
return call_user_func_array(array($imageUrlBuilder, 'waterImg'), func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* 文字水印
|
||||
*
|
||||
* @param string $url 图片链接
|
||||
* @param string $text 文字
|
||||
* @param string $font 文字字体
|
||||
* @param string $fontSize 文字字号
|
||||
* @param string $fontColor 文字颜色
|
||||
* @param numeric $dissolve 透明度
|
||||
* @param string $gravity 水印位置
|
||||
* @param numeric $dx 横轴边距
|
||||
* @param numeric $dy 纵轴边距
|
||||
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
|
||||
* @return string
|
||||
* @author Sherlock Ren <sherlock_ren@icloud.com>
|
||||
*/
|
||||
function waterText(
|
||||
$url,
|
||||
$text,
|
||||
$font = '黑体',
|
||||
$fontSize = 0,
|
||||
$fontColor = null,
|
||||
$dissolve = 100,
|
||||
$gravity = 'SouthEast',
|
||||
$dx = null,
|
||||
$dy = null
|
||||
) {
|
||||
|
||||
static $imageUrlBuilder = null;
|
||||
if (is_null($imageUrlBuilder)) {
|
||||
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
|
||||
}
|
||||
|
||||
return call_user_func_array(array($imageUrlBuilder, 'waterText'), func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从uptoken解析accessKey和bucket
|
||||
*
|
||||
* @param $upToken
|
||||
* @return array(ak,bucket,err=null)
|
||||
*/
|
||||
function explodeUpToken($upToken)
|
||||
{
|
||||
$items = explode(':', $upToken);
|
||||
if (count($items) != 3) {
|
||||
return array(null, null, "invalid uptoken");
|
||||
}
|
||||
$accessKey = $items[0];
|
||||
$putPolicy = json_decode(base64_urlSafeDecode($items[2]));
|
||||
$scope = $putPolicy->scope;
|
||||
$scopeItems = explode(':', $scope);
|
||||
$bucket = $scopeItems[0];
|
||||
return array($accessKey, $bucket, null);
|
||||
}
|
||||
|
||||
// polyfill ucwords for `php version < 5.4.32` or `5.5.0 <= php version < 5.5.16`
|
||||
if (version_compare(phpversion(), "5.4.32") < 0 ||
|
||||
(
|
||||
version_compare(phpversion(), "5.5.0") >= 0 &&
|
||||
version_compare(phpversion(), "5.5.16") < 0
|
||||
)
|
||||
) {
|
||||
function ucwords($str, $delimiters = " \t\r\n\f\v")
|
||||
{
|
||||
$delims = preg_split('//u', $delimiters, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
foreach ($delims as $delim) {
|
||||
$str = implode($delim, array_map('ucfirst', explode($delim, $str)));
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
} else {
|
||||
function ucwords($str, $delimiters)
|
||||
{
|
||||
return \ucwords($str, $delimiters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 parse_url 的结果转换回字符串
|
||||
* TODO: add unit test
|
||||
*
|
||||
* @param $parsed_url - parse_url 的结果
|
||||
* @return string
|
||||
*/
|
||||
function unparse_url($parsed_url)
|
||||
{
|
||||
|
||||
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
|
||||
|
||||
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
|
||||
|
||||
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
|
||||
|
||||
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
|
||||
|
||||
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
|
||||
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
|
||||
return "$scheme$user$pass$host$port$path$query$fragment";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user