Status.js 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. const API = require('../../../../lib/API.js')
  2. const { BaseStdResponse } = require('../../../../BaseStdResponse.js')
  3. const AccessControl = require('../../../../lib/AccessControl.js')
  4. const QgProxyManager = require('../../../../lib/Lepao/QgProxyManager')
  5. const { lookupIpv4Region, extractIpFromServer } = require('../../../../lib/Lepao/ipRegionLookup')
  6. const { parseDetail } = require('../../../../lib/Lepao/lepaoProxyLogDisplay')
  7. class AdminLepaoProxyStatus extends API {
  8. constructor() {
  9. super()
  10. this.setPath('/Admin/Lepao/Proxy/Status')
  11. this.setMethod('GET')
  12. }
  13. async onRequest(req, res) {
  14. const { uuid, session } = req.query
  15. if ([uuid, session].some(v => v === '' || v == null))
  16. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  17. if (!await AccessControl.checkSession(uuid, session))
  18. return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
  19. const permission = await AccessControl.getPermission(uuid)
  20. if (!permission.includes('admin') && !permission.includes('service'))
  21. return res.json({ ...BaseStdResponse.PERMISSION_DENIED })
  22. try {
  23. const snap = await QgProxyManager.getStatusSnapshot()
  24. const redisEntry = snap.redis_current || null
  25. const valid = redisEntry ? QgProxyManager.cacheStillValid(redisEntry) : false
  26. let nodeRegion = null
  27. let egressRegion = null
  28. if (redisEntry?.server) {
  29. const nip = extractIpFromServer(redisEntry.server)
  30. nodeRegion = nip ? await lookupIpv4Region(nip) : null
  31. }
  32. if (redisEntry?.proxyIp) egressRegion = await lookupIpv4Region(redisEntry.proxyIp)
  33. let lastFetchEnriched = snap.last_fetch_log || null
  34. if (lastFetchEnriched?.detail) {
  35. const d = parseDetail(lastFetchEnriched.detail)
  36. const pip = d.proxy_ip
  37. lastFetchEnriched = {
  38. ...lastFetchEnriched,
  39. proxy_ip_region:
  40. pip && String(pip).match(/^(\d{1,3}\.){3}\d{1,3}$/) ? await lookupIpv4Region(pip) : null
  41. }
  42. }
  43. return res.json({
  44. ...BaseStdResponse.OK,
  45. data: {
  46. proxy_enabled: snap.proxy_enabled,
  47. area: snap.area,
  48. area_ex: snap.area_ex,
  49. isp: snap.isp,
  50. distinct_extract: snap.distinct_extract,
  51. updated_at: snap.updated_at,
  52. extract_key_configured: snap.extract_key_configured,
  53. proxy_auth_configured: snap.proxy_auth_configured,
  54. current_proxy: redisEntry
  55. ? {
  56. server: redisEntry.server,
  57. deadline: redisEntry.deadline,
  58. proxy_ip: redisEntry.proxyIp,
  59. request_id: redisEntry.requestId,
  60. fetched_at: redisEntry.fetchedAt,
  61. stale: !valid,
  62. node_region: nodeRegion || '未知',
  63. proxy_ip_region: egressRegion || '未知'
  64. }
  65. : null,
  66. last_fetch_log: lastFetchEnriched
  67. }
  68. })
  69. } catch (e) {
  70. this.logger?.error?.(`AdminLepaoProxyStatus: ${e.stack || e}`)
  71. return res.json({ ...BaseStdResponse.ERR, msg: '读取代理状态失败' })
  72. }
  73. }
  74. }
  75. module.exports.AdminLepaoProxyStatus = AdminLepaoProxyStatus