forked from surol/speedtest-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
117 lines (97 loc) · 2.31 KB
/
config.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
package speedtest
import (
"encoding/xml"
"strings"
"strconv"
"log"
)
type ClientConfig struct {
Coordinates
IP string `xml:"ip,attr"`
ISP string `xml:"isp,attr"`
ISPRating float32 `xml:"isprating,attr"`
ISPDownloadAverage uint32 `xml:"ispdlavg,attr"`
ISPUploadAverage uint32 `xml:"ispulavg,attr"`
Rating float32 `xml:"rating,attr"`
LoggedIn uint8 `xml:"loggedin,attr"`
}
type ConfigTime struct {
Upload uint32
Download uint32
}
type ConfigTimes []ConfigTime
type Config struct {
Client ClientConfig `xml:"client"`
Times ConfigTimes `xml:"times"`
}
func (client *client) Log(format string, a ...interface{}) {
if !client.opts.Quiet {
log.Printf(format, a...)
}
}
type ConfigRef struct {
Config *Config
Error error
}
func (client *client) Config() (*Config, error) {
configChan := make(chan ConfigRef)
client.LoadConfig(configChan)
configRef := <-configChan
return configRef.Config, configRef.Error
}
func (client *client) LoadConfig(ret chan ConfigRef) {
client.mutex.Lock()
defer client.mutex.Unlock()
if client.config == nil {
client.config = make(chan ConfigRef)
go client.loadConfig()
}
go func() {
result := <-client.config
ret <- result
client.config <- result
}()
}
func (client *client) loadConfig() {
client.Log("Retrieving speedtest.net configuration...")
result := ConfigRef{}
resp, err := client.Get("://www.speedtest.net/speedtest-config.php")
if err != nil {
result.Error = err
} else {
config := &Config{}
err = resp.ReadXML(config)
if err != nil {
result.Error = err
} else {
result.Config = config
}
}
client.config <- result
}
func (times ConfigTimes) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
name := attr.Name.Local
if dl := strings.HasPrefix(name, "dl"); dl || strings.HasPrefix(name, "ul") {
num, err := strconv.Atoi(name[2:])
if err != nil {
return err;
}
if num > cap(times) {
newTimes := make([]ConfigTime, num)
copy(newTimes, times)
times = newTimes[0:num]
}
speed, err := strconv.ParseUint(attr.Value, 10, 32);
if err != nil {
return err
}
if dl {
times[num - 1].Download = uint32(speed)
} else {
times[num - 1].Upload = uint32(speed)
}
}
}
return d.Skip()
}