httpProxyManager.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /**
  2. * HTTP代理管理模块
  3. */
  4. const httpProxyManager = {
  5. currentConfig: {},
  6. // 初始化代理管理
  7. init: async function() {
  8. try {
  9. console.log('初始化HTTP代理管理...');
  10. await this.loadProxyStatus();
  11. this.bindEvents();
  12. return Promise.resolve();
  13. } catch (error) {
  14. console.error('初始化HTTP代理管理失败:', error);
  15. }
  16. },
  17. // 加载代理状态
  18. loadProxyStatus: async function() {
  19. try {
  20. const response = await fetch('/api/httpProxy/proxy/status');
  21. if (!response.ok) {
  22. throw new Error('获取代理状态失败');
  23. }
  24. const status = await response.json();
  25. this.updateStatusDisplay(status);
  26. // 加载配置
  27. const configResponse = await fetch('/api/httpProxy/proxy/config');
  28. if (configResponse.ok) {
  29. const configData = await configResponse.json();
  30. this.currentConfig = configData.config || {};
  31. this.updateConfigForm();
  32. }
  33. } catch (error) {
  34. console.error('加载代理状态失败:', error);
  35. this.updateStatusDisplay({
  36. isRunning: false,
  37. error: error.message
  38. });
  39. }
  40. },
  41. // 更新状态显示
  42. updateStatusDisplay: function(status) {
  43. const statusElement = document.getElementById('proxyStatus');
  44. const statusBadge = document.getElementById('proxyStatusBadge');
  45. const portInfo = document.getElementById('proxyPortInfo');
  46. if (statusElement) {
  47. if (status.isRunning) {
  48. statusElement.textContent = '运行中';
  49. statusElement.className = 'status-running';
  50. if (statusBadge) {
  51. statusBadge.textContent = '运行中';
  52. statusBadge.className = 'badge badge-success';
  53. }
  54. } else {
  55. statusElement.textContent = '已停止';
  56. statusElement.className = 'status-stopped';
  57. if (statusBadge) {
  58. statusBadge.textContent = '已停止';
  59. statusBadge.className = 'badge badge-secondary';
  60. }
  61. }
  62. }
  63. if (portInfo && status.config) {
  64. portInfo.textContent = `${status.config.host}:${status.config.port}`;
  65. }
  66. },
  67. // 更新配置表单
  68. updateConfigForm: function() {
  69. if (!this.currentConfig) return;
  70. const elements = {
  71. 'proxy-port': this.currentConfig.port || 8080,
  72. 'proxy-host': this.currentConfig.host || '0.0.0.0',
  73. 'proxy-enable-https': this.currentConfig.enableHttps || false,
  74. 'proxy-enable-auth': this.currentConfig.enableAuth || false,
  75. 'proxy-username': this.currentConfig.username || '',
  76. 'proxy-password': this.currentConfig.password || '',
  77. 'proxy-log-requests': this.currentConfig.logRequests !== false
  78. };
  79. for (const [id, value] of Object.entries(elements)) {
  80. const element = document.getElementById(id);
  81. if (element) {
  82. if (element.type === 'checkbox') {
  83. element.checked = Boolean(value);
  84. } else {
  85. element.value = value;
  86. }
  87. }
  88. }
  89. // 更新允许和阻止的主机列表
  90. this.updateHostLists();
  91. },
  92. // 更新主机列表显示
  93. updateHostLists: function() {
  94. const allowedList = document.getElementById('allowedHostsList');
  95. const blockedList = document.getElementById('blockedHostsList');
  96. if (allowedList && this.currentConfig.allowedHosts) {
  97. allowedList.innerHTML = this.currentConfig.allowedHosts
  98. .map(host => `<span class="host-tag">${host} <button onclick="httpProxyManager.removeAllowedHost('${host}')">&times;</button></span>`)
  99. .join('');
  100. }
  101. if (blockedList && this.currentConfig.blockedHosts) {
  102. blockedList.innerHTML = this.currentConfig.blockedHosts
  103. .map(host => `<span class="host-tag blocked">${host} <button onclick="httpProxyManager.removeBlockedHost('${host}')">&times;</button></span>`)
  104. .join('');
  105. }
  106. },
  107. // 绑定事件
  108. bindEvents: function() {
  109. // 启动代理按钮
  110. const startBtn = document.getElementById('startProxyBtn');
  111. if (startBtn) {
  112. startBtn.addEventListener('click', () => this.startProxy());
  113. }
  114. // 停止代理按钮
  115. const stopBtn = document.getElementById('stopProxyBtn');
  116. if (stopBtn) {
  117. stopBtn.addEventListener('click', () => this.stopProxy());
  118. }
  119. // 保存配置按钮
  120. const saveBtn = document.getElementById('saveProxyConfigBtn');
  121. if (saveBtn) {
  122. saveBtn.addEventListener('click', () => this.saveConfig());
  123. }
  124. // 测试代理按钮
  125. const testBtn = document.getElementById('testProxyBtn');
  126. if (testBtn) {
  127. testBtn.addEventListener('click', () => this.testProxy());
  128. }
  129. // 添加允许主机
  130. const addAllowedBtn = document.getElementById('addAllowedHostBtn');
  131. if (addAllowedBtn) {
  132. addAllowedBtn.addEventListener('click', () => this.addAllowedHost());
  133. }
  134. // 添加阻止主机
  135. const addBlockedBtn = document.getElementById('addBlockedHostBtn');
  136. if (addBlockedBtn) {
  137. addBlockedBtn.addEventListener('click', () => this.addBlockedHost());
  138. }
  139. },
  140. // 启动代理
  141. startProxy: async function() {
  142. try {
  143. const config = this.getConfigFromForm();
  144. const response = await fetch('/api/httpProxy/proxy/start', {
  145. method: 'POST',
  146. headers: { 'Content-Type': 'application/json' },
  147. body: JSON.stringify(config)
  148. });
  149. if (!response.ok) {
  150. const error = await response.json();
  151. throw new Error(error.error || '启动失败');
  152. }
  153. const result = await response.json();
  154. core.showAlert('代理服务启动成功', 'success');
  155. this.updateStatusDisplay(result.status);
  156. } catch (error) {
  157. console.error('启动代理失败:', error);
  158. core.showAlert('启动代理失败: ' + error.message, 'error');
  159. }
  160. },
  161. // 停止代理
  162. stopProxy: async function() {
  163. try {
  164. const response = await fetch('/api/httpProxy/proxy/stop', {
  165. method: 'POST'
  166. });
  167. if (!response.ok) {
  168. const error = await response.json();
  169. throw new Error(error.error || '停止失败');
  170. }
  171. const result = await response.json();
  172. core.showAlert('代理服务已停止', 'success');
  173. this.updateStatusDisplay(result.status);
  174. } catch (error) {
  175. console.error('停止代理失败:', error);
  176. core.showAlert('停止代理失败: ' + error.message, 'error');
  177. }
  178. },
  179. // 保存配置
  180. saveConfig: async function() {
  181. try {
  182. const config = this.getConfigFromForm();
  183. const response = await fetch('/api/httpProxy/proxy/config', {
  184. method: 'PUT',
  185. headers: { 'Content-Type': 'application/json' },
  186. body: JSON.stringify(config)
  187. });
  188. if (!response.ok) {
  189. const error = await response.json();
  190. throw new Error(error.error || '保存配置失败');
  191. }
  192. const result = await response.json();
  193. this.currentConfig = config;
  194. core.showAlert('代理配置已保存', 'success');
  195. this.updateStatusDisplay(result.status);
  196. } catch (error) {
  197. console.error('保存配置失败:', error);
  198. core.showAlert('保存配置失败: ' + error.message, 'error');
  199. }
  200. },
  201. // 测试代理
  202. testProxy: async function() {
  203. try {
  204. const testUrl = document.getElementById('proxyTestUrl')?.value || 'http://httpbin.org/ip';
  205. const response = await fetch('/api/httpProxy/proxy/test', {
  206. method: 'POST',
  207. headers: { 'Content-Type': 'application/json' },
  208. body: JSON.stringify({ testUrl })
  209. });
  210. if (!response.ok) {
  211. const error = await response.json();
  212. throw new Error(error.error || '测试失败');
  213. }
  214. const result = await response.json();
  215. core.showAlert(`代理测试成功 (${result.responseTime})`, 'success');
  216. } catch (error) {
  217. console.error('代理测试失败:', error);
  218. core.showAlert('代理测试失败: ' + error.message, 'error');
  219. }
  220. },
  221. // 从表单获取配置
  222. getConfigFromForm: function() {
  223. return {
  224. port: parseInt(document.getElementById('proxy-port')?.value) || 8080,
  225. host: document.getElementById('proxy-host')?.value || '0.0.0.0',
  226. enableHttps: document.getElementById('proxy-enable-https')?.checked || false,
  227. enableAuth: document.getElementById('proxy-enable-auth')?.checked || false,
  228. username: document.getElementById('proxy-username')?.value || '',
  229. password: document.getElementById('proxy-password')?.value || '',
  230. logRequests: document.getElementById('proxy-log-requests')?.checked !== false,
  231. allowedHosts: this.currentConfig.allowedHosts || [],
  232. blockedHosts: this.currentConfig.blockedHosts || []
  233. };
  234. },
  235. // 添加允许的主机
  236. addAllowedHost: function() {
  237. const input = document.getElementById('newAllowedHost');
  238. const host = input?.value?.trim();
  239. if (host && !this.currentConfig.allowedHosts?.includes(host)) {
  240. if (!this.currentConfig.allowedHosts) {
  241. this.currentConfig.allowedHosts = [];
  242. }
  243. this.currentConfig.allowedHosts.push(host);
  244. this.updateHostLists();
  245. input.value = '';
  246. }
  247. },
  248. // 移除允许的主机
  249. removeAllowedHost: function(host) {
  250. if (this.currentConfig.allowedHosts) {
  251. this.currentConfig.allowedHosts = this.currentConfig.allowedHosts.filter(h => h !== host);
  252. this.updateHostLists();
  253. }
  254. },
  255. // 添加阻止的主机
  256. addBlockedHost: function() {
  257. const input = document.getElementById('newBlockedHost');
  258. const host = input?.value?.trim();
  259. if (host && !this.currentConfig.blockedHosts?.includes(host)) {
  260. if (!this.currentConfig.blockedHosts) {
  261. this.currentConfig.blockedHosts = [];
  262. }
  263. this.currentConfig.blockedHosts.push(host);
  264. this.updateHostLists();
  265. input.value = '';
  266. }
  267. },
  268. // 移除阻止的主机
  269. removeBlockedHost: function(host) {
  270. if (this.currentConfig.blockedHosts) {
  271. this.currentConfig.blockedHosts = this.currentConfig.blockedHosts.filter(h => h !== host);
  272. this.updateHostLists();
  273. }
  274. }
  275. };
  276. // 全局公开模块
  277. window.httpProxyManager = httpProxyManager;