-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
147 lines (125 loc) · 3.55 KB
/
main.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// This program is a simple config checker tool for proxies and global configs. It prints out basic
// statistics and round-trips the low-cardinality portions of the config in order to make sure the
// YAML parses as expected. The tool can either read a local config file (assumed to be plain text)
// or a remote http(s) URL (assumed to be gzipped).
//
// Examples:
//
// go run main.go proxies ~/Library/Application\ Support/Lantern/proxies.yaml
// go run main.go global ~/Library/Application\ Support/Lantern/global.yaml
// go run main.go global https://globalconfig.flashlightproxy.com/global.yaml.gz
package main
import (
"compress/gzip"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
commonconfig "github.com/getlantern/common/config"
"github.com/getlantern/flashlight/v7/config"
"github.com/getlantern/flashlight/v7/domainrouting"
"github.com/getlantern/yaml"
)
func main() {
if len(os.Args) < 3 {
fail("Please specify a format ('proxies' or 'global') and a filename or http(s) url for the config to check")
}
format := os.Args[1]
target := os.Args[2]
u, err := url.Parse(target)
if err != nil {
fail("Unable to parse config url %v: %v", target, err)
}
var bytes []byte
var readErr error
switch u.Scheme {
case "":
bytes, readErr = ioutil.ReadFile(target)
case "http", "https":
bytes, readErr = readRemote(target)
default:
fail("Unrecognized url scheme: %v", u.Scheme)
}
if readErr != nil {
fail("Unable to read %v: %v", target, readErr)
}
log("Checking %v config at %v", format, target)
switch format {
case "proxies":
parseProxies(bytes)
case "global":
parseGlobal(bytes)
default:
fail("Unknown format %v, please specify either 'proxies' or 'global'", format)
}
}
func readRemote(target string) ([]byte, error) {
resp, err := http.Get(target)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Bad response status: %d", resp.StatusCode)
}
gzr, err := gzip.NewReader(resp.Body)
if err != nil {
return nil, err
}
return ioutil.ReadAll(gzr)
}
func parseProxies(bytes []byte) {
cfg := make(map[string]*commonconfig.ProxyConfig)
err := yaml.Unmarshal(bytes, cfg)
if err != nil {
fail("Unable to parse proxies config: %v", err)
}
log("Number of proxies: %d", len(cfg))
out, err := yaml.Marshal(cfg)
if err != nil {
fail("Unable to marshal proxies config")
}
log("------ Round-tripped YAML ------")
os.Stdout.Write(out)
}
func parseGlobal(bytes []byte) {
cfg := &config.Global{}
err := yaml.Unmarshal(bytes, cfg)
if err != nil {
fail("Unable to parse global config: %v", err)
}
log("Number of Proxied Sites: %d", len(cfg.ProxiedSites.Cloud))
var direct, proxied int
for _, rule := range cfg.DomainRoutingRules {
switch rule {
case domainrouting.Direct:
direct++
case domainrouting.Proxy:
proxied++
}
}
log("Domainrouting direct: %d", direct)
log("Domainrouting proxied: %d", proxied)
for name, provider := range cfg.Client.FrontedProviders() {
log("Masquerades for %v: %d", name, len(provider.Masquerades))
}
// Clear out high cardinality data before marshaling
cfg.ProxiedSites = nil
cfg.DomainRoutingRules = nil
cfg.NamedDomainRoutingRules = nil
cfg.Client.Fronted.Providers = nil
out, err := yaml.Marshal(cfg)
if err != nil {
fail("Unable to marshal global config")
}
log("------ Round-tripped YAML ------")
os.Stdout.Write(out)
}
func log(msg string, args ...interface{}) {
fmt.Fprintf(os.Stderr, msg+"\n", args...)
}
func fail(msg string, args ...interface{}) {
fmt.Fprintf(os.Stderr, msg+"\n", args...)
os.Exit(1)
}