accessKeyId = $config['key']; $this->accessKeySecret = $config['secret']; $this->bucket = $config['bucket']; $this->host = $config['bucket'] . '.' . $config['endpoint']; $this->api = 'http://' . $this->host . '/'; $this->preUrl = $config['url']; $this->path = '/' . ltrim($config['path'], '/'); } public function getPath($object) { return $object; } public function exist($object) { $data = $this->getObjectMeta($object); return !empty($data['last-modified']); } public function mtime($object) { $data = $this->getObjectMeta($object); return $data['x-oss-meta-mtime'] ?? (isset($data['last-modified']) ? strtotime($data['last-modified']) : 0); } public function read($object) { $path = $this->path . '/' . $object; $method = 'GET'; $options[CURLOPT_HEADER] = 1; $headers = $this->genHeaders($object); $sign = $this->sign($method, $headers, '/' . $this->bucket . $path); $headers['Authorization'] = "OSS {$this->accessKeyId}:{$sign}"; $url = $this->api . $path; $res = Http::curl($url, [], $method, $headers, $options); if (strpos($res, 'Content-MD5')) { return Http::parse_content($res); } else { return false; } } public function write($object, $content) { $path = $this->path . '/' . $object; $method = 'PUT'; $options[CURLOPT_HEADER] = 1; $headers = $this->genHeaders($object); $headers['Content-MD5'] = base64_encode(md5($content, true)); $sign = $this->sign($method, $headers, '/' . $this->bucket . $path); $headers['Authorization'] = "OSS {$this->accessKeyId}:{$sign}"; $url = $this->api . $path; $res = Http::curl($url, $content, $method, $headers, $options); return strpos($res, '200 OK'); } public function append($object, $content) { $data = $this->getObjectMeta($object); $path = $this->path . '/' . $object . '?append&position=0' . $data['content-length']; $method = 'POST'; $options[CURLOPT_HEADER] = 1; $headers = $this->genHeaders($object); $headers['Content-MD5'] = base64_encode(md5($content, true)); $headers['Accept-Encoding'] = ''; $sign = $this->sign($method, $headers, '/' . $this->bucket . $path); $headers['Authorization'] = "OSS {$this->accessKeyId}:{$sign}"; $url = $this->api . $path; $res = Http::curl($url, $content, $method, $headers, $options); return strpos($res, '200 OK'); } public function remove($object) { $path = $this->path . '/' . $object; $method = 'DELETE'; $options[CURLOPT_HEADER] = 1; $headers = $this->genHeaders($object); $sign = $this->sign($method, $headers, '/' . $this->bucket . $path); $headers['Authorization'] = "OSS {$this->accessKeyId}:{$sign}"; $url = $this->api . $path; $res = Http::curl($url, [], $method, $headers, $options); $headers = Http::parse_headers($res); if ($headers['x-oss-meta-mtime']) { return Http::parse_content($res); } else { return false; } } public function getUrl($object) { return $this->preUrl . $this->path . '/' . $object; } public function error() { return ''; } private function getObjectMeta($object) { $path = $this->path . '/' . $object . '?objectMeta'; $method = 'HEAD'; $options[CURLOPT_HEADER] = 1; $headers = $this->genHeaders($object); $sign = $this->sign($method, $headers, '/' . $this->bucket . $path); $headers['Authorization'] = "OSS {$this->accessKeyId}:{$sign}"; $url = $this->api . $path; $res = Http::curl($url, [], $method, $headers, $options); return Http::parse_headers($res); } private function sign($method, $headers, $object) { $param = []; $param[] = $method; $param[] = $headers['Content-MD5'] ?? ""; $param[] = $headers['Content-Type'] ?? ""; $param[] = $headers['Date']; //$param[] = $headers['Host']; $param[] = $object; return base64_encode(hash_hmac('sha1', join("\n", $param), $this->accessKeySecret, true)); } private function genHeaders($object) { return [ 'Date' => gmdate('D, d M Y H:i:s \G\M\T'), 'Host' => $this->host, 'Content-Type' => File::getMimeByName($object), ]; } }