101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package sub
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"s-ui/logger"
|
|
"s-ui/util"
|
|
"strings"
|
|
)
|
|
|
|
type Link struct {
|
|
Type string `json:"type"`
|
|
Remark string `json:"remark"`
|
|
Uri string `json:"uri"`
|
|
}
|
|
|
|
type LinkService struct {
|
|
}
|
|
|
|
func (s *LinkService) GetLinks(linkJson *json.RawMessage, types string, clientInfo string) []string {
|
|
links := []Link{}
|
|
var result []string
|
|
err := json.Unmarshal(*linkJson, &links)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
for _, link := range links {
|
|
switch link.Type {
|
|
case "external":
|
|
result = append(result, link.Uri)
|
|
case "sub":
|
|
result = append(result, s.getExternalSub(link.Uri)...)
|
|
case "local":
|
|
if types == "all" {
|
|
result = append(result, s.addClientInfo(link.Uri, clientInfo))
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (s *LinkService) addClientInfo(uri string, clientInfo string) string {
|
|
protocol := strings.Split(uri, "://")
|
|
if len(protocol) < 2 {
|
|
return uri
|
|
}
|
|
switch protocol[0] {
|
|
case "vmess":
|
|
var vmessJson map[string]interface{}
|
|
config, err := util.B64StrToByte(protocol[1])
|
|
if err != nil {
|
|
logger.Warning("sub: Error decoding vmess content:", err)
|
|
return uri
|
|
}
|
|
err = json.Unmarshal(config, &vmessJson)
|
|
if err != nil {
|
|
logger.Warning("sub: Error decoding vmess content:", err)
|
|
return uri
|
|
}
|
|
vmessJson["ps"] = vmessJson["ps"].(string) + clientInfo
|
|
result, err := json.MarshalIndent(vmessJson, "", " ")
|
|
if err != nil {
|
|
logger.Warning("sub: Error decoding vmess + clientInfo content:", err)
|
|
return uri
|
|
}
|
|
return "vmess://" + util.ByteToB64Str(result)
|
|
default:
|
|
return uri + clientInfo
|
|
}
|
|
}
|
|
|
|
func (s *LinkService) getExternalSub(url string) []string {
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
|
|
// Make the HTTP request
|
|
response, err := client.Get(url)
|
|
if err != nil {
|
|
logger.Warning("sub: Error making HTTP request:", err)
|
|
return nil
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
// Read the response body
|
|
body, err := io.ReadAll(response.Body)
|
|
if err != nil {
|
|
logger.Warning("sub: Error reading response body:", err)
|
|
return nil
|
|
}
|
|
|
|
// Convert if the content is Base64 encoded
|
|
links := util.StrOrBase64Encoded(string(body))
|
|
return strings.Split(links, "\n")
|
|
|
|
}
|