bool,'status'=>int,'headers'=>array,'body'=>string,'error'=>string] */ function storageHttp($method, $url, array $headers = [], $body = null, $timeout = 30, $insecure = false, $connectTimeout = null) { $respHeaders = []; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => strtoupper($method), CURLOPT_HTTPHEADER => $headers, CURLOPT_CONNECTTIMEOUT => $connectTimeout === null ? min(10, max(3, $timeout)) : max(1, (int)$connectTimeout), CURLOPT_TIMEOUT => $timeout, CURLOPT_FOLLOWLOCATION => false, CURLOPT_SSL_VERIFYPEER => !$insecure, CURLOPT_SSL_VERIFYHOST => $insecure ? 0 : 2, CURLOPT_HEADERFUNCTION => function ($ch, $line) use (&$respHeaders) { $pos = strpos($line, ':'); if ($pos !== false) { $name = strtolower(trim(substr($line, 0, $pos))); $respHeaders[$name] = trim(substr($line, $pos + 1)); } return strlen($line); }, ]); $ca = storageCaBundle(); if ($ca && !$insecure) { curl_setopt($ch, CURLOPT_CAINFO, $ca); } if ($body !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, $body); } $out = curl_exec($ch); $err = curl_error($ch); $errno = curl_errno($ch); $status = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE); curl_close($ch); if ($out === false) { return [ 'ok' => false, 'status' => 0, 'headers' => [], 'body' => '', 'error' => $errno === CURLE_OPERATION_TIMEDOUT ? "请求超时({$timeout}s)" : "网络错误({$errno}): {$err}", ]; } return [ 'ok' => $status >= 200 && $status < 300, 'status' => $status, 'headers' => $respHeaders, 'body' => $out, 'error' => $status >= 200 && $status < 300 ? '' : "HTTP {$status}", ]; } // 生成对象的访问 URL(路径部分逐段编码,保留斜杠) function storageEncodeKey($key) { $key = ltrim((string)$key, '/'); $segments = explode('/', $key); return implode('/', array_map('rawurlencode', $segments)); } // 解析 host 形式:bucket.endpoint 或自定义域名 function storageHostOf($domain, $useHttps = true) { $domain = preg_replace('#^https?://#i', '', trim((string)$domain)); return ($useHttps ? 'https://' : 'http://') . rtrim($domain, '/'); } // 统一把失败信息压缩成一行,便于写入设置页展示 function storageShortError($text, $max = 200) { $text = preg_replace('/\s+/', ' ', trim((string)$text)); return mb_strlen($text, 'UTF-8') > $max ? mb_substr($text, 0, $max, 'UTF-8') . '…' : $text; }