diff options
| author | surbiks <43953720+surbiks@users.noreply.github.com> | 2026-02-09 23:43:17 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-09 23:43:17 +0300 |
| commit | 4779939424eb047d30161631fd89a9876104084c (patch) | |
| tree | 89e2682aa528281879b3afb535f2b34124a17335 /web/controller/xray_setting.go | |
| parent | 4a455aa5322e0803005da2d5d65b85a19dfc42e5 (diff) | |
Add url speed test for outbound (#3767)
* add outbound testing functionality with configurable test URL
* use no kernel tun for conflict errors
Diffstat (limited to 'web/controller/xray_setting.go')
| -rw-r--r-- | web/controller/xray_setting.go | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/web/controller/xray_setting.go b/web/controller/xray_setting.go index b78925f0..a48726de 100644 --- a/web/controller/xray_setting.go +++ b/web/controller/xray_setting.go @@ -1,6 +1,9 @@ package controller import ( + "encoding/json" + + "github.com/mhsanaei/3x-ui/v2/util/common" "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/gin-gonic/gin" @@ -34,9 +37,10 @@ func (a *XraySettingController) initRouter(g *gin.RouterGroup) { g.POST("/warp/:action", a.warp) g.POST("/update", a.updateSetting) g.POST("/resetOutboundsTraffic", a.resetOutboundsTraffic) + g.POST("/testOutbound", a.testOutbound) } -// getXraySetting retrieves the Xray configuration template and inbound tags. +// getXraySetting retrieves the Xray configuration template, inbound tags, and outbound test URL. func (a *XraySettingController) getXraySetting(c *gin.Context) { xraySetting, err := a.SettingService.GetXrayConfigTemplate() if err != nil { @@ -48,15 +52,28 @@ func (a *XraySettingController) getXraySetting(c *gin.Context) { jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } - xrayResponse := "{ \"xraySetting\": " + xraySetting + ", \"inboundTags\": " + inboundTags + " }" + outboundTestUrl, _ := a.SettingService.GetXrayOutboundTestUrl() + if outboundTestUrl == "" { + outboundTestUrl = "https://www.google.com/generate_204" + } + urlJSON, _ := json.Marshal(outboundTestUrl) + xrayResponse := "{ \"xraySetting\": " + xraySetting + ", \"inboundTags\": " + inboundTags + ", \"outboundTestUrl\": " + string(urlJSON) + " }" jsonObj(c, xrayResponse, nil) } // updateSetting updates the Xray configuration settings. func (a *XraySettingController) updateSetting(c *gin.Context) { xraySetting := c.PostForm("xraySetting") - err := a.XraySettingService.SaveXraySetting(xraySetting) - jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err) + if err := a.XraySettingService.SaveXraySetting(xraySetting); err != nil { + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err) + return + } + outboundTestUrl := c.PostForm("outboundTestUrl") + if outboundTestUrl == "" { + outboundTestUrl = "https://www.google.com/generate_204" + } + _ = a.SettingService.SetXrayOutboundTestUrl(outboundTestUrl) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), nil) } // getDefaultXrayConfig retrieves the default Xray configuration. @@ -118,3 +135,24 @@ func (a *XraySettingController) resetOutboundsTraffic(c *gin.Context) { } jsonObj(c, "", nil) } + +// testOutbound tests an outbound configuration and returns the delay/response time. +// Optional form "allOutbounds": JSON array of all outbounds; used to resolve sockopt.dialerProxy dependencies. +func (a *XraySettingController) testOutbound(c *gin.Context) { + outboundJSON := c.PostForm("outbound") + testURL := c.PostForm("testURL") + allOutboundsJSON := c.PostForm("allOutbounds") + + if outboundJSON == "" { + jsonMsg(c, I18nWeb(c, "somethingWentWrong"), common.NewError("outbound parameter is required")) + return + } + + result, err := a.OutboundService.TestOutbound(outboundJSON, testURL, allOutboundsJSON) + if err != nil { + jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) + return + } + + jsonObj(c, result, nil) +} |
