$v) { $newKey = strtolower($k); if (0 !== strpos($k, $prefix)) { $newKey = $prefix . $newKey; } $res[$newKey] = $v; } return $res; } public static function parseMeta($val, $prefix) { if (empty($val)) { return []; } $res = []; foreach ($val as $k => $v) { $newKey = strtolower($k); if (0 === strpos($newKey, $prefix)) { $newKey = str_replace($prefix, '', $newKey); } $res[$newKey] = $v; } return $res; } public static function getContentType($fileName) { $mapping = require(dirname(__DIR__) . '/mime.types.php'); if (!empty($fileName) && !empty(trim($fileName))) { $ext = pathinfo($fileName, PATHINFO_EXTENSION); $ext = strtolower(trim($ext)); if (!empty($mapping['mimes'][$ext])) { return $mapping['mimes'][$ext][0]; } } return null; } public static function getContentMD5($body, $isEnableMD5) { if (false === $isEnableMD5) { return ''; } return base64_encode(md5($body, true)); } public static function encode($val, $encodeType) { $strs = explode('/', $val); $len = \count($strs); switch ($encodeType) { case 'Base64': $strs[$len - 1] = base64_encode($strs[$len - 1]); break; case 'UrlEncode': $strs[$len - 1] = rawurlencode($strs[$len - 1]); break; } return implode('/', $strs); } public static function getUserAgent($val) { if (empty($val)) { return self::getDefaultUserAgent(); } return self::getDefaultUserAgent() . ' ' . $val; } public static function getHost($bucketName, $regionId, $endpoint, $hostModel) { if (empty($regionId) || empty(trim($regionId))) { $regionId = 'cn-hangzhou'; } if (empty($endpoint) || empty(trim($endpoint))) { $endpoint = 'oss-' . $regionId . '.aliyuncs.com'; } if (!empty($bucketName)) { $hostModel = null === $hostModel ? '' : $hostModel; if ('ip' === $hostModel) { $host = $endpoint . '/' . $bucketName; } elseif ('cname' == $hostModel) { $host = $endpoint; } else { $host = $bucketName . '.' . $endpoint; } } else { $host = $endpoint; } return $host; } /** * @param resource $body * @param array $res * * @return VerifyStream */ public static function inject($body, &$res) { return new VerifyStream($body, $res); } /** * @param Request $request * @param string $bucketName * @param string $accessKeyId * @param string $accessKeySecret * @param string $signatureVersion * @param string[] $addtionalHeaders * * @return string */ public static function getSignature($request, $bucketName, $accessKeyId, $accessKeySecret, $signatureVersion, $addtionalHeaders) { $signatureVersion = strtolower($signatureVersion); if ('v2' === $signatureVersion) { if (empty($addtionalHeaders)) { return 'OSS2 AccessKeyId:' . $accessKeyId . ',Signature:' . self::getSignatureV2($request, $bucketName, $accessKeySecret, $addtionalHeaders); } return 'OSS2 AccessKeyId:' . $accessKeyId . ',AdditionalHeaders:' . implode(';', $addtionalHeaders) . ',Signature:' . self::getSignatureV2($request, $bucketName, $accessKeySecret, $addtionalHeaders); } return 'OSS ' . $accessKeyId . ':' . self::getSignatureV1($request, $bucketName, $accessKeySecret); } /** * @param string $val * @param string $decodeType * * @return string */ public static function decode($val, $decodeType) { switch ($decodeType) { case 'Base64Decode': $res = base64_decode($val); return false === $res ? '' : $res; case 'UrlDecode': return rawurldecode($val); } return $val; } private static function parseXml($xmlStr) { if (\PHP_VERSION_ID < 80000) { libxml_disable_entity_loader(true); } $xml = simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA); $rootName = $xml->getName(); return [ $rootName => json_decode( json_encode( $xml ), true ), ]; } private static function getDefaultUserAgent() { if (empty(self::$defaultUserAgent)) { self::$defaultUserAgent = 'Alibaba Cloud (' . PHP_OS . ') '; self::$defaultUserAgent .= 'TeaCore/3'; } return self::$defaultUserAgent; } /** * @param Request $request * @param string $bucketName * @param string $accessKeySecret * * @return string */ private static function getSignatureV1($request, $bucketName, $accessKeySecret) { $canonicalizeResource = ''; if (!empty($bucketName)) { $canonicalizeResource = '/' . $bucketName; } $canonicalizeResource .= $request->pathname; $query = $request->query; ksort($query); if (!empty($query)) { if (false === strpos($canonicalizeResource, '?')) { $canonicalizeResource .= '?'; } foreach ($query as $k => $v) { if (\in_array($k, self::SIGN_KEY_LIST) && null !== $v && '' !== $v) { if ('?' === $canonicalizeResource[\strlen($canonicalizeResource) - 1]) { $canonicalizeResource .= $k . '=' . $v; } else { $canonicalizeResource .= '&' . $k . '=' . $v; } } } } $headers = new Dot($request->headers); $signString = implode("\n", [ strtoupper($request->method), $headers->get('content-md5', ''), $headers->get('content-type', ''), $headers->get('date', ''), implode("\n", self::getCanonicalizeHeaders($request->headers)), $canonicalizeResource, ]); return base64_encode( hash_hmac( 'sha1', $signString, $accessKeySecret, true ) ); } /** * @param Request $request * @param string $bucketName * @param string $accessKeySecret * @param string[] $addtionalHeaders * * @return string */ private static function getSignatureV2($request, $bucketName, $accessKeySecret, $addtionalHeaders) { if (empty($addtionalHeaders)) { $addtionalHeaders = []; } $canonicalizeResource = ''; $pathname = $request->pathname; if (!empty($bucketName)) { $pathname = '/' . $bucketName . $pathname; } $tmp = explode('?', $pathname); $canonicalizeResource .= rawurlencode($tmp[0]); $sortDict = $request->query; if (\count($tmp) > 1 && !empty($tmp[1])) { $sortDict[$tmp[1]] = ''; } ksort($sortDict); if (\count($sortDict) > 0 && false === strpos($canonicalizeResource, '?')) { $canonicalizeResource .= '?'; } $flag = '?' === $canonicalizeResource[\strlen($canonicalizeResource) - 1]; foreach ($sortDict as $k => $v) { if (!$flag) { $canonicalizeResource .= '&'; } else { $flag = false; } if (!empty($v)) { $canonicalizeResource .= rawurlencode($k) . '=' . rawurlencode($v); } else { $canonicalizeResource .= rawurlencode($k); } } $headers = []; $headerKeys = []; foreach ($request->headers as $k => $v) { $key = strtolower($k); if (0 === strpos($key, 'x-oss-')) { $headers[$key] = $v; } $headerKeys[$key] = $k; } foreach ($addtionalHeaders as $header) { $header = strtolower($header); if (isset($headerKeys[$header]) && !isset($headers[$header])) { $headers[$header] = $request->headers[$headerKeys[$header]]; } } $requestHeaders = new Dot($request->headers); $signString = implode("\n", [ strtoupper($request->method), $requestHeaders->get('content-md5', ''), $requestHeaders->get('content-type', ''), $requestHeaders->get('date', ''), implode("\n", self::getCanonicalizeHeaders($headers)), implode(';', $addtionalHeaders), $canonicalizeResource, ]); return base64_encode( hash_hmac( 'sha256', $signString, $accessKeySecret, true ) ); } /** * @param array $headers * * @return array */ private static function getCanonicalizeHeaders($headers) { $canonicalizeHeaders = []; foreach ($headers as $k => $v) { $headerName = strtolower($k); if (0 === strpos($headerName, 'x-oss-')) { array_push($canonicalizeHeaders, $headerName . ':' . $v); } } ksort($canonicalizeHeaders); return $canonicalizeHeaders; } }