mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 08:04:01 +03:00
Introduce explicit config
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Debug bool
|
||||
Verbose bool
|
||||
BindIP net.IP
|
||||
BindPort uint16
|
||||
|
||||
PublicIPv4 net.IP
|
||||
PublicIPv4Port uint16
|
||||
PublicIPv6 net.IP
|
||||
PublicIPv6Port uint16
|
||||
|
||||
StatsIP net.IP
|
||||
StatsPort uint16
|
||||
|
||||
TimeoutRead time.Duration
|
||||
TimeoutWrite time.Duration
|
||||
|
||||
Secret []byte
|
||||
}
|
||||
|
||||
type URLs struct {
|
||||
TG string `json:"tg_url"`
|
||||
TMe string `json:"tme_url"`
|
||||
TGQRCode string `json:"tg_qrcode"`
|
||||
TMeQRCode string `json:"tme_qrcode"`
|
||||
}
|
||||
|
||||
type IPURLs struct {
|
||||
IPv4 URLs `json:"ipv4"`
|
||||
IPv6 URLs `json:"ipv6"`
|
||||
}
|
||||
|
||||
func (c *Config) BindAddr() string {
|
||||
return getAddr(c.BindIP, c.BindPort)
|
||||
}
|
||||
|
||||
func (c *Config) IPv4Addr() string {
|
||||
return getAddr(c.PublicIPv4, c.PublicIPv4Port)
|
||||
}
|
||||
|
||||
func (c *Config) IPv6Addr() string {
|
||||
return getAddr(c.PublicIPv6, c.PublicIPv6Port)
|
||||
}
|
||||
|
||||
func (c *Config) StatAddr() string {
|
||||
return getAddr(c.StatsIP, c.StatsPort)
|
||||
}
|
||||
|
||||
func (c *Config) GetURLs() IPURLs {
|
||||
return IPURLs{
|
||||
IPv4: getURLs(c.PublicIPv4, c.PublicIPv4Port, c.Secret),
|
||||
IPv6: getURLs(c.PublicIPv6, c.PublicIPv6Port, c.Secret),
|
||||
}
|
||||
}
|
||||
|
||||
func getAddr(host fmt.Stringer, port uint16) string {
|
||||
return net.JoinHostPort(host.String(), strconv.Itoa(int(port)))
|
||||
}
|
||||
|
||||
func NewConfig(debug, verbose bool,
|
||||
bindIP net.IP, bindPort uint16,
|
||||
publicIPv4 net.IP, PublicIPv4Port uint16,
|
||||
publicIPv6 net.IP, publicIPv6Port uint16,
|
||||
statsIP net.IP, statsPort uint16,
|
||||
timeoutRead, timeoutWrite time.Duration,
|
||||
secret string) (*Config, error) {
|
||||
secretBytes, err := hex.DecodeString(secret)
|
||||
if err != nil {
|
||||
return nil, errors.Annotate(err, "Cannot create config")
|
||||
}
|
||||
|
||||
if publicIPv4 == nil {
|
||||
publicIPv4, err = getGlobalIPv4()
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("Cannot get public IP")
|
||||
}
|
||||
}
|
||||
if publicIPv4.To4() == nil {
|
||||
return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
|
||||
}
|
||||
if PublicIPv4Port == 0 {
|
||||
PublicIPv4Port = bindPort
|
||||
}
|
||||
|
||||
if publicIPv6 == nil {
|
||||
publicIPv6, err = getGlobalIPv6()
|
||||
if err != nil {
|
||||
publicIPv6 = publicIPv4
|
||||
}
|
||||
}
|
||||
if publicIPv6.To16() == nil {
|
||||
return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
|
||||
}
|
||||
if publicIPv6Port == 0 {
|
||||
publicIPv6Port = bindPort
|
||||
}
|
||||
|
||||
if statsIP == nil {
|
||||
statsIP = publicIPv4
|
||||
}
|
||||
|
||||
conf := &Config{
|
||||
Debug: debug,
|
||||
Verbose: verbose,
|
||||
BindIP: bindIP,
|
||||
BindPort: bindPort,
|
||||
PublicIPv4: publicIPv4,
|
||||
PublicIPv4Port: PublicIPv4Port,
|
||||
PublicIPv6: publicIPv6,
|
||||
PublicIPv6Port: publicIPv6Port,
|
||||
TimeoutRead: timeoutRead,
|
||||
TimeoutWrite: timeoutWrite,
|
||||
Secret: secretBytes,
|
||||
}
|
||||
|
||||
return conf, nil
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
func getGlobalIPv4() (net.IP, error) {
|
||||
return fetchIP("https://v4.ifconfig.co/ip")
|
||||
}
|
||||
|
||||
func getGlobalIPv6() (net.IP, error) {
|
||||
return fetchIP("https://v6.ifconfig.co/ip")
|
||||
}
|
||||
|
||||
func fetchIP(url string) (net.IP, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respData, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ip := net.ParseIP(strings.TrimSpace(string(respData)))
|
||||
if ip == nil {
|
||||
return nil, errors.Errorf("ifconfig.co returns incorrect IP %s", resp)
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func getURLs(addr net.IP, port uint16, secret []byte) (urls URLs) {
|
||||
values := url.Values{}
|
||||
values.Set("server", addr.String())
|
||||
values.Set("port", strconv.Itoa(int(port)))
|
||||
values.Set("secret", hex.EncodeToString(secret))
|
||||
|
||||
urls.TG = makeTGURL(values)
|
||||
urls.TMe = makeTGURL(values)
|
||||
urls.TGQRCode = makeQRCodeURL(urls.TG)
|
||||
urls.TMeQRCode = makeQRCodeURL(urls.TG)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func makeTGURL(values url.Values) string {
|
||||
tgURL := url.URL{
|
||||
Scheme: "tg",
|
||||
Host: "proxy",
|
||||
RawQuery: values.Encode(),
|
||||
}
|
||||
|
||||
return tgURL.String()
|
||||
}
|
||||
|
||||
func makeTMeURL(values url.Values) string {
|
||||
tMeURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: "t.me",
|
||||
Path: "proxy",
|
||||
RawQuery: values.Encode(),
|
||||
}
|
||||
|
||||
return tMeURL.String()
|
||||
}
|
||||
|
||||
func makeQRCodeURL(data string) string {
|
||||
QRURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: "api.qrserver.com",
|
||||
Path: "v1/create-qr-code",
|
||||
}
|
||||
|
||||
values := url.Values{}
|
||||
values.Set("qzone", "4")
|
||||
values.Set("format", "svg")
|
||||
values.Set("data", data)
|
||||
QRURL.RawQuery = values.Encode()
|
||||
|
||||
return QRURL.String()
|
||||
}
|
||||
Reference in New Issue
Block a user