fix(publish-gitea): urllib 连接失败时 curl -k 兜底并携带请求体

This commit is contained in:
2026-09-14 18:58:51 +08:00
parent 4c6cdc3bf8
commit dccc7198f4
+33 -1
View File
@@ -58,11 +58,13 @@ def git_remote_info():
class Api:
def __init__(self, base, owner, repo, token, insecure):
self.api = f'{base}/api/v1/repos/{owner}/{repo}'
self.token = token
self.headers = {'Authorization': f'token {token}'}
self.ctx = ssl._create_unverified_context() if insecure else None
def request(self, method, path, data=None, headers=None, retries=4):
"""发请求; 实例 TLS 间歇性抽风(SSL UNEXPECTED_EOF), 连接级错误自动重试"""
"""发请求; 实例 TLS 间歇性抽风(SSL UNEXPECTED_EOF), 连接级错误自动重试,
并改用 curl -k 兜底(urllib 的握手在该实例上可能持续失败)"""
last = None
for attempt in range(retries):
req = urllib.request.Request(self.api + path, data=data, method=method,
@@ -75,9 +77,39 @@ class Api:
return e.code, json.loads(e.read() or b'{}')
except (urllib.error.URLError, ssl.SSLError, OSError) as e:
last = e
try:
status, body = self._curl(method, path, data, headers)
if status > 0:
return status, body
except Exception as ce:
last = ce
time.sleep(1.0 + attempt)
raise RuntimeError(f'Gitea 请求连续 {retries} 次失败: {last}')
def _curl(self, method, path, data=None, headers=None):
"""curl 兜底: 返回 (status, json/None); 解析失败返回 (0, None) 交回上层重试"""
cmd = ['curl', '-k', '-s', '-X', method, '-w', '\n%{http_code}']
if data is not None:
cmd += ['--data-binary', '@-']
for key, value in self.headers.items():
cmd += ['-H', f'{key}: {value}']
for key, value in (headers or {}).items():
cmd += ['-H', f'{key}: {value}']
cmd.append(self.api + path)
proc = subprocess.run(cmd, input=data, capture_output=True, timeout=600)
out = proc.stdout.decode('utf-8', 'replace')
body, _, code = out.rpartition('\n')
try:
status = int(code.strip())
except ValueError:
return 0, None
if not body.strip():
return status, None
try:
return status, json.loads(body)
except ValueError:
return status, {'raw': body}
def get_json(self, path):
status, data = self.request('GET', path)
return data if status == 200 else None