ProxySelfCheck.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. const axios = require('axios')
  2. const config = require('../../config.json')
  3. const API = require('../../lib/API')
  4. const { BaseStdResponse } = require('../../BaseStdResponse')
  5. const QgProxyManager = require('../../lib/Lepao/QgProxyManager')
  6. const { buildAxiosOutboundConfig } = require('../../lib/Lepao/outboundAxiosConfig')
  7. function resolveSelfEchoUrl() {
  8. const base = String(config.url || '').trim()
  9. if (!base) return `http://127.0.0.1:${config.port}/Corn/ProxySelfIpEcho`
  10. return `${base.replace(/\/+$/, '')}/Corn/ProxySelfIpEcho`
  11. }
  12. class ProxySelfCheck extends API {
  13. constructor() {
  14. super()
  15. this.noEncrypt()
  16. this.setPath('/Corn/ProxySelfCheck')
  17. this.setMethod('GET')
  18. }
  19. async onRequest(req, res) {
  20. try {
  21. const qgOn = await QgProxyManager.isOutboundProxyEnabled()
  22. if (!qgOn) {
  23. await QgProxyManager.recordLog({
  24. event: 'proxy_self_check_skip',
  25. detail: { reason: 'proxy_disabled' }
  26. })
  27. return res.json({
  28. ...BaseStdResponse.OK,
  29. data: { skipped: true, reason: 'proxy_disabled' }
  30. })
  31. }
  32. const frag = await QgProxyManager.getOutboundAxiosFragment({ forceRefresh: false })
  33. if (frag.proxy === false) {
  34. await QgProxyManager.recordLog({
  35. event: 'proxy_self_check_skip',
  36. detail: { reason: 'no_proxy_available' }
  37. })
  38. return res.json({
  39. ...BaseStdResponse.OK,
  40. data: { skipped: true, reason: 'no_proxy_available' }
  41. })
  42. }
  43. const outbound = buildAxiosOutboundConfig(frag)
  44. const echoUrl = resolveSelfEchoUrl()
  45. const rsp = await axios.get(echoUrl, {
  46. timeout: 15000,
  47. validateStatus: () => true,
  48. ...outbound
  49. })
  50. const body = rsp.data || {}
  51. const now = Date.now()
  52. const cached = await QgProxyManager.getCachedParsed()
  53. const proxyIp = body?.data?.ip || null
  54. await QgProxyManager.recordLog({
  55. event: 'proxy_self_check',
  56. server: cached?.server || `${frag.proxy.host}:${frag.proxy.port}`,
  57. deadline: cached?.deadline || null,
  58. detail: {
  59. code: body?.code,
  60. http_status: rsp.status,
  61. target: echoUrl,
  62. proxy_ip: proxyIp,
  63. x_forwarded_for: body?.data?.x_forwarded_for || '',
  64. checked_at: now
  65. }
  66. })
  67. return res.json({
  68. ...BaseStdResponse.OK,
  69. data: {
  70. proxy_ip: proxyIp,
  71. http_status: rsp.status,
  72. target: echoUrl
  73. }
  74. })
  75. } catch (e) {
  76. const msg = e?.message || String(e)
  77. await QgProxyManager.recordLog({
  78. event: 'proxy_self_check_fail',
  79. detail: {
  80. message: msg,
  81. code: e?.code,
  82. status: e?.response?.status
  83. }
  84. })
  85. this.logger?.error?.(`[ProxySelfCheck] ${e?.stack || e}`)
  86. return res.json({
  87. ...BaseStdResponse.ERR,
  88. msg: `代理自检失败: ${msg}`
  89. })
  90. }
  91. }
  92. }
  93. module.exports.ProxySelfCheck = ProxySelfCheck