仰望星辰工作室

better-staridc-MNBT

better-staridc-MNBT/ MPHX/bt_proxy.php 4.3 KB · 136 行 原始文件
Z zfhsh first commit 1 天前
1<?php
2if (!defined('IN_CRONLITE')) exit();
3
4/**
5 * 宝塔面板反向代理 API 封装类
6 *
7 * 独立类,专用于宝塔反向代理模块(/mod/proxy/com/)。
8 * 签名算法与 bt_docker/bt_api 一致,transport 自持。
9 *
10 * 参考文档:https://docs.bt.cn/category/proxy-%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86
11 */
12
13class bt_proxy
14{
15 /** @var string 宝塔面板地址(含协议+端口,无尾斜杠) */
16 public $BT_PANEL;
17 /** @var string 宝塔接口密钥 */
18 public $BT_KEY;
19
20 public function __construct($bt_panel = null, $bt_key = null)
21 {
22 $this->BT_PANEL = rtrim((string)$bt_panel, '/');
23 $this->BT_KEY = (string)$bt_key;
24 }
25
26 // ========================================================================
27 // 反向代理站点管理
28 // ========================================================================
29
30 /**
31 * 获取反向代理站点列表
32 * @param int $p 页码,默认 1
33 * @param int $limit 每页数量,默认 100
34 * @param string $search 搜索关键词
35 * @return array
36 */
37 public function proxy_list($p = 1, $limit = 100, $search = '')
38 {
39 $params = ['p' => $p, 'limit' => $limit];
40 if ($search !== '') $params['search'] = $search;
41 return $this->HttpPost('get_list', $params);
42 }
43
44 /**
45 * 创建反向代理站点
46 * @param array $params domains(换行分隔), proxy_pass, proxy_path(默认/), remark(可选)
47 * @return array
48 */
49 public function proxy_create($params)
50 {
51 return $this->HttpPost('create', $params);
52 }
53
54 /**
55 * 删除反向代理站点
56 * @param int $id 站点 ID
57 * @param string $site_name 站点名称
58 * @return array
59 */
60 public function proxy_delete($id, $site_name)
61 {
62 return $this->HttpPost('delete', [
63 'id' => $id,
64 'site_name' => $site_name,
65 'remove_path' => 0,
66 ]);
67 }
68
69 // ========================================================================
70 // 内部工具(签名与请求 transport,自持)
71 // ========================================================================
72
73 private function GetKeyData()
74 {
75 $now_time = time();
76 return [
77 'request_token' => md5($now_time . '' . md5($this->BT_KEY)),
78 'request_time' => $now_time,
79 ];
80 }
81
82 /**
83 * POST 请求 /mod/proxy/com/<method>/stype
84 */
85 private function HttpPost($method, $params = [], $timeout = 60)
86 {
87 $url = $this->BT_PANEL . '/mod/proxy/com/' . $method . '/stype';
88 $data = array_merge($this->GetKeyData(), $params);
89 $r = $this->request($url, $data, $timeout);
90 if (is_array($r) && isset($r['data']) && is_array($r['data'])) {
91 return $r['data'];
92 }
93 return $r;
94 }
95
96 /**
97 * 统一 cURL 请求(带 cookie jar)
98 */
99 private function request($url, $postData, $timeout)
100 {
101 $cookie_file = ROOT . 'api/cookie/' . md5($this->BT_PANEL) . '.cookie';
102 if (!is_dir(dirname($cookie_file))) {
103 @mkdir(dirname($cookie_file), 0755, true);
104 }
105 if (!file_exists($cookie_file)) {
106 $fp = fopen($cookie_file, 'w+');
107 if (is_resource($fp)) {
108 fclose($fp);
109 }
110 }
111
112 $ch = curl_init();
113 curl_setopt($ch, CURLOPT_URL, $url);
114 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
115 curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
116 curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
117 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
118 curl_setopt($ch, CURLOPT_HEADER, 0);
119 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
120 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
121 if ($postData !== null) {
122 curl_setopt($ch, CURLOPT_POST, 1);
123 curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
124 }
125 $output = curl_exec($ch);
126 $errno = curl_errno($ch);
127 $error = curl_error($ch);
128 curl_close($ch);
129
130 if ($errno) {
131 return ['status' => false, 'msg' => 'cURL 错误(' . $errno . '):' . $error];
132 }
133 $decoded = json_decode($output, true);
134 return $decoded !== null ? $decoded : ['status' => false, 'msg' => '响应解析失败', 'raw' => $output];
135 }
136}