accessKey = $accessKey; $this->secretKey = $secretKey; if (empty($endpoint)) { throw new Ks3ClientException("must set endpoint, please see http://ks3.ksyun.com/doc/api/index.html Region part"); } $this->endpoint = $endpoint; $this->signers = array(); $this->log = new Logger(); } /** * 方法列表:(具体使用请参考readme.md) * listBuckets,罗列bucket * deleteBucket,删除bucket * deleteBucketCORS,删除bucket跨域配置 * createBucket,新建bucket * setBucketAcl,设置bucket访问权限 * setBucketCORS,设置bucket跨域配置 * setBucketLogging,设置bucket日志配置 * listObjects,罗列object * getBucketAcl,获取bucket访问权限 * getBucketCORS,获取bucket跨域配置 * getBucketLocation,获取bucket地点配置 * getBucketLogging,获取bucket日志配置 * bucketExists,判断bucket是否存在 * listMutipartUploads,罗列当前bucket下尚未结束的分块上传 * putObjectByContent,上传文件 * putObjectByFile,上传文件 * setObjectAcl,设置object访问权限 * copyObject,复制object * getObjectMeta,获取object元数据 * objectExists,判断object是否存在 * deleteObject,删除object * deleteObjects,删除多个object * getObject,下载object * getObjectAcl,获取object访问权限 * initMultipartUpload,初始化分块上传 * uploadPart,上传块 * abortMultipartUpload,终止分块上传 * listParts,罗列已经上传的块 * completeMultipartUpload,完成分块上传 * generatePresignedUrl,生成文件外链 * putAdp,添加异步数据处理任务 * getAdp,查询异步数据处理任务 * @param $method * @param array $args * @return ResponseCore|string|string[]|null * @throws Exception */ public function __call($method, $args = array()) { $holder = new MessageHolder(); $holder->msg = "------------------Logging Start-------------------------\r\n"; $holder->msg .= "method->" . $method . " args->" . serialize($args) . "\r\n"; $ex = NULL; try { $result = $this->invoke($method, $args, $holder); } catch (Exception $e) { $holder->msg .= $e . "\r\n"; $ex = $e; } $holder->msg .= "------------------Logging End-------------------------\r\n"; $this->log->info($holder->msg); if ($ex != NULL) { throw $ex; } return $result; } private function invoke($method, $args = array(), $holder, $location = NULL) { $api = API::$API[$method]; if (!$api) { throw new Ks3ClientException($method . " Not Found API"); } if (count($args) !== 0) { if (count($args) > 1 || !is_array($args[0])) { throw new Ks3ClientException("this method only needs one array argument"); } $args = $args[0]; } if (isset($api["redirect"])) { $api = API::$API[$api["redirect"]]; } $request = new Ks3Request(); if (empty($args["Bucket"])) { if ($api["needBucket"]) { throw new Ks3ClientException($method . " this api need bucket"); } } else { $request->bucket = $args["Bucket"]; } $position = $api["objectPostion"] ?? "Key"; if (empty($args[$position])) { if ($api["needObject"]) { throw new Ks3ClientException($method . " this api need " . $position); } } else { $key = $args[$position]; $preEncoding = mb_detect_encoding($key, array("ASCII", "UTF-8", "GB2312", "GBK", "BIG5")); $holder->msg .= "key encoding " . $preEncoding . "\r\n"; if (strtolower($preEncoding) !== "utf-8") { $key = iconv($preEncoding, "UTF-8", $key); } $request->key = $key; } $method = $api["method"]; if ($method === "Method") { if (empty($args["Method"])) { $request->method = "GET"; } else { $request->method = $args["Method"]; } } else { $request->method = $api["method"]; } if (KS3_API_USE_HTTPS) { $request->scheme = "https://"; } else { $request->scheme = "http://"; } $request->endpoint = $this->endpoint; //add subresource if (!empty($api["subResource"])) { $request->subResource = $api["subResource"]; } //add query params if (isset($api["queryParams"])) { foreach ($api["queryParams"] as $key => $value) { $required = FALSE; if (strpos($value, "!") === 0) { $required = TRUE; $value = substr($value, 1); } $index = explode("->", $value); $curIndexArg = $args; $add = TRUE; $curkey = ""; foreach ($index as $key1 => $value1) { if (!isset($curIndexArg[$value1]) && $value1 !== "*") { $add = FALSE; } else { $curkey = $value1; //星号表示所有,按照暂时的业务,默认星号后面就没了 if ($curkey === "*") { foreach ($curIndexArg as $queryK => $queryV) { if (!is_array($queryV)) { $request->addQueryParams($queryK, $queryV); } } $add = FALSE; $required = FALSE; break; } $curIndexArg = $curIndexArg[$value1]; } } if (!empty($curIndexArg) && $add) { $request->addQueryParams($curkey, $curIndexArg); continue; } if ($required) { throw new Ks3ClientException($method . " param " . $value . " is required"); } } } if (isset($api["body"])) { if (isset($api["body"]["builder"])) { $builderName = $api["body"]["builder"]; $builder = new $builderName(); $request->body = $builder->build($args); } else if (isset($api["body"]["position"])) { $position = $api["body"]["position"]; $index = explode("->", $position); $curIndexArg = $args; $add = TRUE; $curkey = ""; foreach ($index as $key1 => $value1) { if (!isset($curIndexArg[$value1])) { $add = FALSE; } else { $curIndexArg = $curIndexArg[$value1]; $curkey = $value1; } } if (!empty($curIndexArg) && $add) { $request->body = $curIndexArg; } } } //add ext headers //TODO //sign request $signer = NULL; if (isset($api["signer"])) { $signers = explode("->", $api["signer"]); foreach ($signers as $key => $value) { $signer = new $value(); $log = $signer->sign($request, array("accessKey" => $this->accessKey, "secretKey" => $this->secretKey, "args" => $args)); if (!empty($log)) { $holder->msg .= $log . "\r\n"; } } } if ($signer === NULL || !($signer instanceof QueryAuthSigner)) { $url = $request->toUrl($this->endpoint); if ($location != NULL) { $url = $location; } $httpRequest = new RequestCore($url); if (KS3_API_DEBUG_MODE === TRUE) { $httpRequest->debug_mode = TRUE; } $httpRequest->set_method($request->method); foreach ($request->headers as $key => $value) { $httpRequest->add_header($key, $value); } $httpRequest->request_body = $request->body; if (isset($args["writeCallBack"])) { $httpRequest->register_streaming_write_callback($args["writeCallBack"]); } if (isset($args["readCallBack"])) { $httpRequest->register_streaming_read_callback($args["readCallBack"]); } $read_stream = $request->read_stream; $read_length = $request->getHeader(Headers::$ContentLength); $seek_position = $request->seek_position; if (isset($read_stream)) { $httpRequest->set_read_stream($read_stream, $read_length); $httpRequest->set_seek_position($seek_position); $httpRequest->remove_header(Headers::$ContentLength); } $write_stream = $request->write_stream; if (isset($write_stream)) { $httpRequest->set_write_stream($write_stream); } $holder->msg .= "request url->" . serialize($httpRequest->request_url) . "\r\n"; $holder->msg .= "request headers->" . serialize($httpRequest->request_headers) . "\r\n"; $holder->msg .= "request body->" . $httpRequest->request_body . "\r\n"; $holder->msg .= "request read stream length->" . $read_length . "\r\n"; $holder->msg .= "request read stream seek position->" . $seek_position . "\r\n"; $httpRequest->send_request(); //print_r($httpRequest); $body = $httpRequest->get_response_body(); $data = new ResponseCore ($httpRequest->get_response_header(), Utils::replaceNS2($body), $httpRequest->get_response_code()); if ($data->status == 307) { $respHeaders = $httpRequest->get_response_header(); $location = $respHeaders["location"]; if (strpos($location, "http") === 0) { $holder->msg .= "response code->" . $httpRequest->get_response_code() . "\r\n"; $holder->msg .= "response headers->" . serialize($httpRequest->get_response_header()) . "\r\n"; $holder->msg .= "response body->" . $body . "\r\n"; $holder->msg .= "retry request to " . $location . "\r\n"; //array($args)详见invoke开头 return $this->invoke($method, array($args), $holder, $location); } } $holder->msg .= "response code->" . $httpRequest->get_response_code() . "\r\n"; $holder->msg .= "response headers->" . serialize($httpRequest->get_response_header()) . "\r\n"; $holder->msg .= "response body->" . $body . "\r\n"; $handlers = explode("->", $api["handler"]); foreach ($handlers as $key => $value) { $handler = new $value(); $data = $handler->handle($data); } return $data; } $url = $request->toUrl($this->endpoint); $holder->msg .= $url . "\r\n"; return $url; } //用于生产表单上传时的签名信息 public function postObject($bucket, $postFormData = array(), $unknowValueFormFiled = array(), $filename = NULL, $expire = 18000): array { $policy = array(); $expireTime = Utils::iso8601(time() + $expire); $policy["expiration"] = $expireTime; $postFormData["bucket"] = $bucket; $conditions = array(); foreach ($postFormData as $key => $value) { $condition = array(); $condition[$key] = str_replace("\${filename}", $filename, $value); $conditions[] = $condition; } foreach ($unknowValueFormFiled as $key => $value) { $condition = array(); $condition[] = "starts-with"; $condition[] = "\$" . $value; $condition[] = ""; $conditions[] = $condition; } $policy["conditions"] = $conditions; $json = json_encode($policy); $signature = base64_encode(hash_hmac('sha1', base64_encode($json), $this->secretKey, true)); $result = array(); $result["Policy"] = base64_encode($json); $result["Signature"] = $signature; $result["KSSAccessKeyId"] = $this->accessKey; return $result; } }