-
Notifications
You must be signed in to change notification settings - Fork 5
/
url_schema.go
73 lines (62 loc) · 1.63 KB
/
url_schema.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package ray2sing
import (
"net/url"
"strings"
T "github.com/sagernet/sing-box/option"
)
// HysteriaURLData holds the parsed data from a Hysteria URL.
type UrlSchema struct {
Scheme string
Username string
Password string
Hostname string
Port uint16
Name string
Params map[string]string
}
func (u UrlSchema) GetServerOption() T.ServerOptions {
return T.ServerOptions{
Server: u.Hostname,
ServerPort: u.Port,
}
}
func (u UrlSchema) GetRelayOptions() (*T.TurnRelayOptions, error) {
return ParseTurnURL(u.Params["relay"])
}
// parseHysteria2 parses a given URL and returns a HysteriaURLData struct.
func ParseUrl(inputURL string, defaultPort uint16) (*UrlSchema, error) {
parsedURL, err := url.Parse(inputURL)
if err != nil {
return nil, err
}
port := toInt16(parsedURL.Port(), defaultPort)
data := &UrlSchema{
Scheme: parsedURL.Scheme,
Username: parsedURL.User.Username(),
Password: getPassword(parsedURL),
Hostname: parsedURL.Hostname(),
Port: port,
Name: parsedURL.Fragment,
Params: make(map[string]string),
}
userInfo, err := decodeBase64IfNeeded(data.Username)
// fmt.Print(userInfo)
if err == nil {
// If decoding is successful, use the decoded string
userDetails := strings.SplitN(userInfo, ":", 2)
if len(userDetails) > 1 {
data.Username = userDetails[0]
data.Password = userDetails[1]
}
}
for key, values := range parsedURL.Query() {
data.Params[strings.ReplaceAll(strings.ToLower(key), "_", "")] = strings.Join(values, ",")
}
return data, nil
}
func getPassword(u *url.URL) string {
if password, ok := u.User.Password(); ok {
return password
}
return ""
}