mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 16:01:55 +03:00
Move cli to separate package
This commit is contained in:
@@ -1,36 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/9seconds/mtg/v2/config"
|
|
||||||
"github.com/9seconds/mtg/v2/mtglib/network"
|
|
||||||
)
|
|
||||||
|
|
||||||
type cli struct {
|
|
||||||
network network.Network
|
|
||||||
conf *config.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cli) ReadConfig(path string) error {
|
|
||||||
content, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read config file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
conf, err := config.Parse(content)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot parse config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ntw, err := makeNetwork(conf)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot build a network: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.conf = conf
|
|
||||||
c.network = ntw
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -30,14 +31,14 @@ type accessResponseURLs struct {
|
|||||||
TmeQrCode string `json:"tme_qrcode"`
|
TmeQrCode string `json:"tme_qrcode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type cliCommandAccess struct {
|
type Access struct {
|
||||||
cli
|
base
|
||||||
|
|
||||||
ConfigPath string `arg required type:"existingfile" help:"Path to the configuration file." name:"config-path"` // nolint: lll, govet
|
ConfigPath string `arg required type:"existingfile" help:"Path to the configuration file." name:"config-path"` // nolint: lll, govet
|
||||||
Hex bool `help:"Print secret in hex encoding."`
|
Hex bool `help:"Print secret in hex encoding."`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cliCommandAccess) Run(cli *CLI) error {
|
func (c *Access) Run(cli *CLI) error {
|
||||||
if err := c.ReadConfig(cli.Access.ConfigPath); err != nil {
|
if err := c.ReadConfig(cli.Access.ConfigPath); err != nil {
|
||||||
return fmt.Errorf("cannot init config: %w", err)
|
return fmt.Errorf("cannot init config: %w", err)
|
||||||
}
|
}
|
||||||
@@ -72,7 +73,7 @@ func (c *cliCommandAccess) Run(cli *CLI) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cliCommandAccess) getIP(protocol string) net.IP {
|
func (c *Access) getIP(protocol string) net.IP {
|
||||||
client := c.network.MakeHTTPClient(0)
|
client := c.network.MakeHTTPClient(0)
|
||||||
client.Transport = &http.Transport{
|
client.Transport = &http.Transport{
|
||||||
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
@@ -80,9 +81,14 @@ func (c *cliCommandAccess) getIP(protocol string) net.IP {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
c.network.PatchHTTPClient(client)
|
c.network.PrepareHTTPClient(client)
|
||||||
|
|
||||||
resp, err := client.Get("https://ifconfig.co") // nolint: bodyclose, noctx
|
req, err := http.NewRequest(http.MethodGet, "https://ifconfig.co", nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -91,7 +97,10 @@ func (c *cliCommandAccess) getIP(protocol string) net.IP {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
defer exhaustResponse(resp)
|
defer func() {
|
||||||
|
io.Copy(ioutil.Discard, resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -101,7 +110,7 @@ func (c *cliCommandAccess) getIP(protocol string) net.IP {
|
|||||||
return net.ParseIP(strings.TrimSpace(string(data)))
|
return net.ParseIP(strings.TrimSpace(string(data)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cliCommandAccess) makeURLs(ip net.IP, cli *CLI) *accessResponseURLs {
|
func (c *Access) makeURLs(ip net.IP, cli *CLI) *accessResponseURLs {
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -140,7 +149,7 @@ func (c *cliCommandAccess) makeURLs(ip net.IP, cli *CLI) *accessResponseURLs {
|
|||||||
return rv
|
return rv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cliCommandAccess) makeQRCode(data string) string {
|
func (c *Access) makeQRCode(data string) string {
|
||||||
values := url.Values{}
|
values := url.Values{}
|
||||||
|
|
||||||
values.Set("qzone", "4")
|
values.Set("qzone", "4")
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/v2/config"
|
||||||
|
"github.com/9seconds/mtg/v2/mtglib/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type base struct {
|
||||||
|
network network.Network
|
||||||
|
conf *config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *base) ReadConfig(path string) error {
|
||||||
|
content, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot read config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
conf, err := config.Parse(content)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot parse config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ntw, err := b.makeNetwork(conf)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot build a network: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.conf = conf
|
||||||
|
b.network = ntw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *base) makeNetwork(conf *config.Config) (network.Network, error) {
|
||||||
|
tcpTimeout := conf.Network.Timeout.TCP.Value(network.DefaultTimeout)
|
||||||
|
idleTimeout := conf.Network.Timeout.Idle.Value(network.DefaultIdleTimeout)
|
||||||
|
dohIP := conf.Network.DOHIP.Value(net.ParseIP(network.DefaultDOHHostname)).String()
|
||||||
|
bufferSize := conf.TCPBuffer.Value(network.DefaultBufferSize)
|
||||||
|
|
||||||
|
baseDialer, err := network.NewDefaultDialer(tcpTimeout, int(bufferSize))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot build a default dialer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyURLs := make([]*url.URL, 0, len(conf.Network.Proxies))
|
||||||
|
|
||||||
|
for _, v := range conf.Network.Proxies {
|
||||||
|
if value := v.Value(nil); value != nil {
|
||||||
|
proxyURLs = append(proxyURLs, v.Value(nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(proxyURLs) {
|
||||||
|
case 0:
|
||||||
|
return network.NewNetwork(baseDialer, dohIP, idleTimeout)
|
||||||
|
case 1:
|
||||||
|
socksDialer, err := network.NewSocks5Dialer(baseDialer, proxyURLs[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot build socks5 dialer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return network.NewNetwork(socksDialer, dohIP, idleTimeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
socksDialer, err := network.NewLoadBalancedSocks5Dialer(baseDialer, proxyURLs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot build socks5 dialer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return network.NewNetwork(socksDialer, dohIP, idleTimeout)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kong"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CLI struct {
|
||||||
|
GenerateSecret GenerateSecret `cmd help:"Generate new proxy secret"` // nolint: govet
|
||||||
|
Access Access `cmd help:"Print access information."` // nolint: govet
|
||||||
|
Version kong.VersionFlag `help:"Print version."`
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -6,14 +6,14 @@ import (
|
|||||||
"github.com/9seconds/mtg/v2/mtglib"
|
"github.com/9seconds/mtg/v2/mtglib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cliCommandGenerateSecret struct {
|
type GenerateSecret struct {
|
||||||
cli
|
base
|
||||||
|
|
||||||
HostName string `arg optional help:"Hostname to use for domain fronting. Default is '${domain_front}'." name:"hostname" default:"${domain_front}"` // nolint: lll, govet
|
HostName string `arg optional help:"Hostname to use for domain fronting. Default is '${domain_front}'." name:"hostname" default:"${domain_front}"` // nolint: lll, govet
|
||||||
Hex bool `help:"Print secret in hex encoding."`
|
Hex bool `help:"Print secret in hex encoding."`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cliCommandGenerateSecret) Run(cli *CLI) error { // nolint: unparam
|
func (c *GenerateSecret) Run(cli *CLI) error { // nolint: unparam
|
||||||
secret := mtglib.GenerateSecret(cli.GenerateSecret.HostName)
|
secret := mtglib.GenerateSecret(cli.GenerateSecret.HostName)
|
||||||
|
|
||||||
if cli.GenerateSecret.Hex {
|
if cli.GenerateSecret.Hex {
|
||||||
@@ -4,21 +4,16 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/v2/cli"
|
||||||
"github.com/alecthomas/kong"
|
"github.com/alecthomas/kong"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = "dev" // has to be set by ldflags
|
var version = "dev" // has to be set by ldflags
|
||||||
|
|
||||||
type CLI struct {
|
|
||||||
GenerateSecret cliCommandGenerateSecret `cmd help:"Generate new proxy secret"` // nolint: govet
|
|
||||||
Access cliCommandAccess `cmd help:"Print access information."` // nolint: govet
|
|
||||||
Version kong.VersionFlag `help:"Print version."`
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
|
||||||
cli := &CLI{}
|
cli := &cli.CLI{}
|
||||||
ctx := kong.Parse(cli, kong.Vars{
|
ctx := kong.Parse(cli, kong.Vars{
|
||||||
"domain_front": "amazonaws.com",
|
"domain_front": "amazonaws.com",
|
||||||
"version": version,
|
"version": version,
|
||||||
|
|||||||
@@ -39,5 +39,5 @@ type Network interface {
|
|||||||
DNSResolve(network, hostname string) (ips []string, err error)
|
DNSResolve(network, hostname string) (ips []string, err error)
|
||||||
MakeHTTPClient(timeout time.Duration) *http.Client
|
MakeHTTPClient(timeout time.Duration) *http.Client
|
||||||
IdleTimeout() time.Duration
|
IdleTimeout() time.Duration
|
||||||
PatchHTTPClient(*http.Client)
|
PrepareHTTPClient(*http.Client)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user