mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-06 13:14:11 +00:00
Merge pull request #1 from Kasp42/codex
Add support for additional subscription base URLs
This commit is contained in:
commit
e970e7e880
7 changed files with 67 additions and 2 deletions
|
|
@ -3,8 +3,10 @@ package sub
|
|||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
|
|
@ -88,6 +90,7 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, int64, xray.C
|
|||
}
|
||||
}
|
||||
}
|
||||
result = append(result, s.getAdditionalSubs(subId)...)
|
||||
|
||||
// Prepare statistics
|
||||
for index, clientTraffic := range clientTraffics {
|
||||
|
|
@ -114,6 +117,47 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, int64, xray.C
|
|||
return result, lastOnline, traffic, nil
|
||||
}
|
||||
|
||||
func (s *SubService) getAdditionalSubs(subID string) []string {
|
||||
additionalURIs, err := s.settingService.GetSubAdditionalURIs()
|
||||
if err != nil || strings.TrimSpace(additionalURIs) == "" {
|
||||
return nil
|
||||
}
|
||||
client := &http.Client{Timeout: 8 * time.Second}
|
||||
var result []string
|
||||
for _, baseURI := range strings.Split(additionalURIs, ",") {
|
||||
baseURI = strings.TrimSpace(baseURI)
|
||||
if baseURI == "" {
|
||||
continue
|
||||
}
|
||||
if !strings.HasSuffix(baseURI, "/") {
|
||||
baseURI += "/"
|
||||
}
|
||||
remoteSubURL := baseURI + subID
|
||||
resp, reqErr := client.Get(remoteSubURL)
|
||||
if reqErr != nil {
|
||||
logger.Warningf("SubService - additional sub request failed for %s: %v", remoteSubURL, reqErr)
|
||||
continue
|
||||
}
|
||||
body, readErr := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if readErr != nil || resp.StatusCode != http.StatusOK {
|
||||
continue
|
||||
}
|
||||
rawBody := strings.TrimSpace(string(body))
|
||||
decoded, decodeErr := base64.StdEncoding.DecodeString(rawBody)
|
||||
if decodeErr == nil {
|
||||
rawBody = string(decoded)
|
||||
}
|
||||
for _, line := range strings.Split(rawBody, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" {
|
||||
result = append(result, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *SubService) getInboundsBySubId(subId string) ([]*model.Inbound, error) {
|
||||
db := database.GetDB()
|
||||
var inbounds []*model.Inbound
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ class AllSetting {
|
|||
this.subEncrypt = true;
|
||||
this.subShowInfo = true;
|
||||
this.subURI = "";
|
||||
this.subAdditionalURIs = "";
|
||||
this.subJsonURI = "";
|
||||
this.subClashURI = "";
|
||||
this.subJsonFragment = "";
|
||||
|
|
@ -89,4 +90,4 @@ class AllSetting {
|
|||
equals(other) {
|
||||
return ObjectUtil.equals(this, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ type AllSetting struct {
|
|||
SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"` // Encrypt subscription responses
|
||||
SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"` // Show client information in subscriptions
|
||||
SubURI string `json:"subURI" form:"subURI"` // Subscription server URI
|
||||
SubAdditionalURIs string `json:"subAdditionalURIs" form:"subAdditionalURIs"` // Comma-separated list of additional subscription base URLs
|
||||
SubJsonPath string `json:"subJsonPath" form:"subJsonPath"` // Path for JSON subscription endpoint
|
||||
SubJsonURI string `json:"subJsonURI" form:"subJsonURI"` // JSON subscription server URI
|
||||
SubClashEnable bool `json:"subClashEnable" form:"subClashEnable"` // Enable Clash/Mihomo subscription endpoint
|
||||
|
|
|
|||
|
|
@ -72,6 +72,16 @@
|
|||
v-model="allSetting.subURI"></a-input>
|
||||
</template>
|
||||
</a-setting-list-item>
|
||||
<a-setting-list-item paddings="small">
|
||||
<template #title>{{ i18n "pages.settings.subAdditionalURIs"}}</template>
|
||||
<template #description>{{ i18n
|
||||
"pages.settings.subAdditionalURIsDesc"}}</template>
|
||||
<template #control>
|
||||
<a-input type="text"
|
||||
placeholder="https://x2.example.com:2096/sbp/, https://x3.example.com/sub/"
|
||||
v-model="allSetting.subAdditionalURIs"></a-input>
|
||||
</template>
|
||||
</a-setting-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel key="2" header='{{ i18n "pages.settings.information" }}'>
|
||||
<a-setting-list-item paddings="small">
|
||||
|
|
@ -176,4 +186,4 @@
|
|||
</a-setting-list-item>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ var defaultValueMap = map[string]string{
|
|||
"subEncrypt": "true",
|
||||
"subShowInfo": "true",
|
||||
"subURI": "",
|
||||
"subAdditionalURIs": "",
|
||||
"subJsonPath": "/json/",
|
||||
"subJsonURI": "",
|
||||
"subClashEnable": "true",
|
||||
|
|
@ -564,6 +565,10 @@ func (s *SettingService) GetSubJsonURI() (string, error) {
|
|||
return s.getString("subJsonURI")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetSubAdditionalURIs() (string, error) {
|
||||
return s.getString("subAdditionalURIs")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetSubClashEnable() (bool, error) {
|
||||
return s.getBool("subClashEnable")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -473,6 +473,8 @@
|
|||
"subShowInfoDesc" = "The remaining traffic and date will be displayed in the client apps."
|
||||
"subURI" = "Reverse Proxy URI"
|
||||
"subURIDesc" = "The URI path of the subscription URL for use behind proxies."
|
||||
"subAdditionalURIs" = "Extra Subscription Base URLs"
|
||||
"subAdditionalURIsDesc" = "Comma-separated base URLs (e.g. https://x2.example.com:2096/sbp/). They work only when the same subscription ID exists on that server."
|
||||
"externalTrafficInformEnable" = "External Traffic Inform"
|
||||
"externalTrafficInformEnableDesc" = "Inform external API on every traffic update."
|
||||
"externalTrafficInformURI" = "External Traffic Inform URI"
|
||||
|
|
|
|||
|
|
@ -473,6 +473,8 @@
|
|||
"subShowInfoDesc" = "Отображать остаток трафика и дату окончания после имени конфигурации"
|
||||
"subURI" = "URI обратного прокси"
|
||||
"subURIDesc" = "Изменить базовый URI URL-адреса подписки для использования за прокси-серверами"
|
||||
"subAdditionalURIs" = "Дополнительные базовые URL подписки"
|
||||
"subAdditionalURIsDesc" = "Базовые URL через запятую (например, https://x2.example.com:2096/sbp/). Работает только если на удалённом сервере существует подписка с тем же SubID."
|
||||
"externalTrafficInformEnable" = "Информация о внешнем трафике"
|
||||
"externalTrafficInformEnableDesc" = "Информировать внешний API о каждом обновлении трафика"
|
||||
"externalTrafficInformURI" = "URI информации о внешнем трафике"
|
||||
|
|
|
|||
Loading…
Reference in a new issue